数据表客户端排序及其他特色实现

        当我们的页面中数据表行非常多时,为了很方便的找到我们需要的及相关纪录行时,大都采用排序的方式,对于现在的开发,几乎不需要写什么代码就能很容易的排序,如:asp.net 2.0中的GridView,如果数据源是DataSet的话,什么都不用写,仅需要设置几个属性就可以了。但这种排序存在着性能上劣势,因为你每次排序时,都会提交该页面,在服务器端进行相应的排序操作,然后将生成的排序页面传递到客户端,这样作会增加用户的等待时间,影响用户的使用感觉。
       如果用户想对他所查看的客户端数据进行一个快速的排序,而不希望将页面提交到服务器,花费太长的等待时间,这时候我们就应该采用客户端排序的解决方案。
       仔细的研究一下数据表中的数据,我们就可以发现其中的各项数据可以分为这样三种类型:字符串、时间、数字。客户端的排序实质上就是实现这三种数据类型的排序。
       在javaScript中虽然提供了Date的数据类型,但为了获得更好的性能,减少由字符串向Date类型转换的成本,我们在这里采用了服务端数据输出妥协的办法,指的是在服务器端输出时间类型的字段时,可以利用string.Format("{0:yyyy-MM-dd}", DateValue)这种方式来生成适合客户端排序的时间字符串。这样时间的排序其实就转化为了字符串的排序。
       到这里关于排序的数据类型已经确定了下来,接下来的就是如何实现了。
       在排序中要用到如下的几个关键的技术点:
              1. currentTable.rows[i].cells[j].innerText.toLowerCase()
              2. 冒泡排序
              3. currentTable.moveRow(i,i+1);
              4. 利用eval(numberString)或者new Number(numberString)实现字符串向数字的转换;
       剩下的基本上属于代码开发技巧上的东西了。

      在实际的应用中,为了避免用户在查看每一行数据不至于和其他行相互混淆,我们常设置表格隔行背景颜色,这还不够,要更好的改善用户体验,还要利用数据行上鼠标的onmouseover,onmouseout及onmouseclick事件来改变当前行的背景色。这样用户就可以更加清楚地查看每一行的数据了。

      本节所叙述的解决方案是做成了一个*.htc,目的是为了以最方便的方式使用该程序,使用起来非常简单,仅需要设置当前table的style属性就可以了。您可以用如下方式实现数据表客户端排序的功能:
<table style=”behavior:url(lovetable.htc)” overColor=”red” clickColor=”Yellow”>……
就这么简单,套用了该样式的表将会自动启用各列的排序功能。其中的overColor、clickColor分别为鼠标滑过、单击时对应行的背景色;你也可以不设,而采用htc提供的默认颜色。此htc是针对asp.net 2.0 中的gridview 量身定做,你可以用如下方式利用到gridview上:<asp:GridView  runat="server" BackColor="#E5F1FF" BorderColor="#E5F1FF" BorderWidth="0px" CellPadding="3" CellSpacing="1" GridLines="None" Style="behavior: url(App_Themes/Blue/loveTable.htc)">.....同样可以在其中设定overcolor和clickcolor属性的值。


本文代码如下:
loveTable.htc(V1.0)

<PUBLIC:ATTACH EVENT="oncontentready" ONEVENT="init()" />
<PUBLIC:PROPERTY NAME="OverColor" />
<PUBLIC:PROPERTY NAME="ClickColor" />

<SCRIPT LANGUAGE="JScript">
/* loveTable.htc
    table client sort,table row mouse move/click events response.

    Author:         Ge.shaofei(2005.8.23 --- 2005.8.25)
     
    Description:
                         A. realize data table client every column up and down sorting.
                         B. using *.htc to provider the easiest way to utilize it.
                         C.  response the onmouseover,onmouseout,onclick event to change the current row backgroundcolor.
                         D.  To be modify to adapter advanced requirement.

    Design Roadmap: A:  bubble sorting;
                            B:  currentTable.rows[i].cells[j].innerText.toLowerCase();
                            C:  currentTable.moveRow(i,i+1);
                            D:  use eval(numberString) or new Number(numberString) to convert numberString to number;

    Version Specification:  V1.0 ;

    Use Method:             <table style="behavior:url(lovetable.htc)" overColor="red" clickColor="Yellow">.....</table>
                           
    Use Attention:    A.  the browser must support *.htc;
                            B.  overColor/clickColor can be ignored to use the default values;
                            C.  change the sorting image to the right path;
*/
var lastclick = -1;
var reverse = false;
var clickObject;
var arrIsNumberCols;
var bc1,bc2;
var validRowsCount;
var overColor,clickColor;
function init()
{
    if(element.rows.length < 2) return;
    element.attachEvent("onmouseover",overthis);
    element.attachEvent("onmouseout",outthis);
    element.attachEvent("onclick",clickthis);
   
    if(OverColor == null) OverColor = "#B4D7FF";
    if(ClickColor == null) ClickColor = "#ffefce";
    theadrow = element.rows[0];
 theadrow.runtimeStyle.cursor = "hand";
 
    validRowsCount = element.rows.length;
    if(element.rows[validRowsCount-1].cells.length == 1)
        validRowsCount = validRowsCount-1;
       
 colCount = theadrow.cells.length;
    arrIsNumberCols = new Array(colCount);
 var l, clickCell;
 for (var i=0; i<colCount; i++)
 {
  l=document.createElement("IMG");
  l.src="App_Themes/Blue/images/blank.gif";
  l.id="srtImg";
  l.width=8;
  l.height=7;

  clickCell = theadrow.cells[i];
  clickCell.selectIndex = i;
  clickCell.insertAdjacentElement("beforeEnd", l)
  clickCell.attachEvent("onclick", doClick);
  
  arrIsNumberCols[i] = isNumberCol(i);
 }

    bc1 = element.rows[1].style.backgroundColor;
    if(validRowsCount > 1)
    {
        for( i=2;i <= validRowsCount-1; i++)
        {
            if(element.rows[i].style.backgroundColor != bc1)
            {
                bc2 = element.rows[i].style.backgroundColor;
                break;
            }
        }
    }
    if( bc2 == null ) bc2 = bc1;

}

