LOGO OA教程 ERP教程 模切知识交流 PMS教程 CRM教程 开发文档 其他文档  
 
网站管理员

Javascript 在本机浏览器中对的表格数据进行排序[转]

admin
2010年8月18日 0:58 本文热度 3522

在Web应用中,数据从服务器端返回到客户端,以表格形式表现出来。如果要对数据集按指定的列排序显示,常规做法都是向服务器发出请求,服务器端程序重新从数据库中取出按指定列排序的数据,返回给客户端,页面重新显示排序后数据。


采用这种方式有如下缺点:

1- 响应时间延迟,每次排序都要向服务器端发送请求,等待结果返回,同时增加网络负载。

2- 编程复杂,可维护性差,而且客户端和服务器端代码耦合度很高,客户端和服务器端都要处理排序涉及的列名、排序方式,如果有分页和查询条件,都需要在客户端页面中保留,排序请求时重新传递到服务器端,当参数数量很多时极易出错。

3- 重用度很低,针对不同表格,很难抽象出一个公共程序来共用,需要逐个编写代码实现,增加工作量。


现在换一个角度考虑,数据既然已下载到了客户端,在重新排序时没有必要再重服务器端获取,只要对浏览器中的数据重新排序显示就可以了。要实现该目标,需要做到以下几点:

1 - 获得表格中要排序的数据,将其放入一个2维数组中。

2 - 对2维数组排序。

3 - 用排序后的数据重新更新表格。


利用浏览器支持的DOM(Document Object Model)和JavaScript即可实现上述目标。


通常页面中会很多的<table>,要获得需要排序数据所在的table,需要在<table>中增加一个id属性,便于document对象用getElementById得到该表格对象,例如要排序的表格定义如下:

<table id="st" >

     <tr>

         <td>1</td>

         <td>2</td>

     </tr>

</table>


在javascript中,用var objTable = document.getElementById("st")就可得到表格对象,该对象在DOM中定义为一个Element。


然后用 var objRows = objTable.getElementsByTagName("tr")得到该表格中全部的行对象,ObjRows.length返回该表格行数;var rowi = objRows[i].getElementsByTagName("td")得到第i行的全部<td>节点,i从0开始计数,rowi.item(j)则可得到第i行,第j列的节点,该节点的innerHTML为该节点<td></td>之间的内容。


获取表格数据到2维数组的代码见源代码,此处略。


下面说明在javascript中2维数组的构造和排序。

javascript不支持2维数组,因此需要用数组的数组来模拟一个2维数组,其方法是先定义一个1维数组,元素个数为2维数组的行数,然后对每个元素赋一个值,值为一个数组,其元素个数为2维数组的列数。构造代码如下:


var rows = new Array(R);   //R为行数

for(var i = 0; i < rows.length; i++){

     rows[i] = new Array(C);     //C为列数

}



利用javascript中的Array.sort(comparer)对rows中的元素排序,比较方式由重新定义的比较函数得到。要根据第j列元素的大小排序,只要定义如下函数即可:


function compareCol(a,b){

    

     if (a[j] < b[j])

         return -1;


     if (a[j] > b[j])

         return 1;


    return 0;


}


因为compareCol只能有两个参数,因此j要定义为全局变量。


用rows.sort(compareCol)就可实现根据j列值的大小对行进行排序。根据javascript文档,字符串比较大小是按照其Unicode编码的大小来比较,对英文排序没有问题,对中文排序时就不是按通常的拼音排序,那需要javascript提供本地化支持,目前没有发现javascript此功能。该功能在java中可用java.text.Collator实现。



以上介绍了在本地对浏览器中的数据进行排序的主要思想,为方便使用,将这些功能进行了封装,以javascript函数的提供,存放在sorttable.js文件中,在需要的页面中用<script type=text/javascript src='sorttable.js'></script>引入。



下面说明排序函数原型和使用方法。


函数1 function sortTable(tableId,sortCol,compareType)


