分享
 
 
 

基于css样式绑定的样式驱动式AJAX程序开发(.net实现)

王朝html/css/js·作者佚名  2008-05-31
窄屏简体版  字體: |||超大  

序言:

前面我介绍了我做的.net版的ajax库(.NET下的简单AJAX处理库 ),现在要介绍的是一种开发模式:样式绑定式驱动开发。

样式驱动是我自己命名的,(我也不知道它叫什么,嘿嘿)以便区别目前的请求驱动式开发(如struts、webwork等)和事件驱动式开发(如asp.net、JSF等)。

正文:

1 简介

首先,让我们来看看传统的WEB开发流程:

·请求驱动: 最常见的一类WEB框架实现了以请求驱动的流程。一个HTTP请求近来,被一个通用的分发器Servlet

(Dispather Servlet)分析,再被分发到一个对应的应用处理器。处理器依次处理UI特有的控制逻辑,调用业务对象和处理会

话状态,准备一个模型,再转发到视图。

·事件驱动: 事件驱动框架的设计目标是将桌面UI编程中著名的事件驱动模式搬到WEB环境中来。其特征是;对于如何将

表单提交到URL、如何将URL映射到控制器这些问题它们不关心;在事件驱动的框架中,表单组件和监听器联系在一起,监听器

通过事件开调用。而且,这类框架通常不打算实现可插拔的试图技术来呈现给特定的模型对象,而是把WEB页看作一写列界面组

件的组合物,每个组件可以保持自己的状态,并且知道如何呈现自己,甚至可能使用不同界面皮肤。

从上面可以看到一个是传统的MVC架构是开发,一个是以页面为中心的快速应用开发(RAD)两者各有各的好处。

样式驱动式开发在请求驱动开发或事件驱动开发的基础上进行简单的封装,在界面层融合了以上两者概念优势,它以最前台

的界面层为基础,通过CSS样式或HTC事件绑定界面元素来执行相应后台业务,从而达到执行相应请求,处理相应的事件的目的

样式驱动的优势在于只需把前台元素赋予特定的样式,即可实现特殊的动能以及特定的业务处理,从而减少编码量和编译的

次数,具有“一次编写,到处绑定”的特点。比传统开发复用性更强。尤其是在AJAX大行其道的今天,在请求驱动框架或事件

驱动现有框架的基础上利用样式绑定式开发基于AJAX的应用,你会发现你的AJAX程序的开发效率会提高很多,尤其是当反复应

用同一(或相似)后台逻辑的情况会更明显,同样,样式绑定式开发对于面向服务式开发也具有很大的优势。

2 基于ASP.NET的样式驱动开发

样式驱动的操作不依赖与后台实现,asp.net的runat=server可以魔法搬地将前台元素转化为后台的元素,不过这样的转化

依赖于特定的元素和后台,比如<input type=text runat=server> 这样确实是将input元素扩展成后台可以使用的服务器元素

了,但是对于后台来讲他要在页面对应的里进行特定的处理,而且input type=text只能是input type=text也不可能扩展自己

的功能。样式驱动则可以把一切元素、控件或控件中的元素利用JS的强大功能在前台转换为你想要的功能和效果,然后再送入

原请求或自定义请求,从而弥补asp.net的一些不足,“一次编写,到处绑定”的特点也为我们省去了多个页面类写重复代码的

诸多困扰。

也许你会说不是有用户控件吗,很抱歉,用户控件跟前台严重耦合,你将它拿到一个项目中也许派不上一点用场。

那WEB控件库呢?虽然能重用,跟用户控件比不耦合了,但是局限性太强,复杂度高,我觉得叫一个普通程序员写一个带模

板项的DataGird能排序的,可以删除、修改、上移下移]可以查看详细信息的控件出来是一件很费事的事。

又有人说了,真笨,我直接拖一个DATAGRID然后再这个基础上加按纽,模板列,排序,详细连接好不好啊,还用特意做个