function isNumberCol(colIndex)
{
    var numberCol = true;
    for( i = 1; i < validRowsCount; i++ )
    {
        if(isNaN(element.rows[i].cells[colIndex].innerText))
        {
            numberCol = false;
            break;
        }
    }
    return numberCol;
}

function doClick(e)
{
 clickObject = e.srcElement;
 if(clickObject.tagName == "A") return;

 while (!((clickObject.tagName == "TH") || (clickObject.tagName == "TD")))
 {
  clickObject = clickObject.parentElement;
 }

 if(lastclick == clickObject.selectIndex)
 {
  if(reverse == false)
  {
   clickObject.children['srtImg'].src = "App_Themes/Blue/images/down.gif";
      reverse = true;
  }
  else
  {
   clickObject.children['srtImg'].src = "App_Themes/Blue/images/up.gif";
   reverse = false;
  }
 }
 else
 {
  reverse = false;
  if(lastclick != -1) theadrow.all('srtImg')[lastclick].src = "App_Themes/Blue/images/blank.gif";
  lastclick = clickObject.selectIndex;
  clickObject.children['srtImg'].src = "App_Themes/Blue/images/up.gif";
 }
 insertionSort();
 hilite();
}

function insertionSort()
{
    var comparedText,currentText,tempRow;
    var colIndex = clickObject.selectIndex;
    var exchange;
    for ( i = 1 ; i < validRowsCount ; i++ )
    {
        exchange = false;
        for ( j = validRowsCount-2; j >= i ; j-- )
        {
          comparedText = element.rows[j].cells[colIndex].innerText.toLowerCase();
   currentText = element.rows[j+1].cells[colIndex].innerText.toLowerCase();
      if (arrIsNumberCols[colIndex])
      {
       comparedText= eval(comparedText);
       currentText= eval(currentText);
      }
            if ((reverse && currentText > comparedText) || (!reverse && currentText < comparedText))
            {
                element.moveRow(j,j+1);
                exchange = true;
            }
        }
        if(!exchange)
            break;
    }
}

function hilite()
{
    var hiliteSwitch = false;
    var getClickbakRowIndex = false;
    for(i=1;i < validRowsCount; i++)
    {
        if(hiliteSwitch)
        {
            element.rows[i].style.backgroundColor = bc1;
        }
        else
        {
            element.rows[i].style.backgroundColor = bc2;           
        }
        hiliteSwitch = !hiliteSwitch;
       
        if(!getClickbakRowIndex)
        {
            if(element.rows[i].runtimeStyle.backgroundColor == ClickColor)
            {
                clickbakRowIndex = i;
                getClickbakRowIndex = true;
            }
        }
    }
}

function overthis()
{
    if(event.srcElement != element)
    {
     var currentRow = getTR();
     if(currentRow.rowIndex != 0 && currentRow.rowIndex != clickbakRowIndex)
     {
         currentRow.runtimeStyle.backgroundColor = OverColor;
     }
    }
}

function outthis()
{
    if(event.srcElement != element)
    {
     var currentRow = getTR();
     if(currentRow.rowIndex != 0 && currentRow.rowIndex != clickbakRowIndex)
      currentRow.runtimeStyle.backgroundColor = '';
    }
}

var clickbakRowIndex = -1;
function clickthis()
{
    if(event.srcElement != element)
    {
     var currentRow = getTR();
         if(currentRow.rowIndex != 0)
         {
             if(clickbakRowIndex != -1)
             {
                 element.rows[clickbakRowIndex].runtimeStyle.backgroundColor = ''
             }
             clickbakRowIndex = currentRow.rowIndex;
             currentRow.runtimeStyle.backgroundColor = ClickColor;
         }
    }
}

function getTR()
{
    var obj = event.srcElement.parentElement;
    while (obj.tagName != "TR")
     obj = obj.parentElement;
 return obj;
}

</SCRIPT>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值