对页面中指定表格中的数据进行排序,通常第一行为标题行,排序时从第二行开始,第一次调用为升序排列,第二次为降序排列,依次轮换。

tableId     为<table id=''>中id的值,在同一个页面中要唯一。

sortCol     排序时用来比较大小的数据所在的列,从1开始计数。

compareType 排序时比较大小的方式,s-按字符串比较大小,n-按数字比较大小。




函数2 function sortTableInRange(tableId,sortCol,compareType,startRow,endRow,startCol,endCol)


         对表格中指定的区域数据排序,有时数据第一列为流水号,最后一行为合计,这些数据不需要参与排序,可用此函数来对部分数据排序。

        
         tableId     为<table id=''>中id的值,在同一个页面中要唯一。

         sortCol     排序时用来比较大小的数据所在的列,从1开始计数。

         compareType 排序时比较大小的方式,s-按字符串比较大小,n-按数字比较大小。

         startRow,endRow 要排序区域开始和结束行号,从1开始计数。例如对第2行到第7行排序,startRow=2,endRow=7

         startCol,endCol   要排序区域开始和结束列号,从1开始计数。





  

存在的问题:

1- 中文不能按拼音排序。



要注意的问题:

要排序的table必须用ID标示,并要作为参数传给排序函数,表格中的数据应该是可以排序的,否则结果不可预知;要排序的表格不能有嵌套表,否则排序出错。



本函数已在IE6.0 ,FireFox1.01中运行通过。源代码和例子代码见后。





参考资料:


Danny Goodman with Michael Morrison    JavaScript Bible 5th   ,John Wiley and Sons   2004


David Flanagan   JavaScript The Definitive Guide 4th ,   O'Reilly   2001






附源代码:要运行例子,需要将javascript代码保存到sorttable.js文件中,html部分代码保存到同一目录下另一文件中即可。



sorttable.js


//=========================================================
//
//   在本机对浏览器页面表格中的数据行进行排序的javascript函数
//  
//   author William   QQ: 22967225

//   create date 2005-12-2
//   version 1.0
//=========================================================


//column index for sort
var indexCol;

//比较函数,用于Array.sort()排序时比较用。
//本函数比较数组元素array1[indexCol]和元素array2[indexCol]Unicode值的大小
function arrayCompare(array1,array2){
   //alert(array1.length+"--"+array1[indexCol]);
   if (array1[indexCol] < array2[indexCol])
    return -1;
   if (array1[indexCol] > array2[indexCol])
    return 1;
  
   return 0;

}

//比较数组元素array1[indexCol]和元素array2[indexCol]的数值大小
function arrayCompareNumber(array1,array2){
  
   if (parseInt(array1[indexCol]) < parseInt(array2[indexCol]))
    return -1;
   if (parseInt(array1[indexCol]) > parseInt(array2[indexCol]))
    return 1;
  
   return 0;

}


//与arrayCompare相反方式比较大小,用于倒序使用
function arrayCompareRev(array1,array2){
  
   if (array1[indexCol] < array2[indexCol])
    return 1;
   if (array1[indexCol] > array2[indexCol])
    return -1;
  
   return 0;

}

//与arrayCompareNumber相反方式比较大小,用于倒序使用
function arrayCompareNumberRev(array1,array2){
   if (parseInt(array1[indexCol]) < parseInt(array2[indexCol]))
    return 1;
   if (parseInt(array1[indexCol]) > parseInt(array2[indexCol]))
    return -1;
  
   return 0;

}


