首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Ajax动态表格

Posted on 2007-05-13 12:06  小城  阅读(2616)  评论(2)    收藏  举报
近来没事做,写了个用ajax和js实现动态表格与分页的东东~~~~
以下是用来解释xml和填充的核心Js代码:(以下调用ajax是经过自己的封装了,参看对ajax的一个小封装
/*--------------------------------------------------------------*/
/*  xcTable  version 1.0  2007/05/11  by 小城                   */
/*  说明: 实现表格与xml数据源的绑定                              */
/*  修正: 2007/05/12 可连续更新表格,以前只能更新一次             */
/*--------------------------------------------------------------*/

/**
 * 把xml数据填充到表格的类
 * write by 小城 2007/05/11
 *
 
*/
function XMLTable() {
  
var _cloneRowIdx = -1;                        //模版行的当前rowIndex,动态增加的
  var _factRowCount = 0;                        //实际行数
  var _recordCount = 0;
  
//           tabID: 被填充表格的ID号
  //       xmlSource: xml数据源,可以是jsp或asp文件
  //       startRow_: 开始定位到每几行
  // rowCntEachPage_: 每页输出的记录数
  this.fillTable = function(tabID, xmlSource, startRow_, rowCntEachPage_){
    
var tabObj = document.getElementById(tabID);
    
var tabRowCount = tabObj.rows.length;        //原table行数
    var rowIdx = -1;
    
var colCount = 0;                            //模版行的单元格数目
    var tmpRowStr;
    
var elAry;
    
var startRow = 0;                            //定位开始输出的行
    var rowCntEachPage = tabRowCount;            //设置每页输出行数

    
if(startRow_ != null || startRow_ != "undefined")
      startRow 
= startRow_ - 1;

    
//重载表格,清掉新增的数据行
    reloadTable(tabObj, rowCntEachPage_);

    
//寻找#{}所在的行
    for(var i = 0; i<tabRowCount; i++){
      
var oRow = tabObj.rows[i];
      
var rowStr = oRow.innerHTML;
      
if(rowStr.indexOf("#{")!=-1){
        tmpRowStr 
= tabObj.rows[i].innerHTML;
        
//求模版行的单元格数目
        colCount = tabObj.rows[i].cells.length;
        _cloneRowIdx 
= i;
        rowIdx 
= i;
        
break;
      }
    }

    elAry 
= getElementName(tmpRowStr);

    
var oAjax = new AjaxRequest(xmlSource);
    oAjax.onSuccess 
= function(xmlDoc){
      _recordCount 
= xmlDoc.getElementsByTagName("rec").length;
      
if(rowCntEachPage_ != null || rowCntEachPage_ != "undefined")
        rowCntEachPage 
= rowCntEachPage_;
      
else
        rowCntEachPage 
= _recordCount;

      
for(var iRow=0; iRow<rowCntEachPage && (iRow + startRow)<_recordCount; iRow++){
        
//copy模版行来处理
        var newRowClone = tabObj.rows[_cloneRowIdx++].cloneNode(true);
        
//给该模版行填充数据
        newRowClone = xmlFillToRow(xmlDoc,newRowClone,colCount,elAry,iRow + startRow);
        
//总加在模版行的上一行
        tabObj.rows[rowIdx - 1].appendChild(newRowClone);
        
//取得实际行数
        _factRowCount = iRow + 1;
      }
      
//隐藏模版行
      //tabObj.deleteRow(_cloneRowIdx);
      tabObj.rows[_cloneRowIdx].style.display ='none';
    }
    oAjax.onFailure 
= function(errorCode){
      alert(
"远程调用失败,错误代码: " + errorCode);
    }
    oAjax.doRequest();
  }

  
//把所有#{}内的变量标识名放到数组中,重复的去掉
  function getElementName(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;
  }

  
function xmlFillToRow(xmlDoc,newRowClone,colCount,elAry,iRow){
    
for(var j=0; j<colCount; j++){
      
///////////////////////////////////////////////////////////////
      //所有行的TD节点,内查找checkbox,对其做选择控制
      tdNodes = newRowClone.childNodes[j].childNodes
      fillCheckBox(tdNodes,xmlDoc.getElementsByTagName(
"check")[iRow].text);
      
//////////////////////////////////////////////////////////////
      var tdCellStr = newRowClone.childNodes[j].innerHTML;
      
//alert(tdCellStr);
      //替换该列的所有#{}值
      for(var i=0; i<elAry.length; i++){
        tdCellStr 
= replaceStr(tdCellStr,"#{" + elAry[i] + "}",xmlDoc.getElementsByTagName(elAry[i])[iRow].text);
      }
      
//alert(tdCellStr);
      //写回模版列
      newRowClone.childNodes[j].innerHTML = tdCellStr;

    }
    
return newRowClone;
  }

  
//处理checkBox的勾选显示
  function fillCheckBox(tdNodes,isCheck){
    
//历遍每个TD的子节点,如果是checkbox就判断是否要勾选
    for(var i=0; i<tdNodes.length; i++){
      
var iNode = tdNodes[i];
      
if(iNode.nodeName == "INPUT" && iNode.type == "checkbox"){
        iNode.checked 
= isCheck == "1"?true:false;
      }
    }
  }

  
function replaceStr(source,subjectStr,targetStr){
    
while(source.indexOf(subjectStr) != -1){
      source 
= source.replace(subjectStr,targetStr);
    }
    
return source;
  }

  
//复原到添加数据前的状态
  function reloadTable(tabObj, rowCntEachPage_){
    
if(_cloneRowIdx != -1){
      
for(var i=0; i<_factRowCount ; i++){
        tabObj.deleteRow(_cloneRowIdx 
- 1);
        _cloneRowIdx
--;
      }
      tabObj.rows[_cloneRowIdx].style.display 
='block';
    }
  }

  
//缺点,要一先执行上面的doRequest()才有值
  this.getRecordCount = function(){
    
return _recordCount;
  }
}



/**
 * 控制表格分页的类
 * write by 小城 2007/05/12
 *
 
*/
//写类的构造函数
var Class = {
    create: 
function() {
        
return function() {
            
this.initialize.apply(this, arguments);
        }
    }
}

PageManage 
= Class.create();

PageManage.prototype 
= {

    initialize: 
function(xtObj,tabID,actionSource,countEachPage) {
        
this.xtObj = xtObj;
        
this.tabID = tabID;
        
this.actionSource = actionSource;
        
this.countEachPage = countEachPage;
        
this.curentPage = 1;
        
this.recordCount;
    },

    firstPage : 
function(){
        
this.curentPage = 1
        
this.xtObj.fillTable(this.tabID,this.actionSource,1,this.countEachPage);
    },

    prePage : 
function(){
        
if((this.curentPage - 1< 1return;
        
this.curentPage--;
        
var startRow = (this.curentPage - 1)*this.countEachPage + 1;
        
this.xtObj.fillTable(this.tabID,this.actionSource,startRow,this.countEachPage);
    },

    nextPage : 
function(){
        
this.recordCount = this.xtObj.getRecordCount();
        
if(this.curentPage + 1 > Math.ceil(this.recordCount/this.countEachPage)) return;
        
this.curentPage++;
        
var startRow = (this.curentPage - 1)*this.countEachPage + 1;
        
this.xtObj.fillTable(this.tabID,this.actionSource,startRow,this.countEachPage);
    },

    lastPage : 
function(){
        
this.recordCount = this.xtObj.getRecordCount();
        
this.curentPage = Math.ceil(this.recordCount/this.countEachPage);
        
var startRow = (Math.ceil(this.recordCount/this.countEachPage) - 1)*this.countEachPage + 1;
        
this.xtObj.fillTable(this.tabID,this.actionSource,startRow,this.countEachPage);
    },

    update : 
function(me){
        
this.countEachPage = me.value;
        
this.firstPage();
    }
}

使用例子:
<table id="tab2" border="1" width="100%">
        
<tr>
            <td><span>编号</span></td>
          
   <td><span>名称</span></td>
        
</tr>
        
<tr>
          
<td align=right><span>#{ID}</span></td>
          
<td><span>#{NAME}</span></td>
        
</tr>
</table>
    
<!-- 这是没有用标签的写法 -->
    
<span style="cursor:hand" onclick="tab2_pm.firstPage();">|<</span>&nbsp;
    
<span style="cursor:hand" onclick="tab2_pm.prePage();"><<</span>&nbsp;
    
<span style="cursor:hand" onclick="tab2_pm.nextPage();">>></span>&nbsp;
    
<span style="cursor:hand" onclick="tab2_pm.lastPage();">>|</span>&nbsp;
    
<input type="text" id="tab2_recCntEachPage" value="3" onchange="tab2_pm.update(this)">
    
<script>
            
var tab2_xtObj = new XMLTable();
            
var tab2_recCntEachPage = document.getElementById("tab2_recCntEachPage").value;
            tab2_pm 
= new PageManage(tab2_xtObj,"tab2","data.xml",tab2_recCntEachPage);
            tab2_xtObj.fillTable(
"tab2","data.xml",1,tab2_recCntEachPage);  
    
</script>

今后会对分页控制的代码进行自定义标签的封装...