控件吗?有很抱歉的告诉你,如果是1000个DATAGIRD,每一个都有这些功能的一种或几种,那么你后台够写的了,即使你抽象

出一层、封装出一个专门的DataGirdBuilder类,也够复杂的,各种重载方法,晕。

那么使用样式绑定式的开发就简单了,给DataGird个排序的样式(比如CssClass=sort),后台几句代码,或者干脆不写(

你的准备比较充足),就可以了,再加个列变为删除按钮(比如其中的一个列里ItemStyle CssClass="delbtn"),就可以了,

别的DataGrid不需要排序,那么样式去掉。而后页面类里干干静静。样式绑定后变化的元素传值到统一的业务对象进行处理,

一切都很规矩。

3 实现

利用我之前做过的AJAX库,再结合Javascript脚本构建一个这样的库不成问题。自然,跟做烧饭做菜一样,这里选料非常的

重要,这里我要选用来自Dean Edwards和Tino Zijdel的事件操作脚本库(common.js)和Neil Cro~~~~y制作的样式基本操作库(

css.js)来做好我们这道美味,噢,当然,还有大名鼎鼎的prototype.js库.

好了,,前台的制作工序基本完成。

然后就是利用我前一阵子做的AJAX库了。

假设是删除,QueryString: command=delrow&JS生成的参数……

则后台调用AjaxDelRow.cs

protected override void DoAjax()

