经过对FlexiGrid的大量使用,及时不时琢磨下其代码,对她的脾性有了一定的了解,是该做总结的时候了。
一、FlexiGrid下载
1、原版代码
最近Paulo P. Marinas对FlexiGrid做了修改,以适应jQuery 1.4.2。看了下作者列出来的特性表,该表很长,但与过去比,却没有增加什么新功能,所以版本号不做修改,仍然是1.0b3。
其中提到的一点值得注意,就是flexAddData方法已改写,性能是否有很大提高,还没测试,要看结果。(最近,抽时间看了一下渲染表格数据的代码,估计效率还是不理想)。还有Editable功能的增加,仍然处于长期计划中,这一点比较令人纠结。
在此说明一下,本文仍然只是对旧版进行总结。
下载:http://code.google.com/p/flexigrid/downloads/list
2、功能优化扩展版
该版本为xuanye(http://www.cnblogs.com/xuanye)的修改版,很好,很强大。
下载1:http://code.google.com/p/xjplugin/downloads/list
下载2:http://xjplugin.googlecode.com/svn/trunk/ControlsSample/Javascripts/Plugins/jquery.flexigrid.js
下载2中的代码新增了getSelectedRows()方法,获取表格行数据将更加简单。
二、配置参数(options)说明
默认参数设置代码:
- // apply default properties
- p = $.extend({
- height: 200,
- //default height
- width: 'auto',
- //auto width
- striped: true,
- //apply odd even stripes
- novstripe: false,
- minwidth: 30,
- //min width of columns
- minheight: 80,
- //min height of columns
- resizable: true,
- //resizable table
- url: false,
- //ajax url
- method: 'POST',
- // data sending method
- dataType: 'xml',
- // type of data loaded
- errormsg: 'Connection Error',
- usepager: false,
- //
- nowrap: true,
- //
- page: 1,
- //current page
- total: 1,
- //total pages
- useRp: true,
- //use the results per page select box
- rp: 15,
- // results per page
- rpOptions: [10, 15, 20, 25, 40],
- title: false,
- pagestat: 'Displaying {from} to {to} of {total} items',
- procmsg: 'Processing, please wait ...',
- query: '',
- qtype: '',
- nomsg: 'No items',
- minColToggle: 1,
- //minimum allowed column to be hidden
- showToggleBtn: true,
- //show or hide column toggle popup
- hideOnSubmit: true,
- autoload: true,
- blockOpacity: 0.5,
- onToggleCol: false,
- onChangeSort: false,
- onSuccess: false,
- onSubmit: false
- // using a custom populate function
- },
- p);
width: 'auto', //宽度值,auto表示根据每列的宽度自动计算
striped: true, //是否显示斑纹效果,默认是奇偶交互的形式
novstripe: false, //没用过,不知怎么用,还需分析源代码
minwidth: 30, //列的最小宽度
minheight: 80, //列的最小高度
resizable: true, //是否可伸缩
url: false, //ajax方式对应的url地址
method: 'POST', // 数据发送方式
dataType: 'xml', // 数据加载的类型
errormsg: 'Connection Error',//错误提示信息
usepager: false, //是否分页
nowrap: true, //是否不换行
page: 1, //默认当前页
total: 1, //总页面数
useRp: true, //是否可以动态设置每页显示的结果数
rp: 15, // 每页默认的结果数
rpOptions: [10,15,20,25,40],//可选择设定的每页结果数
title: false, //标题设置
pagestat: 'Displaying {from} to {to} of {total} items',//显示分页状态
procmsg: ‘Processing, please wait …’,//正在处理的提示信息
query: '',//搜索查询的条件,提交到服务器
qtype: '',//搜索查询的类别,提交到服务器
nomsg: 'No items',//无结果的提示信息
minColToggle: 1, //是否允许隐藏列
showToggleBtn: true, //显示或隐藏数据表格
hideOnSubmit: true,//隐藏提交
autoload: true,//自动加载
blockOpacity: 0.5,//透明度设置
onToggleCol: false,//当在行之间转换时
onChangeSort: false,//当改变排序时
onSuccess: false,//成功后执行
onSubmit: false // 触发自定义populate的提交事件
三、使用步骤说明
1、在<head>标识里加入引用文件代码(注意文件存放路径):
- < link rel = "stylesheet"href = "flexigrid/flexigrid.css"type = "text/css" > </link>
- <script type="text/javascript " src="jquery / jquery.1.3.2.mini.js "></script>
- <script type="text / javascript " src="flexigrid / flexigrid.js "></script>"
添加工具按钮图标样式:
- < style type = "text/css" >
- /* === 增加工具按钮图标样式 ====*/
- .flexigrid div.fbutton.add
- {
- padding - left: 20px;
- background: url(images / row_add.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.edit
- {
- padding - left: 20px;
- background: url(images / row_edit.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.delete
- {
- padding - left: 20px;
- background: url(images / row_delete.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.reset
- {
- padding - left: 20px;
- background: url(images / user_reset.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.excel
- {
- padding - left: 20px;
- background: url(images / excel.gif) no - repeat center left;
- }
- < /style>/
为了方便以后使用,上面这段样式可以加入到flexigrid.css文件中。
2、在<body>标识里加入代码:
- <table id="grid" style="display:none"></table>
如果要增加/编辑数据,还要加入下面这样的HTML代码:
- <div id="dialog_div" style='display:none'>
- <form id="dialog_form" name="dialog_form" action="">
- <table width="100%" class="tableinput">
- <tr>
- <td width="30%">操作工号:</td>
- <td width="70%">
- <input name="username" type="text" id="username" />*八位数字
- <input name="user_id" type="hidden" id="user_id" />
- </td>
- </tr>
- <tr>
- <td>真实姓名:</td>
- <td><input name="name" type="text" id="name" /></td>
- </tr>
- <tr>
- <td>市县机构:</td>
- <td>{{$input.html_sxjg}}</td>
- </tr>
- <tr>
- <td>营业机构:</td>
- <td>{{$input.html_yyjg}}</td>
- </tr>
- <tr>
- <td>分配角色:</td>
- <td>{{$input.html_auth}}</td>
- </tr>
- </table>
- </form>
- </div>
3、在<head>标识里编写JavaScript代码
代码示例:
- < script type = "text/javascript" >
- $(function() {
- // 表单中的文本输入栏绑定 inputtxt 样式类
- $('#dialog_form input:text').addClass('inputtxt');
- $("#grid").flexigrid({
- url: '{{url controller='Ghgl ' action='GetPagerData '}}',
- //url:'index.php?ctl=User&act=GetJsonData',
- dataType: 'json',
- colModel:
- [
- {
- display: '序号',
- name: 'seq',
- width: 40,
- sortable: false,
- align: 'center'
- },
- {
- display: '#ID',
- name: 'user_id',
- width: 40,
- sortable: true,
- align: 'left',
- hide: true
- },
- {
- display: '操作工号',
- name: 'username',
- width: 70,
- sortable: true,
- align: 'left'
- },
- {
- display: '真实姓名',
- name: 'name',
- width: 60,
- sortable: false,
- align: 'left'
- },
- {
- display: '分配角色',
- name: 'role',
- width: 80,
- sortable: false,
- align: 'left'
- },
- {
- display: '市县单位',
- name: 'sxmc',
- width: 120,
- sortable: false,
- align: 'left'
- },
- {
- display: '营业机构',
- name: 'jgmc',
- width: 120,
- sortable: true,
- align: 'left'
- },
- {
- display: '工号创建时间',
- name: 'created',
- width: 110,
- sortable: false,
- align: 'left',
- hide: false
- },
- {
- display: '密码更新时间',
- name: 'pwdupdated',
- width: 110,
- sortable: false,
- align: 'left',
- hide: false
- }
- ],
- searchitems:
- [
- {
- display: '用户工号',
- name: 'username'
- },
- {
- display: '用户姓名',
- name: 'name',
- isdefault: true
- },
- {
- display: '市县单位',
- name: 'sxmc'
- },
- {
- display: '营业机构',
- name: 'jgmc'
- }
- ],
- sortname: "sx_id, jg_id, username",
- sortorder: "DESC",
- title: '<font color="#336699">操作工号维护</font>',
- usepager: true,
- useRp: true,
- rp: 15,
- showTableToggleBtn: false,
- width: 600,
- height: 400,
- striped: true,
- //onSubmit: addFormData,
- pagestat: '当前显示记录 {from} 到 {to} 条,总 {total} 条',
- procmsg: '正在处理,请稍等 ...',
- nomsg: '找不到符合条件的资料!',
- errormsg: '连接后台失败!',
- buttons:
- [
- {
- name: '添加',
- bclass: 'add',
- onpress: opt
- },
- {
- name: '修改',
- bclass: 'edit',
- onpress: opt
- },
- {
- name: '删除',
- bclass: 'delete',
- onpress: opt
- },
- {
- separator: true
- },
- {
- name: '导出EXCEL',
- bclass: 'excel',
- onpress: opt
- }
- ]
- });
- /**
- * 添加/修改对话框
- */
- $('#dialog_div').dialog({
- hide: '',
- //点击取消后隐藏,如果设为true,则无法关闭弹窗。
- autoOpen: false,
- width: 340,
- //height:230,
- modal: true,
- //蒙层
- //title:'单位资料添加/修改',
- overlay: {
- opacity: 0.5,
- background: "black"
- },
- buttons: {
- '关闭': function() {
- $(this).dialog("close");
- },
- '重置': function() {
- $(this).children('form')[0].reset();
- },
- '提交': function() {
- addUpdate();
- }
- }
- });
- /**
- * 点击工具条按钮操作
- */
- function opt(com, grid) {
- switch (com) {
- case '添加':
- $('.ui-dialog-title').html('<font color="#336699">添加操作工号</font>');
- $('#dialog_form input[name=user_id]')[0].value = '';
- $('#dialog_div').dialog('open').children('form')[0].reset();
- break;
- case '修改':
- $('.ui-dialog-title').html('<font color="#336699">修改操作工号</font>');
- selected_count = $('.trSelected', grid).length;
- if (selected_count == 0) {
- JAlert('请选择一条记录。', '消息提示');
- return false;
- }
- if (selected_count > 1) {
- jAlert('抱歉每次只能修改一条记录。', '消息提示');
- return false;
- }
- // 读取表格所选行数据
- var data = new Array();
- $('.trSelected td', grid).each(function(i) {
- data[i] = $(this).children('div').text();
- });
- //alert(data);
- // 初始化编辑数据界面数据
- $('#dialog_form input[name=user_id]')[0].value = data[1];
- $('#dialog_form input[name=username]')[0].value = data[2];
- $('#dialog_form input[name=name]')[0].value = data[3];
- $.ajax({
- url: '{{url controller='Ghgl ' action='GetUpdData '}}',
- data: {
- user_id: data[1]
- },
- type: 'POST',
- dataType: 'json',
- success: function(data) {
- //alert($('#jg_id').options);
- var jg_slt = $('#dialog_form #jg_id option');
- var jg_len = jg_slt.length;
- if (jg_len > 0) {
- setSelected(jg_slt, data.jg_id);
- }
- var auth_radio = $('#dialog_form input:radio');
- //alert(auth_radio.length);
- if (auth_radio.length > 0) {
- setChecked(auth_radio, data.auth);
- }
- }
- });
- $('#dialog_div').dialog('open');
- break;
- case '删除':
- selected_count = $('.trSelected', grid).length;
- if (selected_count == 0) {
- jAlert('请选择一条记录。', '消息提示');
- return false;
- }
- if (selected_count > 1) {
- jAlert('抱歉每次只能删除一条记录。', '消息提示');
- return false;
- }
- var names = '';
- $('.trSelected td:nth-child(4) div', grid).each(function(i) {
- if (i) {
- names += ',';
- }
- names += $(this).text();
- });
- var ids = '';
- $('.trSelected td:nth-child(2) div', grid).each(function(i) {
- if (i) {
- ids += ',';
- }
- ids += $(this).text();
- })
- /*
- if (ids == '') {
- alert('请选择删除记录,允许同时选择多条记录。');
- return;
- }*/
- /*
- if(confirm("确认删除[" + names + "]的用户工号吗?")){
- del(ids);
- }*/
- jConfirm("确认删除[<font color='#FF0000'>" + names + "</font>]的用户工号吗?", '删除确认',
- function(btn) {
- if (btn) {
- del(ids);
- }
- });
- break;
- case '导出EXCEL':
- document.location.href = "{{url controller='Ghgl' action='Export'}}";
- break;
- }
- }
- /**
- * 添加记录
- */
- function addUpdate() {
- $('#dialog_form').ajaxSubmit({
- //$('#dialog_form').ajaxform({
- url: "{{url controller='Ghgl' action='Save'}}",
- type: 'POST',
- dataType: 'json',
- resetForm: true,
- success: function(data) {
- if (data.success) {
- $('#grid').flexReload();
- $('#dialog_div').dialog('close');
- } else {
- jAlert(data.msg, '消息提示');
- return false;
- }
- },
- error: function() {}
- });
- };
- /**
- * 删除记录
- */
- function del(ids) {
- $.ajax({
- url: "{{url controller='Ghgl' action='Del'}}",
- data: {
- ids: ids
- },
- type: 'POST',
- dataType: 'json',
- success: function(data) {
- if (data.success) {
- $('#grid').flexReload();
- } else {
- jAlert(data.msg, '消息提示');
- return false;
- }
- }
- });
- };
- /**
- * 重置密码
- */
- function reset(id) {
- $.ajax({
- url: "{{url controller='Ghgl' action='Reset'}}",
- data: {
- user_id: id
- },
- type: 'POST',
- dataType: 'json',
- success: function(data) {
- if (data.success) {
- jAlert(data.msg, '消息提示');
- return;
- } else {
- jAlert(data.msg, '错误提示');
- return false;
- }
- },
- error: function() {}
- });
- };
- // 根据 value 初始化下拉列表框
- function setSelected(slt, value) {
- for (var i = 0; i < slt.length; i++) {
- if (slt[i].value == value) {
- slt[i].selected = true;
- } else {
- slt[i].selected = false;
- }
- }
- };
- // 根据 value 初始化单选按钮
- function setChecked(slt, value) {
- for (var i = 0; i < slt.length; i++) {
- if (slt[i].value == value) {
- slt[i].checked = true;
- } else {
- slt[i].checked = false;
- }
- }
- };
- });
- < /script>/
其中代码段:
- // 读取表格所选行数据
- var data = new Array();
- $('.trSelected td', grid).each(function(i) {
- data[i] = $(this).children('div').text();
- });
- //alert(data);
为读取表格所选行数据,通过$('.trSelected td', grid)来读取。
- var ids = '';
- $('.trSelected td:nth-child(2) div',grid).each(function(i){
- if(i){
- ids += ',';
- }
- ids += $(this).text();
- })
为读取所选行单元格数据代码,通过:$('.trSelected td:nth-child(2) div',grid)来读取,如果允许多选,读取回来的是一个数组值。注意:td:nth-child(2)的意思为所选行的第二个单元格,因为:nth-child(index)的索引值从1起。
FlexiGrid.options参数介绍:
1、colModel:列定义数组,用来设置数据网格的表头及数据显示格式。
name:字段名称,必须设置,类型:string,默认值: 无。注意:如果dataType参数设置为json(dataType: 'json'),则name值必须与返回的元素名对应。
width:设置列宽度,必须设置,类型:数值(单位为像素px),默认值:无。
sortable:是否可排序,类型:boolen,默认值:false,不排序。
process:处理程序,类型:
function,可格式化单元格。
hide:设置列是否隐藏,类型:boolen,默认值:false
align:设置列数据对齐方式,有三个参数:left、center、right。
代码示例:
- colModel:
- [
- {
- display: '序号',
- name: 'seq',
- width: 40,
- sortable: false,
- align: 'center'
- },
- {
- display: '#ID',
- name: 'user_id',
- width: 40,
- sortable: true,
- align: 'left',
- hide: true
- },
- {
- display: '操作工号',
- name: 'username',
- width: 70,
- sortable: true,
- align: 'left'
- },
- {
- display: '真实姓名',
- name: 'name',
- width: 60,
- sortable: false,
- align: 'left'
- },
- {
- display: '分配角色',
- name: 'role',
- width: 80,
- sortable: false,
- align: 'left'
- },
- {
- display: '市县单位',
- name: 'sxmc',
- width: 120,
- sortable: false,
- align: 'left'
- },
- {
- display: '营业机构',
- name: 'jgmc',
- width: 120,
- sortable: true,
- align: 'left'
- },
- {
- display: '工号创建时间',
- name: 'created',
- width: 110,
- sortable: false,
- align: 'left',
- hide: false
- },
- {
- display: '密码更新时间',
- name: 'pwdupdated',
- width: 110,
- sortable: false,
- align: 'left',
- hide: false
- }
- ],
2、buttons:工具栏Button定义数组,用来设置数据网格的工具条按钮。
bclass :样式, 类型:boolen,默认值:无
onpress :当button被点击时触发的事件接受button的name为第一个参数,Grid为第二个参数的一个function
separator :是否显示分隔符
代码示例:
- buttons:
- [
- {
- name: '添加',
- bclass: 'add',
- onpress: opt
- },
- {
- name: '修改',
- bclass: 'edit',
- onpress: opt
- },
- {
- name: '删除',
- bclass: 'delete',
- onpress: opt
- },
- {
- separator: true
- },
- {
- name: '导出EXCEL',
- bclass: 'excel',
- onpress: opt
- }
- ]
其中:
name:设置按钮文字
separator:设置是否显示分隔线
bclass:设置按钮样式,示例:
- < style >
- .flexigrid div.fbutton.add
- {
- background: url(.. / lib / jquery / flexigrid / css / images / row_add.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.edit
- {
- background: url(.. / lib / jquery / flexigrid / css / images / row_edit.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.delete
- {
- background: url(.. / lib / jquery / flexigrid / css / images / row_delete.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.reset
- {
- background: url(.. / images / user_reset.gif) no - repeat center left;
- }
- .flexigrid div.fbutton.excel
- {
- background: url(.. / images / excel.gif) no - repeat center left;
- }
- < /style>
onpress:点击按钮时触发的事件,接受button的name为第一个参数,grid为第二个参数的一个function。
示例代码:
- /**
- * 点击工具条按钮操作
- */
- function opt(com, grid) {
- switch (com) {
- case '添加':
- ...
- break;
- case '修改':
- ...
- break;
- case '删除':
- ...
- break;
- case '导出EXCEL':
- ...
- break;
- }
- }
3、后台PHP代码(json):
摘自FlexiGrid最新版的示例代码:
- function runSQL($rsql) {
- $connect = mysql_connect($hostname,$username,$password) or die ("Error: could not connect to database");
- $db = mysql_select_db($dbname);
- $result = mysql_query($rsql) or die ('test');
- return $result;
- mysql_close($connect);
- }
- function countRec($fname,$tname) {
- $sql = "SELECT count($fname) FROM $tname ";
- $result = runSQL($sql);
- while ($row = mysql_fetch_array($result)) {
- return $row[0];
- }
- }
- $page = $_POST['page'];
- $rp = $_POST['rp'];
- $sortname = $_POST['sortname'];
- $sortorder = $_POST['sortorder'];
- if (!$sortname) $sortname = 'name';
- if (!$sortorder) $sortorder = 'desc';
- $sort = "ORDER BY $sortname $sortorder";
- if (!$page) $page = 1;
- if (!$rp) $rp = 10;
- $start = (($page-1) * $rp);
- $limit = "LIMIT $start, $rp";
- $sql = "SELECT iso,name,printable_name,iso3,numcode FROM country $sort $limit";
- $result = runSQL($sql);
- $total = countRec('iso','country');
- // 生成json格式数据
- header("Expires: Mon, 26 Jul 1997 05:00:00 GMT" );
- header("Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . "GMT" );
- header("Cache-Control: no-cache, must-revalidate" );
- header("Pragma: no-cache" );
- header("Content-type: text/x-json");
- $json = "";
- $json .= "{\n";
- $json .= "page: $page,\n";
- $json .= "total: $total,\n";
- $json .= "rows: [";
- $rc = false;
- while ($row = mysql_fetch_array($result)) {
- if ($rc) $json .= ",";
- $json .= "\n{";
- $json .= "id:'".$row['iso']."',";
- $json .= "cell:['".$row['iso']."'";
- $json .= ",'".addslashes($row['name'])."'";
- $json .= ",'".addslashes($row['printable_name'])."'";
- $json .= ",'".addslashes($row['iso3'])."'";
- $json .= ",'".addslashes($row['numcode'])."']";
- $json .= "}";
- $rc = true;
- }
- $json .= "]\n";
- $json .= "}";
- echo $json;
本人的后台后代码:
- /**
- * 返回JSON分页数据到前台
- *
- */
- function actionGetPagerData()
- {
- $user = $this->user;
- $page = ($_POST['page']) ? $_POST['page'] : 1;
- $limit = ($_POST['rp'])?$_POST['rp'] : 15;
- $sortname = ($_POST['sortname']) ? $_POST['sortname'] : 'username';
- $sortorder = ($_POST['sortorder']) ? $_POST['sortorder'] : 'DESC';
- $sort = "$sortname $sortorder";
- $offset = ($page - 1) * $limit;
- $query = ($_POST['query']) ? trim($_POST['query']) : '';
- $qtype = ($_POST['qtype']) ? trim($_POST['qtype']) : '';
- if ($qtype == 'name' || $qtype == 'sxmc') {
- $query = mb_convert_encoding($query, 'GB2312', 'utf-8');
- }
- if ($user['RBAC_ROLES'][0] == 'SYSTEM_ADMIN') {
- $conditions = array(
- array('auth', 1, '=', 'OR'),
- array('auth', 2, '='),
- );
- } elseif ($user['RBAC_ROLES'][0] == 'POWER_USER') {
- $conditions = array(
- array('sx_id', $user['SXID'], '=', 'AND'),
- array('auth', 3, '=', 'OR'),
- array('sx_id', $user['SXID'], '=', 'AND'),
- array('auth', 4, '='),
- );
- }
- if ($query && $user['RBAC_ROLES'][0] == 'POWER_USER') {
- $conditions = array(
- array('sx_id', $user['SXID'], '=', 'AND'),
- array($qtype, $query, '=')
- );
- }
- if ($qtype == 'name' && $query != '' && $user['RBAC_ROLES'][0] == 'POWER_USER') {
- $conditions = array(
- array('sx_id', $user['SXID'], '=', 'AND'),
- array($qtype, '%' . $query . '%', 'LIKE')
- );
- }
- if ($qtype == 'sxmc' && $query != '' && $user['RBAC_ROLES'][0] == 'SYSTEM_ADMIN') {
- $cxtj = array(
- array('sxmc', '%' . $query . '%', 'LIKE')
- );
- $sxjg = & FLEA::getSingleton('Table_Sxjg');
- $row = $sxjg->find($cxtj);
- $conditions = array(
- array('sx_id', $row['SXID'], '=', 'AND'),
- array('auth', 1, '=', 'OR'),
- array('sx_id', $row['SXID'], '=', 'AND'),
- array('auth', 2, '='),
- );
- }
- if ($qtype == 'jgmc' && $query != '' && $user['RBAC_ROLES'][0] == 'POWER_USER') {
- $cxtj = array(
- array('sx_id', $this->user['SXID'], '=', 'AND'),
- array('jgmc', '%' . $query . '%', 'LIKE')
- );
- $tblYyjg = & FLEA::getSingleton('Table_Yyjg');
- $row = $tblYyjg->find($cxtj);
- $conditions = array(
- array('sx_id', $this->user['SXID'], '=', 'AND'),
- array('jg_id', $row['jg_id'], '=')
- );
- }
- //$conditions = null;
- $this->_tblUsers->enableLinks();
- $rows = $this->_tblUsers->findAll($conditions, $sort, array($limit, $offset));
- $rs = $this->_tblUsers->findAll($conditions);
- $total = count($rs);
- $json = "";
- $json .= "{\n";
- $json .= "page: $page,\n";
- $json .= "total: $total,\n";
- $json .= "rows: [";
- $rc = false;
- $i = 1;
- foreach ($rows as $row) {
- if ($rc) $json .= ",";
- $json .= "\n{";
- $json .= "user_id:'".$row['user_id']."',";
- $json .= "cell:['".$i."'";
- $json .= ",'".$row['user_id']."'";
- $json .= ",'".$row['username']."'";
- $json .= ",'".$row['name']."'";
- $json .= ",'".$row['roles'][0]['rolename_cn']."'";
- $json .= ",'".$row['sxjg']['sxmc']."'";
- $json .= ",'".addslashes($row['yyjg']['jgmc'])."'";
- $json .= ",'".$row['created']."'";
- //$json .= ",'".$row['updated']."']";
- $json .= ",'".$row['pwdupdated']."']";
- $json .= "}";
- $rc = true;
- $i++;
- }
- $json .= "]\n";
- $json .= "}";
- echo $json;
- exit;
- }
四、功能优化扩展版说明
功能优化扩展版的改变:
1、修改了仿ext的皮肤,界面更加漂亮;
2、优化了渲染表格代码,速度提高了60%;
3、增加了显示checkbox列功能;
4、为方便处理行数据,增加了行数据绑定功能。
options新增参数:
- qop: "Eq", //搜索的操作符
- showcheckbox: false, //是否在列首添加checkbox
- rowhandler: false, //在生成行时绑定事件,如双击,右键等
- rowbinddata: false, // 是否在行上绑定数据
- extParam: {}, // 扩展外部参数动态注册到grid,实现如自定义查询等操作
- onrowchecked: false, // checkbox选中状态发生变化时触发的事件
- gridClass: "bbit-grid" //绑定样式
buttons新增参数:
btnText: 设置工具按钮附加文本,原来的为displayname,我这里改成了btnText。
示例:
- buttons:
- [
- {name: 'Add', btnText: "新增", bclass: 'add', onpress: function(Add, grid){alert('这是新增操作。');return false;}},
- {name: 'Edit', btnText: "修改", bclass: 'edit', onpress: ''},
- {name: 'Delete', btnText: "删除", bclass: 'delete', onpress: ''},
- {separator: true},
- {name: 'Export', btnText: "导出Excel", bclass: 'excel', onpress: ''}
- ]
新增方法1:
- var ids = $("#grid").getCheckedRows(); 可以获取到选中行的主键值,里面保存的是记录的ID数组。
*注意:
该方法需要十分注意JSON分页格式数据,举例说明:
- ...
- $json .= "\n{";
- $json .= "user_id:'".$row['user_id']."',";
- $json .= "cell:['".$i."'";
- $json .= ",'".$row['user_id']."'";
- ...
其中的:
- $json .= "user_id:'".$row['user_id']."',";
里面的主键名必须统一使用id,即为:
- $json .= "id:'".$row['user_id']."',";
getCheckedRows()才能正确获取数据。
新增方法2:
- var rows = $("#grid).getSelectedRows(); // 获取表格行数据
*注意,该方法需要将 rowbinddata 参数设为 true,而且返回的数据为二维数组。
同时,为了保证该方法在IE、FF下都能使用正常,需要修改FlexiGrid.js代码。
打开FlexiGrid.js文件,找到代码行:
- items.push($(this).attr("ch").split('_FG$SP_'));
将其修改为:
- items.push($(this).attr("CH").split('_FG$SP_'));
功能实现示例:
1、查询的布局可自行设置,完了调用方法刷新grid即可,类似如下所示:
- var p = { extParam: [
- { name: "stuName", value: $("#selectinput").val() },
- { name: "stuId", value: $("#selectStuId").val() },
- { name: "stuNo", value: $("#selectNo").val() },
- { name: "stuGrade", value: $("#selectGrade").val() },
- { name: "SID", value: $("#sugvalue").val() },
- { name: "Sname", value: $("#sugname").val() },
- { name: "Sgust", value: $("#suggust").val() }
- ]
- };
- $("#grid").flexOptions(p).flexReload();
2、grid中有一些记录是已经选中的,我怎样让它们从数据库中查出来时前面的checkbox设置成选中?
首先把是否选中的值作为列表中的列和其他数据一起查询回来一次,
然后再在Flexigrid中的 rowhandler参数定义一个函数,如下所示:
- rowhandler: InitGridCheck,
函数实现:
- function InitGridCheck(tr) {
- var ch = $.browser.msie ? tr.ch : target.getAttribute("ch");
- var cell = ch.split("_FG$SP_");
- if(cell[7] != 1){return;}
- var chkb = $(tr).find(":checkbox");
- if (chkb.length>0) {
- chkb[0].checked = true;
- chkb[0].defaultChecked = true;
- $(tr).addClass('trSelected');
- }
- }
除错:
由于xuanye的修改版代码在取消显示checkbox列(showcheckbox: false)时,存在无法单击表格行时无法选定记录行的bug,因为如果不能选定记录行,则无法进行编辑、删除等操作。
打开jquery.flexigrid.js文件,找到735行,加入单击表格行事件代码:
- $('tbody tr', g.bDiv).each(
- function() {
- // 增加单击行时的处理代码(modified by hegz 2009/03/29)
- $(this)
- .click(
- function(e)
- {
- var obj = (e.target || e.srcElement);
- if (obj.href || obj.type) return true;
- if ($(this).hasClass('trSelected')) {
- $(this).removeClass('trSelected');
- if (p.showcheckbox)
- $("input.itemchk", this)[0].checked = false;
- } else {
- $(this).addClass('trSelected');
- if (p.showcheckbox)
- $("input.itemchk", this)[0].checked = true;
- }
- if (p.onrowchecked) p.onrowchecked.call(this);
- if (p.singleSelect) $(this).siblings().removeClass('trSelected');
- }
- );
- // modified end
- ...
其实,原版代码是有这样的代码的,但xuanye修改后取消了。
原版FlexiGrid代码:
- addRowProp: function() {
- $('tbody tr', g.bDiv).each(function() {
- $(this).click(function(e) {
- var obj = (e.target || e.srcElement);
- if (obj.href || obj.type) return true;
- $(this).toggleClass('trSelected');
- if (p.singleSelect) $(this).siblings().removeClass('trSelected')
- }).mousedown(function(e) {
- if (e.shiftKey) {
- $(this).toggleClass('trSelected');
- g.multisel = true;
- this.focus();
- $(g.gDiv).noSelect()
- }
- }).mouseup(function() {
- if (g.multisel) {
- g.multisel = false;
- $(g.gDiv).noSelect(false)
- }
- }).hover(function(e) {
- if (g.multisel) {
- $(this).toggleClass('trSelected')
- }
- },
- function() {});
- if ($.browser.msie && $.browser.version < 7.0) {
- $(this).hover(function() {
- $(this).addClass('trOver')
- },
- function() {
- $(this).removeClass('trOver')
- })
- }
- })
- },
(今天,通过与xuanye兄交流,这个不是bug,只是通过右键菜单来支持,现在的最新代码已支持该功能,我有可能白忙活了,哈哈。)
五、jQuery 1.4.2支持测试
jQuery 1.4.2推出后,由于效率比jQuery 1.3.2高很多,因此我们的项目开发需要逐渐过渡到jQuery 1.4.2,以改善项目的整体运行效率。怀着这样的目的,这两天来我抽时间对FlexiGrid在jQuery 1.4.2下的运行做了简单的测试。发现旧版本在jQuery 1.4.2也能正常运行,但由于jQuery 1.4.2对JSON数据格式有严格的限制,名值对必须加双引号括起来,否则将发生JSON数据解析错误。如下图所示:
当然了,如果想弹出上面的警告框,需要稍微修改下Flexigrid的js代码。
打开Flexigrid的源代码,找到populate()方法,将其中的Ajax error回调函数修改为:
- error:function (data, textStatus, errorThrown) {
- alert(textStatus);
- }
即可。不过,测试完后要记得将源代码恢复原状就行。
六、结束语
Paulo P. Marinas 的目标是致力打造功能完善、简单易用的轻量级grid。他确保将来增加新的功能后,代码经过压缩,大小不超过20K,这确实令人赞赏。但其一直以来计划增加的Editable功能始终无法实现,就令我等有点失望了,或者xuanye等大虾在不久的将来会去扩充实现这一功能也未可知。
七、参考资料
1、官方网站(http://www.flexigrid.info/)。
2、基于jQuery的GridView-Flexigrid(2)-扩展和修复(http://www.cnblogs.com/xuanye/archive/2009/11/08/Xuanye_jQuery_FlexiGrid_Demo.html)
3、基于jQuery的GridView-FlexiGrid的使用和改造(1)--如何使用,完全参数说明(http://www.cnblogs.com/xuanye/archive/2009/11/04/Xuanye_jQuery_FlexiGrid.html)
评论
步骤如下:
1、用2003版以上的EXCEL创建好模板文件,文件保存为“XML表格”。
模板格式如下所示:
- <?xml version="1.0" encoding="gb2312"?>
- <?mso-application progid="Excel.Sheet"?>
- <Workbook xmlns="urn:schemas-microsoft-com:office:spreadsheet"
- xmlns:o="urn:schemas-microsoft-com:office:office"
- xmlns:x="urn:schemas-microsoft-com:office:excel"
- xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet"
- xmlns:html="http://www.w3.org/TR/REC-html40">
- <DocumentProperties xmlns="urn:schemas-microsoft-com:office:office">
- <Author>USER</Author>
- <LastAuthor>tech1</LastAuthor>
- <LastPrinted>2009-08-13T09:35:20Z</LastPrinted>
- <Created>2009-04-21T07:03:50Z</Created>
- <LastSaved>2009-08-13T09:36:41Z</LastSaved>
- <Company>CHINA</Company>
- <Version>11.9999</Version>
- </DocumentProperties>
- <ExcelWorkbook xmlns="urn:schemas-microsoft-com:office:excel">
- <WindowHeight>8100</WindowHeight>
- <WindowWidth>13524</WindowWidth>
- <WindowTopX>288</WindowTopX>
- <WindowTopY>108</WindowTopY>
- <ProtectStructure>False</ProtectStructure>
- <ProtectWindows>False</ProtectWindows>
- </ExcelWorkbook>
- <Styles>
- <Style ss:ID="Default" ss:Name="Normal">
- <Alignment ss:Vertical="Center"/>
- <Borders/>
- <Font ss:FontName="宋体" x:CharSet="134" ss:Size="12"/>
- <Interior/>
- <NumberFormat/>
- <Protection/>
- </Style>
- <Style ss:ID="s21">
- <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
- <Borders>
- <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
- </Borders>
- <Font ss:FontName="楷体_GB2312" x:CharSet="134" x:Family="Modern" ss:Size="12"/>
- <Interior ss:Color="#CCFFFF" ss:Pattern="Solid"/>
- </Style>
- <Style ss:ID="s22">
- <Alignment ss:Vertical="Center"/>
- <Borders>
- <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
- </Borders>
- </Style>
- <Style ss:ID="s23">
- <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
- <Borders>
- <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
- </Borders>
- </Style>
- <Style ss:ID="s24">
- <Alignment ss:Horizontal="Left" ss:Vertical="Center"/>
- <Borders>
- <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
- </Borders>
- </Style>
- <Style ss:ID="s27">
- <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
- <Borders>
- <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
- </Borders>
- <Font ss:FontName="楷体_GB2312" x:CharSet="134" x:Family="Modern" ss:Size="12"/>
- <Interior ss:Color="#CCFFFF" ss:Pattern="Solid"/>
- <NumberFormat ss:Format="@"/>
- </Style>
- <Style ss:ID="s28">
- <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
- <Borders>
- <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Left" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Right" ss:LineStyle="Continuous" ss:Weight="1"/>
- <Border ss:Position="Top" ss:LineStyle="Continuous" ss:Weight="1"/>
- </Borders>
- <NumberFormat ss:Format="@"/>
- </Style>
- <Style ss:ID="s29">
- <NumberFormat ss:Format="@"/>
- </Style>
- <Style ss:ID="s32">
- <Alignment ss:Horizontal="Left" ss:Vertical="Center"/>
- <Borders>
- <Border ss:Position="Bottom" ss:LineStyle="Continuous" ss:Weight="1"/>
- </Borders>
- <Font ss:FontName="楷体_GB2312" x:CharSet="134" x:Family="Modern" ss:Size="14"/>
- </Style>
- <Style ss:ID="s34">
- <Alignment ss:Horizontal="Center" ss:Vertical="Center"/>
- <Font ss:FontName="楷体_GB2312" x:CharSet="134" x:Family="Modern" ss:Size="18"
- ss:Bold="1"/>
- </Style>
- </Styles>
- <Worksheet ss:Name="Sheet1">
- <Table ss:ExpandedColumnCount="7" ss:ExpandedRowCount="200" x:FullColumns="1"
- x:FullRows="1" ss:DefaultColumnWidth="52.8" ss:DefaultRowHeight="15.45">
- <Column ss:Width="32.4"/>
- <Column ss:StyleID="s29" ss:Width="75.600000000000009"/>
- <Column ss:AutoFitWidth="0" ss:Width="56.4"/>
- <Column ss:Width="95.399999999999991"/>
- <Column ss:AutoFitWidth="0" ss:Width="68.399999999999991"/>
- <Column ss:AutoFitWidth="0" ss:Width="69.6"/>
- <Column ss:Width="82.199999999999989"/>
- <Row ss:AutoFitHeight="0" ss:Height="26.55">
- <Cell ss:MergeAcross="6" ss:StyleID="s34"><Data ss:Type="String">代收交通违法罚款系统操作工号分配表</Data></Cell>
- </Row>
- <Row ss:AutoFitHeight="0" ss:Height="26.55">
- <Cell ss:MergeAcross="6" ss:StyleID="s32"><Data ss:Type="String">导出日期:{{$exportdate}}</Data></Cell>
- </Row>
- <Row ss:AutoFitHeight="0">
- <Cell ss:StyleID="s21"><Data ss:Type="String">序号</Data></Cell>
- <Cell ss:StyleID="s27"><Data ss:Type="String">用户工号</Data></Cell>
- <Cell ss:StyleID="s21"><Data ss:Type="String">用户姓名</Data></Cell>
- <Cell ss:StyleID="s21"><Data ss:Type="String">所属机构</Data></Cell>
- <Cell ss:StyleID="s21"><Data ss:Type="String">分配角色</Data></Cell>
- <Cell ss:StyleID="s21"><Data ss:Type="String">创建日期</Data></Cell>
- <Cell ss:StyleID="s21"><Data ss:Type="String">密码修改日期</Data></Cell>
- </Row>
- {{section name=i loop=$lists}}
- <Row ss:AutoFitHeight="0">
- <Cell ss:StyleID="s22"><Data ss:Type="Number">{{$lists[i].seq}}</Data></Cell>
- <Cell ss:StyleID="s28"><Data ss:Type="Number">{{$lists[i].username}}</Data></Cell>
- <Cell ss:StyleID="s24"><Data ss:Type="String">{{$lists[i].name}}</Data></Cell>
- <Cell ss:StyleID="s24"><Data ss:Type="String">{{$lists[i].jggl.name}}</Data></Cell>
- <Cell ss:StyleID="s24"><Data ss:Type="String">{{$lists[i].roles.0.rolename_cn}}</Data></Cell>
- <Cell ss:StyleID="s23"><Data ss:Type="String">{{$lists[i].cdate}}</Data></Cell>
- <Cell ss:StyleID="s23"><Data ss:Type="String">{{$lists[i].pdate}}</Data></Cell>
- </Row>
- {{/section}}
- </Table>
- <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
- <PageSetup>
- <Header x:Margin="0.51181102362204722"/>
- <Footer x:Margin="0.51181102362204722"/>
- <PageMargins x:Bottom="0.98425196850393704" x:Left="0.74803149606299213"
- x:Right="0" x:Top="0.98425196850393704"/>
- </PageSetup>
- <Unsynced/>
- <Print>
- <ValidPrinterInfo/>
- <PaperSizeIndex>9</PaperSizeIndex>
- <VerticalResolution>0</VerticalResolution>
- </Print>
- <Selected/>
- <Panes>
- <Pane>
- <Number>3</Number>
- <ActiveRow>7</ActiveRow>
- <ActiveCol>3</ActiveCol>
- </Pane>
- </Panes>
- <ProtectObjects>False</ProtectObjects>
- <ProtectScenarios>False</ProtectScenarios>
- </WorksheetOptions>
- </Worksheet>
- <Worksheet ss:Name="Sheet2">
- <Table ss:ExpandedColumnCount="0" ss:ExpandedRowCount="0" x:FullColumns="1"
- x:FullRows="1" ss:DefaultColumnWidth="52.8" ss:DefaultRowHeight="15.45"/>
- <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
- <Unsynced/>
- <ProtectObjects>False</ProtectObjects>
- <ProtectScenarios>False</ProtectScenarios>
- </WorksheetOptions>
- </Worksheet>
- <Worksheet ss:Name="Sheet3">
- <Table ss:ExpandedColumnCount="0" ss:ExpandedRowCount="0" x:FullColumns="1"
- x:FullRows="1" ss:DefaultColumnWidth="52.8" ss:DefaultRowHeight="15.45"/>
- <WorksheetOptions xmlns="urn:schemas-microsoft-com:office:excel">
- <Unsynced/>
- <ProtectObjects>False</ProtectObjects>
- <ProtectScenarios>False</ProtectScenarios>
- </WorksheetOptions>
- </Worksheet>
- </Workbook>
*注意其中的代码段,是通过后台PHP代码及Smarty引擎动态批量替换。
- {{section name=i loop=$lists}}
- <Row ss:AutoFitHeight="0">
- <Cell ss:StyleID="s22"><Data ss:Type="Number">{{$lists[i].seq}}</Data></Cell>
- <Cell ss:StyleID="s28"><Data ss:Type="Number">{{$lists[i].username}}</Data></Cell>
- <Cell ss:StyleID="s24"><Data ss:Type="String">{{$lists[i].name}}</Data></Cell>
- <Cell ss:StyleID="s24"><Data ss:Type="String">{{$lists[i].jggl.name}}</Data></Cell>
- <Cell ss:StyleID="s24"><Data ss:Type="String">{{$lists[i].roles.0.rolename_cn}}</Data></Cell>
- <Cell ss:StyleID="s23"><Data ss:Type="String">{{$lists[i].cdate}}</Data></Cell>
- <Cell ss:StyleID="s23"><Data ss:Type="String">{{$lists[i].pdate}}</Data></Cell>
- </Row>
- {{/section}}
2、编写后台生成报表的代码,由Smarty动态生成报表。如下所示:
- /**
- * 导出EXCEL
- *
- */
- function actionExport()
- {
- $user = $this->user;
- $sort = '`jg_id`, `username` ASC';
- $this->_tblUsers->enableLinks();
- $rows = $this->_tblUsers->findAll(null, $sort);
- //dump($rows);
- $i = 0;
- foreach ($rows as $row) {
- $rows[$i]['seq'] = $i + 1;
- $rows[$i]['cdate'] = date('Y.m.d', strtotime($row['created']));
- $rows[$i]['pdate'] = $row['pwdupdated'] == '0000-00-00 00:00:00' ? '' : date('Y.m.d', strtotime($row['pwdupdated']));
- $i++;
- }
- $this->tpl->assign('exportdate', date('Y年m月d日'));
- $this->tpl->assign('lists', $rows);
- $this->excelHeaderSend('用户操作工号分配表.xml');
- $this->display('ghgl.xml', false);
- }
*说明:上面的代码在FleaPHP下使用,如果不是在FleaPHP下使用,使用其它方式读取MySQL数据即可。