//define a 2-dimension array
function BiArray(rows,cols){
  
   //simulate multidimension array
   this.rows = rows;
   this.cols = cols;
  
   //construct array
   var lines = new Array(rows);

   for(var i = 0;i < lines.length; i++){
    lines[i] = new Array(cols);
   }
  
  
   // 设置数组在(i,j)的元素值为value
   this.setElement = function(i,j,value){ lines[i][j] = value; };
  
   // 获取数组在(i,j)处元素的值
   this.getElement = function(i,j){return lines[i][j];};
  
   // 返回数组第i行所在的数组
   this.getLine = function(i){return lines[i];};

  
   // 根据第j列字符串的值,对数组的行进行排序,排序结果为升序
   this.sortLine = function(j){
        indexCol = j;
        lines.sort(arrayCompare);
       };
  
   // 根据第j列数值的值,对数组的行进行排序,排序结果为升序
   this.sortLineByNumber = function(j){
        indexCol = j;
        lines.sort(arrayCompareNumber);
       };

  
   // 根据第j列字符串的值,对数组的行进行排序,排序结果为倒序
   this.sortLineRev = function(j){
        indexCol = j;
        lines.sort(arrayCompareRev);
       };
  
   // 根据第j列数值的值,对数组的行进行排序,排序结果为倒序
   this.sortLineByNumberRev = function(j){
        indexCol = j;
        lines.sort(arrayCompareNumberRev);

       };

   //将二维数组转为字符串格式
   this.toString = function(){
        var rst ="";
        for(var i = 0; i < lines.length; i++){
         for(var j = 0; j < lines[i].length; j++){
          rst += lines[i][j];
          rst += '\t';
         }
         rst += '\n';
        }

        return rst;
       };

} // end of BiArray define

//ascending or descending
var asce = true;


/**
   对表格中指定范围的数据进行排序
   tableId     要排序的表格的id,值格式为 <table id="tb1" >
   sortCol     用于排序的列号,从1开始计数
   compareType    排序时比较方式,s-按字符串比较,n-按数值比较
   startRow    排序范围起始行号,从1开始计数
   endRow      排序范围结束行号,从1开始计数
   startCol    排序范围起始列号,从1开始计数
   endCol      排序范围结束列号,从1开始计数

*/
function sortTableInRange(tableId,sortCol,compareType,startRow,endRow,startCol,endCol){
  
  
   try{
    var table = document.getElementById(tableId);
    // get all row object of the table
    var objRows = table.getElementsByTagName("tr");
    //alert(objRows.length);
   
    endRow = (endRow < objRows.length ? endRow : objRows.length);
   
    var sortRows = endRow - startRow + 1;
    //alert("sortRows "+sortRows);
    if (sortRows < 2) //only one line,don't sort
     return ;
   
   
    endCol = (endCol < objRows[1].getElementsByTagName("td").length ? endCol :
      objRows[1].getElementsByTagName("td").length);
   
   
    // column number of sort
    //var cols = objRows[1].childNodes.length;
    var cols = endCol - startCol + 1;
    
   
    
    // define a array to store table cell and sort them
    var tabData = new BiArray(sortRows,cols);
   
   
    var ari = 0;
    // retrived table cell data save to array
    for(i = startRow - 1; i < endRow; i++){
     //retrived all <td> cell
     var cells = objRows[i].getElementsByTagName("td");
    
     var arj = 0;
     for(var j = startCol - 1; j < endCol; j++){
      tabData.setElement(ari,arj,cells.item(j).innerHTML);
      arj++;
     
     }
     ari++;

    }
   
    if (asce){
     if (compareType == "n" || compareType == 'N')
      tabData.sortLineByNumber(sortCol- startCol);
     else
      tabData.sortLine(sortCol - startCol);

     asce = false;
    }else{
     if (compareType == "n" || compareType == 'N')
      tabData.sortLineByNumberRev(sortCol - startCol);
     else
      tabData.sortLineRev(sortCol - startCol);
     asce = true;
    }

    ari = 0;
    //update table data with array
    for(i = startRow -1; i < endRow; i++){
     //retrived all <td> cell
     var cells = objRows[i].getElementsByTagName("td");
    
     arj = 0;
     for(var j = startCol - 1; j < endCol; j++){
      cells.item(j).innerHTML = tabData.getElement(ari,arj);
      arj++;
     }
     ari++;
    }


   }catch(e){
    alert(e);
   }
}