...{

// 搜集参数

string parlist = request.Params["pars"];

string[] paritem = parlist.Split('|');

Hashtable hash = new Hashtable(paritem.Length);

for(int i=0;i<paritem.Length-1;i++)

...{

string[] paritempart = paritem[i].Split('^');

hash.Add(paritempart[0],paritempart[1]);

}

bool isDeled = false;

string table = request.Params["table"];

// 判断来源

if(table!=null)

...{

if(table.Equals("dgBigclassmanage")) //DATAGRID的ID号

...{

// 调用对应业务外观的DAO来删除

// hash["0"]为datagrid的第0列,假设第0列传过来是ID值

isDeled = (new BusinessFacade()).DeleteById(hash["0"].ToString());

}

if(isDeled)

...{

Output("true");

}

else

...{

Output("false");

}

}

AjaxDelRow制作流程请参考.NET下的简单AJAX处理库

好了,完成删除,,那么所有对应这个业务的删除都可以由命名为dgBigclassmanage的某一元素通过绑定delbtn样式来执行删

除(当然,这样不科学,不过是DEMO嘛,如果是实际你可以在QueryString里多传一个参数,在到AjaxDelRow派发后再用进行二

次派发,然后以这个参数做标识就完美了)由于麻烦,,有兴趣的自己做吧。。 呵呵。

这个样式只依赖TABLE元素,所以DATAGRID、DATALIST、自己做的TABLE,自定义控件只要最后生成TABLE元素的控件都可以用。

主要提供一个思想,跟代码制作的好坏无关。在.NET里轻量地使用样式绑定,在有AJAX应用的开发中效果很棒。你也可以自己去实现一个更优秀的轻量框架了。

增删改、上下移动记录样式绑定的JS:

/**//**

* Written by Wangzhongyuan

*

* 这是一个样式驱动的功能按钮控制脚本,样式用法如下:

*

* 修改按钮样式: editgtn 应用样式后即可把目标元素变为修改按钮,目标行变为修改行并出现确定、取消按钮。

* 删除按钮样式: delbtn 应用样式后即可把目标元素变为删除按钮,点击删除则目标删除。

* 上移下移按钮样式: updownbtn 应用样式后即可把目标元素变为上移、下移元素,目标行变为可上移和下移。

*

* 其他需要样式正在制作中........

**/

var crudbtn = ...{

that: false,

isOdd: false,

lastAssignedId : 0,

addbtnid : 0,

newRows: -1,

init : function() ...{

// 首先, 查看浏览器是否能执行此脚本(有些浏览器不能用getElementsByTagName)

if (!document.getElementsByTagName) ...{

return;

}

this.that = this;

this.run();

},

/**//**

* 遍历document中的所有table,如果有样式crudtable,则应用此脚本

*

**/

run : function() ...{

var tables = document.getElementsByTagName("table");

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

var thisTable = tables[i];

if (css.elementHasClass(thisTable, 'crudtable')) ...{

this.makecrudTable(thisTable);

}

}

},

/**//**

* 构建控制按钮

**/

makecrudTable : function(table) ...{

// 首先, 检测table是否有id,如果没有则创建

if (!table.id) ...{

table.id = 'crudTable'+this.lastAssignedId++;

}

// 遍历表格的数据行

var newRows = new Array();

// 遍历表格所有数据行

for (var j = 0; j < table.tBodies[0].rows.length-1; j++) ...{

// 遍历数据行所有列

for(var k = 0;k < table.tBodies[0].rows[j+1].cells.length;k++) ...{

// 判断是否存在删除样式,如果存在则把该单元个转化为删除按钮

if(css.elementHasClass(table.tBodies[0].rows[j+1].cells[k], 'delbtn')) ...{

table.tBodies[0].rows[j+1].cells[k].id = 'delbtn'+this.addbtnid ++;

var linkEl = createElement('a');

linkEl.href = '#';

linkEl.onclick = this.delRow;

linkEl.setAttribute('columnId', k);

var innerEls = table.tBodies[0].rows[j+1].cells[k].childNodes;

linkEl.innerText = "删除";

table.tBodies[0].rows[j+1].cells[k].appendChild(linkEl);

}

// 判断是否存在修改样式,如果存在则把该单元个转化为修改按钮

if(css.elementHasClass(table.tBodies[0].rows[j+1].cells[k], 'editbtn')) ...{

table.tBodies[0].rows[j+1].cells[k].id = 'delbtn'+this.addbtnid ++;

var linkEl = createElement('a');

linkEl.href = '#';

linkEl.onclick = this.editRow;

linkEl.setAttribute('columnId', k);

var innerEls = table.tBodies[0].rows[j+1].cells[k].childNodes;

linkEl.innerText = "修改";

table.tBodies[0].rows[j+1].cells[k].appendChild(linkEl);

}

// 判断是否存在上移、下移样式,如果存在则把该单元个转化为上移、下移按钮

if(css.elementHasClass(table.tBodies[0].rows[j+1].cells[k], 'updownbtn')) ...{

table.tBodies[0].rows[j+1].cells[k].id = 'updownbtn'+this.addbtnid ++;

var linkEl = createElement('a');

linkEl.href = '#';

linkEl.onclick = this.upRow;

linkEl.setAttribute('columnId', k);

var innerEls = table.tBodies[0].rows[j+1].cells[k].childNodes;

linkEl.innerText = "上移";

table.tBodies[0].rows[j+1].cells[k].appendChild(linkEl);

var p = createElement('span');

p.innerHTML = "&nbsp;&nbsp;";

table.tBodies[0].rows[j+1].cells[k].appendChild(p);

var linkEl2 = createElement('a');

linkEl2.href = '#';

linkEl2.onclick = this.downRow;

linkEl2.setAttribute('columnId', k);

var innerEls2 = table.tBodies[0].rows[j+1].cells[k].childNodes;

linkEl2.innerText = "下移";

table.tBodies[0].rows[j+1].cells[k].appendChild(linkEl2);

}

}

}

// 隔行换颜色,依赖odd样式

this.isOdd = true;

var rows = table.tBodies[0].rows;

// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones

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

this.doStripe(rows[i+1]);

}

},

/**//**

* 隔行分色策略,依赖odd样式

**/

doStripe : function(rowItem) ...{

if (!this.isOdd) ...{

css.addClassToElement(rowItem, 'odd');

} else ...{

css.removeClassFromElement(rowItem, 'odd');

}

this.isOdd = !this.isOdd;

},

/**//**

* 删除目标列

**/

