/*--------------------------------------------------------------*
* xcTable version 2.0 2007/05/21 by stenly
* 说明: 实面多table同进绑定多xml数据源
* 修正: 当请求一次xml数据后,分页时不用重新请求,可以分批显示数据记录
* checkbox在翻页的时候都可以保留该值
* 修正: 分页时,不能识别是那个Table的问题
* 修正: 改进了解释表格时的效率
*
/*--------------------------------------------------------------*/
/**
* 把xml数据填充到表格的类 version 2.0
* write by stenly 2007/05/21
*
*/
XMLTable = Class.create();
XMLTable.prototype = {
initialize: function(tabID_,xmlSource_) {
this.tabID = tabID_; //被填充表格的ID号
this.xmlSource = xmlSource_; //xml数据源,可以是jsp或asp文件
this.cloneRowIdx = -1; //模版行的当前rowIndex,动态增加的
this.factTabRowCount = 0; //实际行数
this.xmlRecordCount = 0;
this.xmlDoc = null;
this.elAry; //模版行的所有#{}内的元素名称,重复的去掉
this.rowIdx = -1;
this.colCount = 0; //模版行的单元格数目
this.tmplRowStr; //模版行的innerHTML String
this.tabObj;
this.tabRowCount; //table的所有行数,包括非记录的行数
this.cloneRowIdx;
this.factRecRowCnt; //实际输出的行数
},
fillTable:function(startRow,recCntEachPage){
startRow--; //下标从零开始
this.reloadTable(this.tabObj);
if(this.xmlDoc != null){
doXmlFill(this,startRow,recCntEachPage);
}else{
this.init();
//传入一个this引用,在AjaxRequest类内把值设到外部的this.xmlDoc中,不然xmlDoc是传不出来的
var oAjax = new AjaxRequest(this.xmlSource,this);
oAjax.onSuccess = function(parent,xmlDoc){
parent.xmlDoc = xmlDoc; //直接用this.xmlDoc=xmlDoc无效
doXmlFill(parent,startRow,recCntEachPage);
}
oAjax.onFailure = function(errorCode){
alert("远程调用失败,错误代码: " + errorCode);
}
oAjax.doRequest();
}
//private function define
//parent为 XMLTable对象的引用
function doXmlFill(parent,startRow,rowCntEachPage){
parent.xmlRecordCount = parent.xmlRecordCount==0?parent.xmlDoc.getElementsByTagName("rec").length : parent.xmlRecordCount;
for(var tabRow=0; tabRow<rowCntEachPage && (tabRow + startRow)<parent.xmlRecordCount; tabRow++){
//copy模版行来处理
var newRowClone = parent.tabObj.rows[parent.cloneRowIdx++].cloneNode(true);
//给该模版行填充数据
newRowClone = xmlFillToRow(parent.xmlDoc,newRowClone,parent.colCount,parent.elAry,tabRow + startRow);
//总加在模版行的上一行
parent.tabObj.rows[parent.rowIdx - 1].appendChild(newRowClone);
//取得实际行数
parent.factRecRowCnt = tabRow + 1;
}
//隐藏模版行
//tabObj.deleteRow(_cloneRowIdx);
parent.tabObj.rows[parent.cloneRowIdx].style.display ='none';
//private function define
function xmlFillToRow(xmlDoc,newRowClone,colCount,elAry,xmlRow){
var tmplRowStr; //模版列的innerHTML
var chkPosEachRow; //记录每行checkbox的位置,事件绑定时不用重头历遍
for(var j=0; j<colCount; j++){
///////////////////////////////////////////////////////////////
//反回该行的所有TD单元格
oNodes = newRowClone.childNodes[j].childNodes;
//处理每个单元格内所有的checkbox
chkPosEachRow = fillCheckBox(oNodes,xmlDoc.getElementsByTagName("check")[xmlRow].text,xmlRow);
//////////////////////////////////////////////////////////////
//取出一个单元格的innerHTML
oCellStr = newRowClone.childNodes[j].innerHTML;
//替换该列的所有#{}值
for(var i=0; i<elAry.length; i++){
oCellStr = parent.replaceStr(oCellStr,"#{" + elAry[i] + "}",xmlDoc.getElementsByTagName(elAry[i])[xmlRow].text);
}
//处理后的每个单元格的innerHTML写回模版行
newRowClone.childNodes[j].innerHTML = oCellStr;
//给该单元格的所有checkbox绑定事件处理函数
bindEvent(xmlDoc,chkPosEachRow,newRowClone.childNodes[j]);
}
return newRowClone;
}
//处理checkBox的勾选显示
function fillCheckBox(oNodes,isCheck,xmlRow){
var chkPosEachRow = new Array(); //记录每行checkbox的位置,事件绑定时不用重头历遍
var j=0;
//历遍每个TD的子节点,如果是checkbox就判断是否要勾选
for(var i=0; i<oNodes.length; i++){
var oNode = oNodes[i];
if(oNode.nodeName == "INPUT" && oNode.type == "checkbox"){
//checkbox的value记录xmlData记录集当前行的序列
oNode.value = xmlRow;
//判断是否勾选
oNode.checked = isCheck == "1"?true:false;
chkPosEachRow[j++] = i;
//事件绑定放到这里没有效
//eval("oNode.attachEvent('onclick',function() {updateXMLData(" + oNode.value + ")})");
}
}
return chkPosEachRow;
}
//给每个checkbox绑定事件
function bindEvent(xmlDoc,chkPosAry,oCell){
var oNode;
var oNodes = oCell.childNodes;
for(var i=0; i<chkPosAry.length; i++){
oNode = oNodes[chkPosAry[i]];
eval("oNode.attachEvent('onclick',function() {updateXMLData(xmlDoc,oNode)})");
}
//历遍表格的每个子节点,这种算法的效率不够高
/*
var tab = document.getElementById(tabID);
//已知模版列中定义了checkbox那么生成的各条记录都有checkbox,只需找出第一行的checkbox
//位置即可,不用每一行都从头找出checkbox节省历遍时间
//
//历遍该表格的每一行
for(var i = 0; i<tab.rows.length; i++){
var oRow = tab.rows[i]; //取出行对象
oCells = oRow.cells; //每行有多少个单元格
//历遍每行的所有单元格
for(var j = 0; j<oCells.length; j++){
var oCell = oCells[j]; //每行的一个单元格对象
oNodes = oCell.childNodes; //取出每个单元格的所有节点对象
//历遍所有节点对象
for(z = 0; z<oNodes.length; z++){
var oNode = oNodes[z];
if(oNode.nodeName == "INPUT" && oNode.type == "checkbox"){
//eval("oNode.attachEvent('onclick',function() {updateXMLData(" + oNode.value + ")})");
//eval("obj[i].attachEvent('onclick',function() {updateXMLData(obj[" + i + "])})");
}
}
}*/
}
//同步更新xml文件
function updateXMLData(xmlDoc,oChk){
//alert("xmlDate row=" + oChk.value);
//alert(oChk.checked);
xmlDoc.getElementsByTagName("check")[oChk.value].text = oChk.checked?1:0;
//alert(xmlDoc.getElementsByTagName("check")[oChk.value].text);
}
}
},
init:function(){
this.tabObj = document.getElementById(this.tabID);
this.tabRowCount = this.tabObj.rows.length;
//寻找#{}所在的行
for(var i = 0; i<this.tabRowCount; i++){
var oRow = this.tabObj.rows[i];
var rowStr = oRow.innerHTML;
if(rowStr.indexOf("#{")!=-1){
this.tmplRowStr = this.tabObj.rows[i].innerHTML;
//求模版行的单元格数目
this.colCount = this.tabObj.rows[i].cells.length;
this.cloneRowIdx = i;
this.rowIdx = i;
break;
}
}
this.elAry = this.getElementName(this.tmplRowStr);
},
//把所有#{}内的变量标识名放到数组中,重复的去掉
getElementName:function(rowStr){
var i = 0;
var j;
var elStr;
var elAry = new Array();
var mark = true;
while(i > -1){
i = rowStr.indexOf("#{",i + 1);
j = rowStr.indexOf("}",j + 1);
elStr = rowStr.substr(i + 2,j - i - 2);
if(elStr!=""){
for(var z=0; z<elAry.length; z++){
if(elStr == elAry[z]){
mark = false;
break;
}
}
if(mark)
elAry.push(elStr);
mark = true;
}
}
return elAry;
},
replaceStr:function(source,subjectStr,targetStr){
while(source.indexOf(subjectStr) != -1){
source = source.replace(subjectStr,targetStr);
}
return source;
},
//复原到添加数据前的状态
reloadTable:function(tabObj){
if(this.cloneRowIdx != -1){
for(var i=0; i<this.factRecRowCnt ; i++){
tabObj.deleteRow(this.cloneRowIdx - 1);
this.cloneRowIdx--;
}
tabObj.rows[this.cloneRowIdx].style.display ='block';
}
},
//缺点,要一先执行上面的doRequest()才有值
getRecordCount:function(){
return this.xmlRecordCount;
}
}
/**
* 控制表格分页的类
* write by stenly 2007/05/12
*
*/
//写类的构造函数
/*
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
*/
PageManage = Class.create();
PageManage.prototype = {
initialize: function(xtObj,recCntEachPage) {
this.xtObj = xtObj;
this.tabID = xtObj.tabID;
this.actionSource = xtObj.xmlSource;
this.recCntEachPage = recCntEachPage;
this.curentPage = 1;
this.recordCount;
},
firstPage : function(){
this.curentPage = 1;
this.xtObj.fillTable(1,this.recCntEachPage);
},
prePage : function(){
if((this.curentPage - 1) < 1) return;
this.curentPage--;
var startRow = (this.curentPage - 1)*this.recCntEachPage + 1;
this.xtObj.fillTable(startRow,this.recCntEachPage);
},
nextPage : function(){
this.recordCount = this.xtObj.getRecordCount();
if(this.curentPage + 1 > Math.ceil(this.recordCount/this.recCntEachPage,true)) return;
this.curentPage++;
var startRow = (this.curentPage - 1)*this.recCntEachPage + 1;
this.xtObj.fillTable(startRow,this.recCntEachPage);
},
lastPage : function(){
this.recordCount = this.xtObj.getRecordCount();
this.curentPage = Math.ceil(this.recordCount/this.recCntEachPage);
var startRow = (Math.ceil(this.recordCount/this.recCntEachPage) - 1)*this.recCntEachPage + 1;
this.xtObj.fillTable(startRow,this.recCntEachPage);
},
update : function(me){
this.recCntEachPage = me.value;
this.firstPage();
}
}
调用:* xcTable version 2.0 2007/05/21 by stenly
* 说明: 实面多table同进绑定多xml数据源
* 修正: 当请求一次xml数据后,分页时不用重新请求,可以分批显示数据记录
* checkbox在翻页的时候都可以保留该值
* 修正: 分页时,不能识别是那个Table的问题
* 修正: 改进了解释表格时的效率
*
/*--------------------------------------------------------------*/
/**
* 把xml数据填充到表格的类 version 2.0
* write by stenly 2007/05/21
*
*/
XMLTable = Class.create();
XMLTable.prototype = {
initialize: function(tabID_,xmlSource_) {
this.tabID = tabID_; //被填充表格的ID号
this.xmlSource = xmlSource_; //xml数据源,可以是jsp或asp文件
this.cloneRowIdx = -1; //模版行的当前rowIndex,动态增加的
this.factTabRowCount = 0; //实际行数
this.xmlRecordCount = 0;
this.xmlDoc = null;
this.elAry; //模版行的所有#{}内的元素名称,重复的去掉
this.rowIdx = -1;
this.colCount = 0; //模版行的单元格数目
this.tmplRowStr; //模版行的innerHTML String
this.tabObj;
this.tabRowCount; //table的所有行数,包括非记录的行数
this.cloneRowIdx;
this.factRecRowCnt; //实际输出的行数
},
fillTable:function(startRow,recCntEachPage){
startRow--; //下标从零开始
this.reloadTable(this.tabObj);
if(this.xmlDoc != null){
doXmlFill(this,startRow,recCntEachPage);
}else{
this.init();
//传入一个this引用,在AjaxRequest类内把值设到外部的this.xmlDoc中,不然xmlDoc是传不出来的
var oAjax = new AjaxRequest(this.xmlSource,this);
oAjax.onSuccess = function(parent,xmlDoc){
parent.xmlDoc = xmlDoc; //直接用this.xmlDoc=xmlDoc无效
doXmlFill(parent,startRow,recCntEachPage);
}
oAjax.onFailure = function(errorCode){
alert("远程调用失败,错误代码: " + errorCode);
}
oAjax.doRequest();
}
//private function define
//parent为 XMLTable对象的引用
function doXmlFill(parent,startRow,rowCntEachPage){
parent.xmlRecordCount = parent.xmlRecordCount==0?parent.xmlDoc.getElementsByTagName("rec").length : parent.xmlRecordCount;
for(var tabRow=0; tabRow<rowCntEachPage && (tabRow + startRow)<parent.xmlRecordCount; tabRow++){
//copy模版行来处理
var newRowClone = parent.tabObj.rows[parent.cloneRowIdx++].cloneNode(true);
//给该模版行填充数据
newRowClone = xmlFillToRow(parent.xmlDoc,newRowClone,parent.colCount,parent.elAry,tabRow + startRow);
//总加在模版行的上一行
parent.tabObj.rows[parent.rowIdx - 1].appendChild(newRowClone);
//取得实际行数
parent.factRecRowCnt = tabRow + 1;
}
//隐藏模版行
//tabObj.deleteRow(_cloneRowIdx);
parent.tabObj.rows[parent.cloneRowIdx].style.display ='none';
//private function define
function xmlFillToRow(xmlDoc,newRowClone,colCount,elAry,xmlRow){
var tmplRowStr; //模版列的innerHTML
var chkPosEachRow; //记录每行checkbox的位置,事件绑定时不用重头历遍
for(var j=0; j<colCount; j++){
///////////////////////////////////////////////////////////////
//反回该行的所有TD单元格
oNodes = newRowClone.childNodes[j].childNodes;
//处理每个单元格内所有的checkbox
chkPosEachRow = fillCheckBox(oNodes,xmlDoc.getElementsByTagName("check")[xmlRow].text,xmlRow);
//////////////////////////////////////////////////////////////
//取出一个单元格的innerHTML
oCellStr = newRowClone.childNodes[j].innerHTML;
//替换该列的所有#{}值
for(var i=0; i<elAry.length; i++){
oCellStr = parent.replaceStr(oCellStr,"#{" + elAry[i] + "}",xmlDoc.getElementsByTagName(elAry[i])[xmlRow].text);
}
//处理后的每个单元格的innerHTML写回模版行
newRowClone.childNodes[j].innerHTML = oCellStr;
//给该单元格的所有checkbox绑定事件处理函数
bindEvent(xmlDoc,chkPosEachRow,newRowClone.childNodes[j]);
}
return newRowClone;
}
//处理checkBox的勾选显示
function fillCheckBox(oNodes,isCheck,xmlRow){
var chkPosEachRow = new Array(); //记录每行checkbox的位置,事件绑定时不用重头历遍
var j=0;
//历遍每个TD的子节点,如果是checkbox就判断是否要勾选
for(var i=0; i<oNodes.length; i++){
var oNode = oNodes[i];
if(oNode.nodeName == "INPUT" && oNode.type == "checkbox"){
//checkbox的value记录xmlData记录集当前行的序列
oNode.value = xmlRow;
//判断是否勾选
oNode.checked = isCheck == "1"?true:false;
chkPosEachRow[j++] = i;
//事件绑定放到这里没有效
//eval("oNode.attachEvent('onclick',function() {updateXMLData(" + oNode.value + ")})");
}
}
return chkPosEachRow;
}
//给每个checkbox绑定事件
function bindEvent(xmlDoc,chkPosAry,oCell){
var oNode;
var oNodes = oCell.childNodes;
for(var i=0; i<chkPosAry.length; i++){
oNode = oNodes[chkPosAry[i]];
eval("oNode.attachEvent('onclick',function() {updateXMLData(xmlDoc,oNode)})");
}
//历遍表格的每个子节点,这种算法的效率不够高
/*
var tab = document.getElementById(tabID);
//已知模版列中定义了checkbox那么生成的各条记录都有checkbox,只需找出第一行的checkbox
//位置即可,不用每一行都从头找出checkbox节省历遍时间
//
//历遍该表格的每一行
for(var i = 0; i<tab.rows.length; i++){
var oRow = tab.rows[i]; //取出行对象
oCells = oRow.cells; //每行有多少个单元格
//历遍每行的所有单元格
for(var j = 0; j<oCells.length; j++){
var oCell = oCells[j]; //每行的一个单元格对象
oNodes = oCell.childNodes; //取出每个单元格的所有节点对象
//历遍所有节点对象
for(z = 0; z<oNodes.length; z++){
var oNode = oNodes[z];
if(oNode.nodeName == "INPUT" && oNode.type == "checkbox"){
//eval("oNode.attachEvent('onclick',function() {updateXMLData(" + oNode.value + ")})");
//eval("obj[i].attachEvent('onclick',function() {updateXMLData(obj[" + i + "])})");
}
}
}*/
}
//同步更新xml文件
function updateXMLData(xmlDoc,oChk){
//alert("xmlDate row=" + oChk.value);
//alert(oChk.checked);
xmlDoc.getElementsByTagName("check")[oChk.value].text = oChk.checked?1:0;
//alert(xmlDoc.getElementsByTagName("check")[oChk.value].text);
}
}
},
init:function(){
this.tabObj = document.getElementById(this.tabID);
this.tabRowCount = this.tabObj.rows.length;
//寻找#{}所在的行
for(var i = 0; i<this.tabRowCount; i++){
var oRow = this.tabObj.rows[i];
var rowStr = oRow.innerHTML;
if(rowStr.indexOf("#{")!=-1){
this.tmplRowStr = this.tabObj.rows[i].innerHTML;
//求模版行的单元格数目
this.colCount = this.tabObj.rows[i].cells.length;
this.cloneRowIdx = i;
this.rowIdx = i;
break;
}
}
this.elAry = this.getElementName(this.tmplRowStr);
},
//把所有#{}内的变量标识名放到数组中,重复的去掉
getElementName:function(rowStr){
var i = 0;
var j;
var elStr;
var elAry = new Array();
var mark = true;
while(i > -1){
i = rowStr.indexOf("#{",i + 1);
j = rowStr.indexOf("}",j + 1);
elStr = rowStr.substr(i + 2,j - i - 2);
if(elStr!=""){
for(var z=0; z<elAry.length; z++){
if(elStr == elAry[z]){
mark = false;
break;
}
}
if(mark)
elAry.push(elStr);
mark = true;
}
}
return elAry;
},
replaceStr:function(source,subjectStr,targetStr){
while(source.indexOf(subjectStr) != -1){
source = source.replace(subjectStr,targetStr);
}
return source;
},
//复原到添加数据前的状态
reloadTable:function(tabObj){
if(this.cloneRowIdx != -1){
for(var i=0; i<this.factRecRowCnt ; i++){
tabObj.deleteRow(this.cloneRowIdx - 1);
this.cloneRowIdx--;
}
tabObj.rows[this.cloneRowIdx].style.display ='block';
}
},
//缺点,要一先执行上面的doRequest()才有值
getRecordCount:function(){
return this.xmlRecordCount;
}
}
/**
* 控制表格分页的类
* write by stenly 2007/05/12
*
*/
//写类的构造函数
/*
var Class = {
create: function() {
return function() {
this.initialize.apply(this, arguments);
}
}
}
*/
PageManage = Class.create();
PageManage.prototype = {
initialize: function(xtObj,recCntEachPage) {
this.xtObj = xtObj;
this.tabID = xtObj.tabID;
this.actionSource = xtObj.xmlSource;
this.recCntEachPage = recCntEachPage;
this.curentPage = 1;
this.recordCount;
},
firstPage : function(){
this.curentPage = 1;
this.xtObj.fillTable(1,this.recCntEachPage);
},
prePage : function(){
if((this.curentPage - 1) < 1) return;
this.curentPage--;
var startRow = (this.curentPage - 1)*this.recCntEachPage + 1;
this.xtObj.fillTable(startRow,this.recCntEachPage);
},
nextPage : function(){
this.recordCount = this.xtObj.getRecordCount();
if(this.curentPage + 1 > Math.ceil(this.recordCount/this.recCntEachPage,true)) return;
this.curentPage++;
var startRow = (this.curentPage - 1)*this.recCntEachPage + 1;
this.xtObj.fillTable(startRow,this.recCntEachPage);
},
lastPage : function(){
this.recordCount = this.xtObj.getRecordCount();
this.curentPage = Math.ceil(this.recordCount/this.recCntEachPage);
var startRow = (Math.ceil(this.recordCount/this.recCntEachPage) - 1)*this.recCntEachPage + 1;
this.xtObj.fillTable(startRow,this.recCntEachPage);
},
update : function(me){
this.recCntEachPage = me.value;
this.firstPage();
}
}
<span style="cursor:hand" onclick="tab2_pm.firstPage();">|<</span>
<span style="cursor:hand" onclick="tab2_pm.prePage();"><<</span>
<span style="cursor:hand" onclick="tab2_pm.nextPage();">>></span>
<span style="cursor:hand" onclick="tab2_pm.lastPage();">>|</span>
<input type="text" id="tab2_recCntEachPage" value="3" onchange="tab2_pm.update(this)">
<script>
var tab2_xtObj = new XMLTable("tab2","data.xml");
var tab2_recCntEachPage = document.getElementById("tab2_recCntEachPage").value;
tab2_xtObj.fillTable(1,tab2_recCntEachPage);
tab2_pm = new PageManage(tab2_xtObj,tab2_recCntEachPage);
</script>
用标签封装了的写法<span style="cursor:hand" onclick="tab2_pm.prePage();"><<</span>
<span style="cursor:hand" onclick="tab2_pm.nextPage();">>></span>
<span style="cursor:hand" onclick="tab2_pm.lastPage();">>|</span>
<input type="text" id="tab2_recCntEachPage" value="3" onchange="tab2_pm.update(this)">
<script>
var tab2_xtObj = new XMLTable("tab2","data.xml");
var tab2_recCntEachPage = document.getElementById("tab2_recCntEachPage").value;
tab2_xtObj.fillTable(1,tab2_recCntEachPage);
tab2_pm = new PageManage(tab2_xtObj,tab2_recCntEachPage);
</script>
<pageManage:navigator tableID="tab1" xmlsrc="data.xml" recordCount=3/>
浙公网安备 33010602011771号