Flexigrid是一款轻量级的jQuery表格插件,体积很小,压缩后的js和css源码只有不到40k,并且简单易用。然而简单通常意味着一些高级功能的缺失,好在其源码还是比较简单的,比较容易看懂。项目主页是:http://www.flexigrid.info/。
基本功能就不多说了,笔者前段时间实现了几个小小的功能扩展,今天整理出来分享给需要的读者:实现了表格单元内容的HTML模板以及鼠标单击事件。使用方法是在定义grid的colModel时对该列进行额外的配置,下列代码的注释中已经说明:
$('#userGrid').flexigrid({
resizable: false,
url : url,
dataType : 'json',
method:'get',
singleSelect: true,
colModel : [ {
display : '用户名',
name : 'userName',
width : 100,
sortable : false,
align : 'center'
}, {
display : '测试',
name : 'test',
width : 120,
/* 2013-06-08 NearEast flexigrid 新功能示例
定义html显示模板,{$}是一个变量,表示后台传过来的该列的数据值 */
html:'<span style="color:red">新功能示例:</span><button class="btn-success" οnclick="alert(this);">{$}</button>',
/* 2013-06-08 NearEast flexigrid 新功能示例
指定鼠标单击此列元素时的事件处理函数*/
handler:NearEast.printArgs
}],
buttons : [ {
name : '新增',
bclass : 'add',
onpress : func
}],
searchitems : [ {
display : '用户名',
name : 'userName'
}],
sortname : "userName",
sortorder : "asc",
usepager : true,
title : '用户列表',
useRp : true,
rp : 15,
width : 600,
height : 200
});
实现的效果类似下图红圈所示:
查看代码,找到表格类g的addData函数,对于数据类型为json的情况,在数据填充部分(定义td.innerHTML内容的部分,约在第356行)对源码进行修改。
首先,我们定义一个变量
var ph = p.colModel[idx].html || '{$}';
这个变量代表了数据显示使用的模板。其中p是整个表格的配置属性对象,也就是我们在调用flexigrid 方法的时候,传递进去的那些配置项。idx代表当前遍历的列的索引,于是p.colModel[idx]就是当前遍历的列的配置。这里定义的ph变量首先检查列配置中时候包含html模板配置,如果没有定义则其默认值为变量{$}。
接下来,我们要根据后台传递过来的数据类型取得相应元素的数据值。
此处的作用域中,有一个row变量代表了当前遍历的数据行,row.cell是一个数组,对应后台传过来的json数据中的cell项。cell项可以是一个“名-值”对的json对象,如:
cell: {newid:0,author:’NearEast’, url:’http://blog.csdn.net/neareast’,address:’北京’};
也可以是一个简单的数组,如:
cell:[0,’NearEast’,’http://blog.csdn.net/neareast/article/details/12904393’,’海淀’]。
针对cell项的两种格式,我们分别进行判断:如果cell是数组,则直接取数组的第idx项,即row.cell[idx];如果cell是json对象,则使用colModel中指定的name(p.colModel[idx].name)作为key,来取json对应的值。
最后,我们用上一步取到的数据值对模板进行填充,然后赋值给表格单元td的innerHTML即可。模板的填充使用了javascript字符串的原生方法replace,将ph变量中的所有“{$}”变量替换为应有的数据值。最终的相关代码如下所示://如果cell是数组
if (typeof row.cell[idx] != "undefined") {
td.innerHTML = ph.replace(/{\$}/g, (row.cell[idx] != null) ? row.cell[idx] : '' );//null-check for Opera-browser
//如果cell是json对象
} else {
td.innerHTML = ph.replace(/{\$}/g, row.cell[p.colModel[idx].name]);
}
关于正则表达式,可参见笔者的另一篇博文:http://blog.csdn.net/neareast/article/details/6936460。
至此,自定义模板的功能已经完成了,而其实我们已经找到了动态控制表格单元内容的方法,我们不光可以随心所欲地改变单元的样式,还可以方便地添加其它自定义功能了,例如添加行元素的鼠标双击事件,或者针对某列所有单元的单击事件处理函数,详见下文。