delRow : function(e) ...{

var that = crudbtn.that;

var linkEl = getEventTarget(e);

var td = linkEl.parentNode;

var tr = td.parentNode;

var thead = tr.parentNode;

var table = thead.parentNode;

if (!table.tBodies || table.tBodies[0].rows.length <= 1) ...{

return false;

}

this.isOdd = true;

var rows = table.tBodies[0].rows;

// 实现AJAX调用处理删除

var pars = "pars=";

for(h=0;h<tr.cells.length;h++) ...{

if(!css.elementHasClass(tr.cells[h],'editbtn')&&!css.elementHasClass(tr.cells[h],'delbtn')

&&!css.elementHasClass(tr.cells[h],'updownbtn')) ...{

var colid = tr.cells[h].getAttribute('columnId');

if(tr.cells[h].firstChild.value!=null) ...{

pars += h +"^"+ tr.cells[h].firstChild.value +"|";

}

else ...{

pars += h +"^"+ tr.cells[h].innerText +"|";

}

}

}

pars += "&command=delrow&callback=afterUpdate&table="+table.id;

table.deleteRow(tr.rowIndex);

// 重新隔行换色

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

if (!this.isOdd) ...{

css.addClassToElement(rows[i], 'odd');

} else ...{

css.removeClassFromElement(rows[i], 'odd');

}

this.isOdd = !this.isOdd;

}

new Ajax.Updater('result','Dispatcher.ajax?'+pars,...{evalScripts: true});

if(table.rows.length<=1) ...{

alert("该页已无数据,系统将重载数据项");

window.location = "?";

}

},

/**//**

* 修改按钮

**/

editRow : function(e) ...{

var that = crudbtn.that;

var linkEl = getEventTarget(e);

var td = linkEl.parentNode;

var tr = td.parentNode;

var thead = tr.parentNode;

var table = thead.parentNode;

var column = linkEl.getAttribute('columnId') || td.cellIndex;

var cellcount = tr.cells.length;

// 如果没点击修改

if(tr.getAttribute('editing')!=1) ...{

for(var o=0;o<cellcount;o++) ...{

// 如果该列含有修改样式、删除样式或其他类似样式,则忽略该列

if(!css.elementHasClass(tr.cells[o],'editbtn')&&!css.elementHasClass(tr.cells[o],'delbtn')

&&!css.elementHasClass(tr.cells[o],'updownbtn') &&!css.elementHasClass(tr.cells[o],'noedit')) ...{

var inputEl = createElement('input');

inputEl.type = "text";

// 文本框大小

// inputEl.size = tr.cells[o].innerText.length*2; inputEl.size = tr.cells[o].innerText.replace(/[^\x00-\xff]/gi,'xx').length;

tr.cells[o].setAttribute('columnId', o);

inputEl.setAttribute('oldValue', tr.cells[o].innerHTML);

var inputEls = tr.cells[o].innerText;

inputEl.value = inputEls;

tr.cells[o].firstChild.removeNode(true);

tr.cells[o].appendChild(inputEl);

tr.setAttribute('editing',1);

linkEl.setAttribute('oldValue',linkEl.innerText);

}

}

linkEl.innerText = "确定";

var p = createElement('span');

p.innerHTML = "&nbsp;&nbsp;";

td.appendChild(p);

var linkEl2 = createElement('a');

linkEl2.href="#";

linkEl2.onclick = that.cancelRow;

linkEl2.innerText = "取消";

td.appendChild(linkEl2);

}

else

...{

// 如果已经点击了确定

var pars = "pars=";

if(tr.getAttribute('editing')!=0) ...{

td.childNodes[0].removeNode(true);

td.childNodes[0].removeNode(true);

td.childNodes[0].removeNode(true);

var linkEl2 = createElement('a');

linkEl2.href="#";

linkEl2.onclick = that.editRow;

linkEl2.innerText = "修改";

td.appendChild(linkEl2);

for(h=0;h<tr.cells.length;h++) ...{

if(!css.elementHasClass(tr.cells[h],'editbtn')&&!css.elementHasClass(tr.cells[h],'delbtn')

&&!css.elementHasClass(tr.cells[h],'updownbtn')) ...{

var colid = tr.cells[h].getAttribute('columnId');

if(tr.cells[h].firstChild.value!=null)

pars += h +"^"+ tr.cells[h].firstChild.value +"|";

else

pars += h +"^"+ tr.cells[h].innerText +"|";

}

if(!css.elementHasClass(tr.cells[h],'editbtn')&&!css.elementHasClass(tr.cells[h],'delbtn')

&&!css.elementHasClass(tr.cells[h],'updownbtn') &&!css.elementHasClass(tr.cells[h],'noedit')) ...{

tr.cells[h].innerHTML = tr.cells[h].firstChild.value;

}

}

pars = pars.substr(0,pars.length-1);

tr.setAttribute('editing',0);

pars += "&command=editrow&callback=afterUpdate&table="+table.id;

new Ajax.Updater('result','Dispatcher.ajax?'+pars,...{evalScripts: true});

}

}

},