/**
   对表格除第一行外的数据行排序,是sortYableInRange(tableId,sortCol,compareType,2,tabRows,1,tabCols)
   的特例。
   tableId     要排序的表格的id,值格式为 <table id="tb1" >
   用于排序的列号,从1开始计数
   compareType    排序时比较方式,s-按字符串比较,n-按数值比较

*/
function sortTable(tableId,sortCol,compareType){
  
  
   try{
    var table = document.getElementById(tableId);
    // get all row object of the table
    var objRows = table.getElementsByTagName("tr");
    //alert(objRows.length);
   
   
    var endRows = objRows.length;
   
    if (endRows < 2) //only one line,don't sort
     return ;
   
    // column number of table
    var cols = objRows[1].getElementsByTagName("td").length;
   
   
    sortTableInRange(tableId,sortCol,compareType,2,endRows,1,cols);
   

   }catch(e){
    alert(e);
   }
}

==========javascript 代码结束============


例子HTML页面代码


<html>
<head content="text/html; charset=gb2312" >
<script type="text/javascript" src="sorttable.js">
</script>
</head>
<body>
   常规排序例子<br>
   <table id="t1" border="1">
    <tr>
     <td width="20%"><a href="#" onclick="sortTable('t1',1,'s')" >城市</a></td>
     <td width="30%"><a href="#" onclick="sortTable('t1',2,'s')" >品牌</a></td>
     <td width="30%"><a href="#" onclick="sortTable('t1',3,'n')" >销量</a></td>
    </tr>
    <tr>
    
     <td><a href="#" >北京</a></td>
     <td>GOOGLE</td>
     <td>64</td>
    </tr>
    <tr>
     <td>上海</td>
     <td>CISCO</td>
     <td>54</td>
    </tr>

    <tr>
     <td>广州</td>
     <td>MS</td>
     <td>9</td>
    </tr>

    <tr>
    
     <td>南京</td>
     <td>INTEL</td>
     <td>120</td>
    </tr>

   </table>



   <br>对部分数据排序例子(对第2-5行,第2-4列区域排序)<br>
   <table id="t2" border="1">
    <tr>
     <td>序号</td>
     <td width="20%"><a href="#" onclick="sortTableInRange('t2',2,'s',2,5,2,4)" >城市</a></td>
     <td width="30%"><a href="#" onclick="sortTableInRange('t2',3,'s',2,5,2,4)" >品牌</a></td>
     <td width="30%"><a href="#" onclick="sortTableInRange('t2',4,'n',2,5,2,4)" >销量</a></td>
    </tr>
    <tr>
     <td>1</td>
     <td><a href="#" >北京</a></td>
     <td>GOOGLE</td>
     <td>64</td>
    </tr>
    <tr>
     <td>2</td>
     <td>上海</td>
     <td>CISCO</td>
     <td>54</td>
    </tr>
    <tr>
     <td>3</td>
     <td>广州</td>
     <td>MS</td>
     <td>9</td>
    </tr>
    <tr>
     <td>4</td>
     <td>南京</td>
     <td>INTEL</td>
     <td>120</td>
    </tr>
   </table>
</body>
</html>

该文章在 2010/8/18 0:58:43 编辑过
关键字查询
相关文章
正在查询...
点晴ERP是一款针对中小制造业的专业生产管理软件系统,系统成熟度和易用性得到了国内大量中小企业的青睐。
点晴PMS码头管理系统主要针对港口码头集装箱与散货日常运作、调度、堆场、车队、财务费用、相关报表等业务管理,结合码头的业务特点,围绕调度、堆场作业而开发的。集技术的先进性、管理的有效性于一体,是物流码头及其他港口类企业的高效ERP管理信息系统。
点晴WMS仓储管理系统提供了货物产品管理,销售管理,采购管理,仓储管理,仓库管理,保质期管理,货位管理,库位管理,生产管理,WMS管理系统,标签打印,条形码,二维码管理,批号管理软件。
点晴免费OA是一款软件和通用服务都免费,不限功能、不限时间、不限用户的免费OA协同办公管理系统。
Copyright 2010-2024 ClickSun All Rights Reserved