在开发WEB应用程序的时候,我们经常会碰到这样一些问题。
比如检索一个商品信息表(编号,名称,价格,产地)时,我们需要取出商品编号,名称,价格,产地等信息。
假如得到的检索结果如下:
编号 | 名称 | 价格 | 产地
-------------------------------------------------------
001 | 苹果 | 3.50 | 山东
002 | 香蕉 | 2.00 | 海南
003 | 雪梨 | 3.00 | 贵州
这时,如果我们想要以价格的高低重新排序的话,当然可以改变数据库的排序条件,重新从数据库抽取数据。
但是,当采用分页显示的时,当用户看到第N页的时候,如果突然向以另一种排序方式查看当前页面的数据的话,即使改变数据库的排序方式,也很难达到目的,因为排序方式改变之后,按照另一种方式排序在一个页面数据都基本上分布到好几个不同的页面上。
如果能用客户端脚本来实现的话,那我们就可以不用再考虑整体数据的顺序了,可以任意控制当前数据页的排序。
下面开始就以JavaScript为例简单介绍实现流程。
1.我们知道,用HTML显示表格用的是TABLE这个标签,这其中每一行用一个TR标签标识,而每个TR又有很多个TD组成。上面的检索结果用HTML表示的结果如下:
<TABLE>
<TR><TD>001</TD> <TD>苹果</TD><TD>3.50</TD><TD>山东</TD><TR>
<TR><TD>002</TD> <TD>香蕉</TD><TD>2.00 </TD><TD>海南</TD><TR>
<TR><TD>003</TD> <TD>雪梨</TD><TD>3.00</TD><TD>贵州</TD><TR>
<TABLE>
2.要排序,就需要对排序列的表格数据进行比较操作。因此,我们需要为TABLE指定一个ID来识别表格。加上ID的表格数据如下所示:
<TABLE ID=oTable>
<TR><TD>001</TD> <TD>苹果</TD><TD>3.50</TD><TD>山东</TD></TR>
<TR><TD>002</TD> <TD>香蕉</TD><TD>2.00 </TD><TD>海南</TD></TR>
<TR><TD>003</TD> <TD>雪梨</TD><TD>3.00</TD><TD>贵州</TD></TR>
</TABLE>
3.读取表格数据,然后进行排序,我们可以用TABLE标签的rows集合来获取所有的数据行,然后再用cells集合获取列,最近进行排序。下面是用JavaScript实现的函数表格排序,全部的源程序如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head><title>用JavaScript实现表格数据的排序</title>
<meta http-equiv="Content-type" content="text/html; charset=GB2312">
<meta http-equiv="Content-Script-Type" content="text/javascript">
<meta http-equiv="Content-Style-Type" content="text/css">

<script language="JavaScript">...
<!--
function swapData(i,j)

...{
recObj = document.getElementById('oTable');
itemCount = recObj.rows[i].cells.length;
//交换第i行和第j行的数据
//注:如果只需要兼容IE的话,下面的循环可以用swapNode这个函数代替
//recObj.rows[i].swapNode(recObj.rows[j]);
for(n = 0; n < itemCount; n++)

...{
tmp = recObj.rows[i].cells[n].innerHTML;
recObj.rows[i].cells[n].innerHTML = recObj.rows[j].cells[n].innerHTML;
recObj.rows[j].cells[n].innerHTML = tmp;
}
}
//除去空格
function trim(str)

...{
var re = /^s*/gim;
str = str.replace(re,"");
re = /s*$/gim;
str = str.replace(re,"");
return str;
}
function sort(key,up)

...{
recObj = document.getElementById('oTable');
if(recObj.rows.length == 0)

...{
return;
}
itemCnt = recObj.rows.length;
obj = recObj.rows;
i = 0;
j = 0;
switch(key)

...{
case 'BH'://编号
case 'MC'://名称
case 'CD'://产地
if(key == 'BH')
subIndex = 0;
else if(key == 'MC')
subIndex = 1;
else if(key == 'CD')
subIndex = 3;
for(i = 0;i < itemCnt - 1; i++)

...{
objA = obj[i].cells[subIndex];//第i+1行subIndex+1列的TD标签对象
for(j = i + 1; j < itemCnt; j++)

...{
objB = obj[j].cells[subIndex];//第j+1行subIndex+1列的TD标签对象
if(trim(objB.innerHTML) == "")

...{
continue;
}
if((up && (objA.innerHTML > objB.innerHTML)) || (!up && (objA.innerHTML < objB.innerHTML)) )

...{
swapData(i,j);//数据交换
}
}
}
break;
case 'JG'://价格
subIndex = 2;
for(i = 0;i < itemCnt - 1; i++)

...{
objA = obj[i].cells[subIndex];//第i+1行subIndex+1列的TD标签对象
for(j = i + 1; j < itemCnt; j++)

...{
objB = obj[j].cells[subIndex];//第j+1行subIndex+1列的TD标签对象
if(trim(objB.innerHTML) == "" || isNaN(objB.innerHTML))

...{
continue;
}
else if(trim(objA.innerHTML) == ""
|| isNaN(objA.innerHTML)
|| (up && (eval(objA.innerHTML) > eval(objB.innerHTML)))
|| (!up && (eval(objA.innerHTML) < eval(objB.innerHTML))) )

...{
swapData(i,j);//数据交换
}
}
}
break;
default:
break;
}
}
-->
</script>
</head>
<body>
<table id=oTable>
<tr><td>001</td> <td>苹果</td><td>3.50</td><td>山东</td></tr>
<tr><td>002</td> <td>香蕉</td><td>2.00 </td><td>海南</td></tr>
<tr><td>003</td> <td>雪梨</td><td>3.00</td><td>贵州</td></tr>
</table>
<input type=button value="编号升序" onclick="sort('BH',true)">
<input type=button value="编号降序" onclick="sort('BH',false)">
<input type=button value="名称升序" onclick="sort('MC',true)">
<input type=button value="名称降序" onclick="sort('MC',false)">
<input type=button value="价格升序" onclick="sort('JG',true)">
<input type=button value="价格降序" onclick="sort('JG',false)">
<input type=button value="产地升序" onclick="sort('CD',true)">
<input type=button value="产地降序" onclick="sort('CD',false)">
</body>
</html>

※如果要看运行效果,将上面的程序段保存到一个HTML文件,直接用IE等浏览器打开即可。
4.为了说明简单,上面的排序算法用的是最简单的冒泡算法,用兴趣的读者完全可以按照自己的需求采用不同的算法。