/**//**

* 取消修改

**/

cancelRow : function(e) ...{

var that = crudbtn.that;

var target = getEventTarget(e);

var td = target.parentNode;

var tr = td.parentNode;

var thead = tr.parentNode;

var table = thead.parentNode;

var column = target.getAttribute('columnId') || td.cellIndex;

for(var o=0;o<tr.cells.length-1;o++) ...{

// 如果该列含有修改样式、删除样式或其他类似样式,则忽略该列

if(!css.elementHasClass(tr.cells[o],'editbtn')&&!css.elementHasClass(tr.cells[o],'delbtn')

&&!css.elementHasClass(tr.cells[o],'updownbtn') &&!css.elementHasClass(tr.cells[o],'noedit')) ...{

tr.cells[o].innerHTML = tr.cells[o].firstChild.getAttribute('oldValue');

tr.setAttribute('editing',0);

target.innerText = target.getAttribute('oldValue');

}

}

var linkEl = createElement('a');

linkEl.href = '#';

linkEl.onclick = that.editRow;

td.firstChild.removeNode(true);

td.firstChild.removeNode(true);

td.firstChild.removeNode(true);

var innerEls = td.childNodes;

linkEl.innerText = "修改";

td.appendChild(linkEl);

td.setAttribute('columnId', column);

},

/**//**

* 上移按钮

**/

upRow : function(e) ...{

var that = crudbtn.that;

var linkEl = getEventTarget(e);

var td = linkEl.parentNode;

var tr = td.parentNode;

var thead = tr.parentNode;

var table = thead.parentNode;

// var column = linkEl.getAttribute('columnId') || td.cellIndex;

var oTr = tr.innerHTML;

if(tr.rowIndex == 1) ...{

alert("已经是第一行了");

return false;

}

else ...{

table.moveRow(tr.rowIndex,tr.rowIndex-1);

this.isOdd = true;

var rows = table.tBodies[0].rows;

// 重新隔行换色

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

if (!this.isOdd) ...{

css.addClassToElement(rows[i], 'odd');

} else ...{

css.removeClassFromElement(rows[i], 'odd');

}

this.isOdd = !this.isOdd;

}

}

// 实现AJAX调用处理上移

var pars = "pars=";

for(h=0;h<tr.cells.length;h++) ...{

if(!css.elementHasClass(tr.cells[h],'editbtn')&&!css.elementHasClass(tr.cells[h],'delbtn')

&&!css.elementHasClass(tr.cells[h],'updownbtn')) ...{

var colid = tr.cells[h].getAttribute('columnId');

if(tr.cells[h].firstChild.value!=null) ...{

pars += h +"^"+ tr.cells[h].firstChild.value +"|";

}

else ...{

pars += h +"^"+ tr.cells[h].innerText +"|";

}

}

}

var pars2 = "&pars2=";

var uprow = table.rows[tr.rowIndex+1];

for(y=0;y<uprow.cells.length;y++) ...{

if(!css.elementHasClass(uprow.cells[y],'editbtn')&&!css.elementHasClass(uprow.cells[y],'delbtn')

&&!css.elementHasClass(uprow.cells[y],'updownbtn')) ...{

var colid = uprow.cells[y].getAttribute('columnId');

if(uprow.cells[y].firstChild.value!=null) ...{

pars2 += y +"^"+ uprow.cells[y].firstChild.value +"|";

}

else ...{

pars2 += y +"^"+ uprow.cells[y].innerText +"|";

}

}

}

pars3 = "&command=MoveUpDown&callback=afterUpdate&table="+table.id;

new Ajax.Updater('result','Dispatcher.ajax?'+pars+pars2+pars3,...{evalScripts: true});

},

/**//**

* 下移按钮

**/

downRow : function(e) ...{

var that = crudbtn.that;

var linkEl = getEventTarget(e);

var td = linkEl.parentNode;

var tr = td.parentNode;

var thead = tr.parentNode;

var table = thead.parentNode;

var otr = tr;

if(tr.rowIndex == table.rows.length-1) ...{

alert("已经是最后一行了");

return false;

}

else ...{

table.moveRow(tr.rowIndex,tr.rowIndex+1);

this.isOdd = true;

var rows = table.tBodies[0].rows;

// 重新隔行换色

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

if (!this.isOdd) ...{

css.addClassToElement(rows[i], 'odd');

} else ...{

css.removeClassFromElement(rows[i], 'odd');

}

this.isOdd = !this.isOdd;

}

}

// 实现AJAX调用处理下移

// 下移则把pars和pars2的值反过来,后台不变

var pars = "pars2=";

for(h=0;h<tr.cells.length;h++) ...{

if(!css.elementHasClass(tr.cells[h],'editbtn')&&!css.elementHasClass(tr.cells[h],'delbtn')

&&!css.elementHasClass(tr.cells[h],'updownbtn')) ...{

var colid = tr.cells[h].getAttribute('columnId');

if(tr.cells[h].firstChild.value!=null) ...{

pars += h +"^"+ tr.cells[h].firstChild.value +"|";

}

else ...{

pars += h +"^"+ tr.cells[h].innerText +"|";

}

}

}

var pars2 = "&pars=";

var uprow = table.rows[tr.rowIndex-1];

for(y=0;y<uprow.cells.length;y++) ...{

if(!css.elementHasClass(uprow.cells[y],'editbtn')&&!css.elementHasClass(uprow.cells[y],'delbtn')

&&!css.elementHasClass(uprow.cells[y],'updownbtn')) ...{

var colid = uprow.cells[y].getAttribute('columnId');

if(uprow.cells[y].firstChild.value!=null) ...{

pars2 += y +"^"+ uprow.cells[y].firstChild.value +"|";

}

else ...{

pars2 += y +"^"+ uprow.cells[y].innerText +"|";

}

}

}

pars3 = "&command=MoveUpDown&callback=afterUpdate&table="+table.id;

new Ajax.Updater('result','Dispatcher.ajax?'+pars+pars2+pars3,...{evalScripts: true});

}

}

function crudbtnInit() ...{

crudbtn.init();

}

// 回调: 处理结束后的反映

afterUpdate = function(e) ...{

if(e == 'true') ...{

}

else if(e == 'false') ...{

alert("您的操作失败了,请重新尝试");

window.location.reload();

}

else if(e == 'repeated') ...{

alert("您写入了重复的信息!请重新输入");

window.location.reload();

}

}

addEvent(window, 'load', crudbtnInit);

后台处理同 AjaxDelRow.cs

排序样式绑定JS:

/**//*

* Written by Wangzhongyuan

* 通过绑定sort样式进行后台排序的代码

*/

var sorting = ...{

that: false,

isOdd: false,

sortColumnIndex : -1,

lastAssignedId : 0,

newRows: -1,

lastSortedTable: -1,

/**//**

* 初始化排序器

**/

init : function() ...{

// 首先, 查看浏览器是否能执行此脚本(有些浏览器不能用getElementsByTagName)

if (!document.getElementsByTagName) ...{

return;

}

this.that = this;

this.run();

},

/**//**

* 在文档中遍历所有table,如果table拥有sort样式,则启动排序功能

**/

run : function() ...{

var tables = document.getElementsByTagName("table");

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

var thisTable = tables[i];

if (css.elementHasClass(thisTable, 'sort')) ...{

this.makeSortable(thisTable);

}

}

},

/**//**

* 启动给定表的排序功能

**/

makeSortable : function(table) ...{

// 首先,检测该table是否有ID.如果没有就分配一个给它

if (!table.id) ...{

table.id = 'sortableTable'+this.lastAssignedId++;

}

// 判断有没有数据

if(table.rows.length<2)

return ;

// 把表格的第一行视为表头,然后下面要把它们变成可点击

var row = table.tBodies[0].rows[0];

/**//* 结合后台的hack: 主要用于解析初始化时的排序方向.

* 由于考虑到适应自定义数据绑定模板,故越过表头,使用第二行

*/

var row2 = table.tBodies[0].rows[1];

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

// 建立一个链接,并使它拥有能控制排序的onClick事件

var linkEl = createElement('a');

linkEl.href = '#';

linkEl.onclick = this.headingClicked;

linkEl.setAttribute('columnId', i);

linkEl.title = '点击排序';

// 获取标题行的所有列,以便加入链接

var innerEls = row.cells[i].childNodes;

// 遍历标题行的所有列并加入链接

for (var j = 0; j < innerEls.length; j++) ...{

// 如果标题列样式为nosort则不排序

if(!css.elementHasClass(row.cells[i], 'nosort'))

linkEl.appendChild(innerEls[j]);

}

// 把新链接加到表格中

row.cells[i].appendChild(linkEl);

var spanEl = createElement('span');

css.addClassToElement(row.cells[i], 'tableSortArrow');

// 加两个空格

// spanEl.appendChild(document.createTextNode(' '));

row.cells[i].appendChild(spanEl);

// 为每一列判断从后台传过来的排序方向样式

if(css.elementHasClass(row2.cells[i], 'sortOrderASC')) ...{

spanEl.className = 'tableSortArrow';

spanEl.appendChild(document.createTextNode(' ↑'));

spanEl.setAttribute('sortOrder', 'ASC');

}

else if(css.elementHasClass(row2.cells[i], 'sortOrderDESC'))

...{

spanEl.className = 'tableSortArrow';

spanEl.appendChild(document.createTextNode(' ↓'));

spanEl.setAttribute('sortOrder', 'DESC');

}

}

// 初始化隔行换色标志

this.isOdd = false;

var rows = table.tBodies[0].rows;

// 启动隔行换色

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

this.doStripe(rows[i]);

}

},

headingClicked: function(e) ...{

var that = sorting.that;

// 被点击的目标链接

var linkEl = getEventTarget(e);

// 直接获取td, tr, thead 和 table

var td = linkEl.parentNode;

var tr = td.parentNode;

var thead = tr.parentNode;

var table = thead.parentNode;

// 获得目标链接的columnId属性

var column = linkEl.getAttribute('columnId') || td.cellIndex;

// 找出当前列的排序方向

var arrows = css.getElementsByClass(td, 'tableSortArrow', 'span');

var previousSortOrder = '';

if (arrows.length > 0) ...{

previousSortOrder = arrows[0].getAttribute('sortOrder');

}

that.lastSortedTable = table.id;

// 将哪一列被排序回馈给用户

// 首先把所有的排序方向复位

var arrows = css.getElementsByClass(tr, 'tableSortArrow', 'span');

for (var j = 0; j < arrows.length; j++) ...{

var arrowParent = arrows[j].parentNode;

arrowParent.removeChild(arrows[j]);

if (arrowParent != td) ...{

spanEl = createElement('span');

spanEl.className = 'tableSortArrow';

// 加入两个空格

// spanEl.appendChild(document.createTextNode(' '));

arrowParent.appendChild(spanEl);

}

}

// 现在,回馈给用户

var spanEl = createElement('span');

spanEl.className = 'tableSortArrow';

if (null == previousSortOrder || '' == previousSortOrder || 'DESC' == previousSortOrder) ...{

spanEl.appendChild(document.createTextNode(' ↑'));

td.setAttribute('sortOrder', 'ASC');

spanEl.setAttribute('sortOrder', 'ASC');

} else ...{

spanEl.appendChild(document.createTextNode(' ↓'));

td.setAttribute('sortOrder', 'DESC');

spanEl.setAttribute('sortOrder', 'DESC');

}

td.appendChild(spanEl);

// 以下为没有doPostBack的版本,已经取消

/**//*

if(td.firstChild.getAttribute('columnId')!=null) {

window.location = "?sortdirect="+td.getAttribute('sortOrder')+"&colid="+td.firstChild.getAttribute('columnId');

}

else {

window.location = "?sortdirect="+td.getAttribute('sortOrder')+"&colid="+td.getAttribute('columnId');

}

*/

// 使用__doPostBack进入后台处理

__doPostBack('Pars',"sortdirect="+td.getAttribute('sortOrder')+"&colid="+td.firstChild.getAttribute('columnId'));

return false;

},

/**//**

* 隔行换色

**/

doStripe : function(rowItem) ...{

if (!this.isOdd) ...{

css.addClassToElement(rowItem, 'odd');

} else ...{

css.removeClassFromElement(rowItem, 'odd');

}

this.isOdd = !this.isOdd;

}

}

function sortInit() ...{

sorting.init();

}

addEvent(window, 'load', sortInit)

后台:

public DataView SortBuilder(object dataobj,DataView dv)

...{

string req = Request.Form["__EVENTARGUMENT"];

string p_sort = null;

string p_colid = null;

if(req!=null)

...{

string[] args = req.Split('&');

foreach (string arg in args)

...{

string[] hash = arg.Split('=');

if(hash[0].Equals("sortdirect"))

...{

p_sort = hash[1];

}

else if(hash[0].Equals("colid"))

...{

p_colid = hash[1];

}

}

if(p_sort!=null && p_colid!=null && !p_colid.Equals("null"))

...{

SortDirect = p_sort;

int iColid = Int32.Parse(p_colid);

if(dataobj is DataGrid)

...{

foreach (DataGridColumn dc in ((DataGrid)dataobj).Columns)

...{

if(((Style)(Style)dc.ItemStyle).CssClass.IndexOf("sortOrder")!=-1)

...{

((Style)(Style)dc.ItemStyle).CssClass = "";

}

}

((Style)(((DataGrid)dataobj).Columns[iColid].ItemStyle)).CssClass += " sortOrder" + SortDirect;

DataGrid grid = (DataGrid)dataobj;

DataGridColumn dgc = grid.Columns[iColid];

BoundColumn bc = (BoundColumn)dgc;

string df = bc.DataField;

dv.Sort = df + " " + SortDirect;

}

if(dataobj is DataList)

...{

DataList dl = (DataList)dataobj;

((Style)dl.ItemStyle).CssClass += " sortOrder" + SortDirect;

dv.Sort = dl.DataKeyField + " " + SortDirect;

}

// 自定义控件,,,可以自己实现一个

if(dataobj is table)

...{

table tbl = (table)dataobj;

tbl.DataSource = ViewLogic.Data.DataSourceFactory.Create(dv.Table);

IList list = (tbl).ColumnList;

tbl.ColName = list[iColid].ToString();

tbl.SortDriect = SortDirect;

dv.Sort = list[iColid] + " " + SortDirect;

}

}

}

return dv;

}

样式绑定的用法如下

例如,排序样式绑定的用法:

前台: 引用JS,并绑定样式 sort

后台:

DataSet ds = 获取数据源ds

DataView dv = ds.Tables[0].DefaultView;

dv= SortBuilder(控件,dv) ;

控件.DataSource = newdv;

详情请见:http://bbs.goufang.com/js.rar

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有