`

基于jQuery的FlexiGrid的插件使用和改造

阅读更多
已不推荐下载,如要下载去这个连接下载最新的
http://gundumw100.iteye.com/admin/blogs/545610


http://www.cnblogs.com/xuanye/archive/2009/11/04/Xuanye_jQuery_FlexiGrid.html

http://www.cnblogs.com/xuanye/archive/2009/11/08/Xuanye_jQuery_FlexiGrid_Demo.html

上面的2个链接是我参考的例子

虽然Flexigrid已然算是优秀,但是问题还是有?比如:

1:不支持在列首添加checkbox列

2:如何给行附加事件(如右键快显菜单或双击)或者在最后列添加操作列(在列的定义中,有个process的函数可使用,返回html,可参考示例中的formatMoney)?同时获取该列的数据?

3: 如何能够兼容 jQuery 1.3+?(默认不兼容)

4:如何改善性能问题(IE的脚本执行能力实在是可怜,特别在IE6下,当行列多时,总是有2-3秒的停滞)

5:如何让某列不参与显示隐藏控制?

6:如何格式化某列?比如工资列前加“¥”

改进后的FlexiGrid:
第一项:重新定义的皮肤

这些只需修改对饮的CSS即可实现,只是非常长,就不贴出来了,有兴趣有耐心的朋友可以去研究下代码。

第二项:在首列添加一个checkbox列

1:首先在参数中添加一个showcheckbox的参数
2:然后再输出头时判断该属性,如果为真则输出一个列包含checkbox(用于全选)
1 if (p.showcheckbox) {
2       var cth = $('<th/>');
3       var cthch = $('<input type="checkbox"/>');
4       cthch.addClass("noborder")
5       //给该列添加一些自定义的属性,在生成数据行时需要用到这些属性
6       cth.addClass("cth").attr({ 'axis': "col-1", width: "22", "isch": true }).append(cthch);
7       $(tr).append(cth);
8   }





3:然后在生成数据行时通过,因为数据行的生成的依据完全是根据thead中th的属性来创建的,这样我们可以通过上面设置的isch属性在制定的列上创建checkbox列
1 $.each(data.rows,function(i,row) //循环数据行
2 {
3 var tr = document.createElement('tr');
4 if (i % 2 && p.striped) tr.className = 'erow';
5 if (row.id) tr.id = 'row' + row.id;
6   $('thead tr:first th',g.hDiv).each( //获取列头,循环列头来生成数据单元格,这里有个性能问题,即每次循环数据行都要检索列头,事实上没有必要
7     function (){...});
8 ...
9 });

4:设置checkbox头列不参与拖拽列

5:给checkbox头列添加全选的事件实现
1 if (chkall.length > 0) {
2                        chkall[0].onclick = g.checkAllOrNot;
3                        return;
4                    }
01 checkAllOrNot: function(parent) {
02        var ischeck = $(this).attr("checked");
03        $('tbody tr', g.bDiv).each(function() {
04            if (ischeck) {
05                $(this).addClass("trSelected");
06            }
07            else {
08                $(this).removeClass("trSelected");
09            }
10        });
11        $("input.itemchk", g.bDiv).each(function() {
12            this.checked = ischeck;
13            //Raise Event
14            if (p.onrowchecked) {
15                p.onrowchecked.call(this);
16            }
17        });
18    },

6:最后一项是新增一个onrowchecked的事件,即在每一行的的checkbox选中状态发生变化时触发某个事件,onrowchecked在参数中注册。

7:新增getCheckedRows方法获取Grid中的选中行,返回是行主键的数组

第三项:修改每次都要获取记录数的bug,如果返回的记录数小于0,即没有总获取记录数,则使用上一次的获取到的记录数。

即总是在当前index为第一页是才从返回值从获取页面否则,沿用上次。和服务器端配合,可减少count的次数提高性能

第四项:Toolbar中的button增加displayname


源码toolbar中button只有name没有displayname,添加一个区分一下,不然感觉就像在C#中写了个中文的类名

第五项:快速检索增加正则表达式验证,增加操作符参数


Flexigrid有个快速检索的功能,虽然不太常用,但是偶尔的场景游泳,添加了两个参数。一个是操作标识(即=,LIKE等)
另一个正则表达式验证,即对输入查询的值进行简单的校验

第六项:可从外部集成行事件

增加参数rowhanlder,在生成行时绑定事件,如双击,右键等


第七项:在行上绑定数据

增加参数rowbinddata,配合第六个操作,如在双击事件中获取该行的数据

第八项:兼容jQuery 1.3+


当我兴致匆匆的升级了jQuery框架后,发现脚本开始报错了,于是只能阅读代码,一个一个修正。

第九项:修正了Json数据的row为null时脚本报错的问题

这个不知道算不算bug,反正是当我服务器端没有数据返回null,原来的脚本报错了,于是加了个判断

第十项:新增列不参与toggle,只需配置列的toggle=false

希望某列不参与显示隐藏控制,即在生成下拉控制器时判断该属性为真则跳过

第十一项:修改AddData的组装逻辑,优化事件附件,提升性能


原来的逻辑是通过Dom操作,将tr td生成,并添加到行列中,最后在通过检索循环触发单元格的proccess事件和行默认事件(如单击选中事件),而且在上诉两个行为中存在致使浏览器重绘Dom的操作。还存在一些不必要的循环,这样的逻辑在表格行列较多,客户机性能较差,又是IE6的话影响非常之明显。即时在我的电脑上,在IE6下仍然是表现不佳。

所以调整为添加行列统一将生成的html push到数组一次性付给tbody,同时在生成单元格html时处理process事件(不要再次查找和循环,避免多次重绘dom)

第十二项:添加extParam参数可将外部参数动态注册到grid,实现如查询等操作


下面是我根据上面测试的一个例子,本例需要结合我的另一篇文章看http://gundumw100.iteye.com/admin/blogs/531131

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>FlexiGrid</title>

<link href="css/flexigrid.css" type="text/css" rel="stylesheet" />
<link href="css/contextmenu.css" type="text/css" rel="stylesheet"  />
<script src="lib/jquery/jquery-1.3.2.min.js" type="text/javascript"></script>
<script src="jquery.contextmenu.js" type="text/javascript"></script>
<script src="jquery.flexigrid.js" type="text/javascript" ></script>
<script type="text/javascript">
$(document).ready(function(){
	var maiheight = document.documentElement.clientHeight;
	var w = $("#ptable").width() - 3;
	var gapTop =  30;
	var otherpm = 150; //GridHead,toolbar,footer,gridmargin
	var h = maiheight - gapTop - otherpm;

var grid=$("#flex1").flexigrid({
		width: w,
		height: h,
		url: 'flexGridServlet.do',
		dataType: 'json',
		colModel : [
			//{display: '<input type="checkbox" id="checkAll"/>', name : 'check', width : 50, sortable : false, align: 'center',hide: false},
			{display: '编号', name : 'id', width : 50, sortable : true, align: 'center',toggle : false},
			{display: '工作名称', name : 'job_name', width : 250, sortable : false, align: 'center'},
			{display: '工作地址', name : 'work_address', width : 100, sortable : true, align: 'center'},
			{display: '工资', name : 'salary', width : 60, sortable : true, align: 'right',process:formatMoney},
			{display: '日期', name : 'date', width : 120, sortable : true, align: 'center'},
			{display: '语言', name : 'language', width : 80, sortable : true, align: 'center'}																
			],
		buttons : [
			{ name: 'add', displayname: '新增', bclass: 'add', onpress: toolbarItem },
            { name: 'modify', displayname: '修改', bclass: 'modify', onpress: toolbarItem },
            { name: 'delete', displayname: '删除', bclass: 'delete', onpress: toolbarItem },
			{separator: true}
			],
		searchitems : [
			{display: '编号', name : 'id', isdefault: true},
			{display: '工作名称', name : 'job_name'},
			{display: '工作地址', name : 'work_address'},
			{display: '语言', name : 'language'}
			],
		errormsg: '发生异常',
		sortname: "id",
		sortorder: "desc",
		usepager: true,
		title: '信息发布管理',
		pagestat: '显示记录从{from}到{to},总数 {total} 条',
		useRp: true,
		rp: 10,
		rpOptions: [10, 15, 20, 30, 40, 100], //可选择设定的每页结果数
		nomsg: '没有符合条件的记录存在',
		minColToggle: 1, //允许显示的最小列数
		showTableToggleBtn: true,
		autoload: true, //自动加载,即第一次发起ajax请求
		resizable: false, //table是否可伸缩
		procmsg: '加载中, 请稍等 ...',
		hideOnSubmit: true, //是否在回调时显示遮盖
		blockOpacity: 0.5,//透明度设置
		showcheckbox: true,//是否显示第一列的checkbox(用于全选)
		gridClass: "bbit-grid",//样式
        rowhandler: contextmenu,//是否启用行的扩展事情功能,在生成行时绑定事件,如双击,右键等
		rowbinddata: true,//配合上一个操作,如在双击事件中获取该行的数据
		onrowchecked: false//在每一行的的checkbox选中状态发生变化时触发某个事件
	});
	function contextmenu(row) {
        var menu = { width: 150, items: [
             { text: "查看", icon: "images/icons/search.png", alias: "contextmenu-view", action: contextMenuItem },
             { text: "编辑", icon: "images/icons/modify.png", alias: "contextmenu-modify", action: contextMenuItem },
             { text: "删除", icon: "images/icons/close.png", alias: "contextmenu-delete", action: contextMenuItem }
        ]
    };
	function contextMenuItem(target) {
            var id = $(target).attr("id").substr(3);
            var cmd = this.data.alias;
            var ch = $.browser.msie ? target.ch : target.getAttribute("ch");
            var cell = ch.split("_FG$SP_");
            if (cmd == "contextmenu-view") {
                alert("编辑,编号=" + id);
            }
            else if (cmd == "contextmenu-modify") {
                alert("编辑,编号=" + id);
            }
            else if (cmd == "contextmenu-delete") {
                var name = cell[1];
                if (confirm("你确认要删除 [" + name + "] 吗?")) {
                    alert("删除,编号=" + id);
                }
            }
            else {
                $("#flex1").flexReload();
            }
        }
        $(row).contextmenu(menu);
    }
	
	function toolbarItem(com, grid) {
       if (com=='delete'){
			if($('.trSelected',grid).length==0){
				alert("请选择要删除的数据");
			}else{
				if(confirm('是否删除这 ' + $('.trSelected',grid).length + ' 条记录吗?')){
					 var  ids ="";
				     for(var i=0;i<$('.trSelected',grid).length;i++){
				        ids+=","+$('.trSelected',grid).find("td:eq(2)").eq(i).text();//获取id,td:eq(2)
				      }
				      ids=ids.substring(1);
				      $.ajax({
							type: "POST",
							url: "flexGridServlet.do?action=delete",
							data: "id="+ids,
							dataType:"text",
							success: function(msg){
								if(msg=="success"){
									$("#flex1").flexReload();
								}else{
									alert("有错误发生,msg="+msg);
								}
							},
							error: function(msg){
								alert("msg="+msg);
							}
						});
		      	}
		   }
		}else if (com=='add'){
			alert("flexGridServlet.do?action=add");
			window.location.href="flexGridServlet.do?action=add";
		}else if (com=='modify'){
			if($(".trSelected").length==1){
				window.location.href="flexGridServlet.do?action=modify&id="+$('.trSelected',grid).find("td").eq(2).text();
			}else if($(".trSelected").length>1){
				alert("请选择一个修改,不能同时修改多个");
			}else if($(".trSelected").length==0){
				alert("请选择一个您要修改的记录")
			}
			//$("#flex1").flexReload({});
		}
    }
	function formatMoney(value, pid) {
         return "¥" + parseFloat(value).toFixed(2);
    }
    
});
</script>
<style>
   
   .bbit-grid div.fbutton .add{
       	padding-left:20px;
        background: url(images/icons/add.png) no-repeat center left;
   }
   .bbit-grid div.fbutton .modify{
       padding-left:20px;
       background: url(images/icons/modify.png) no-repeat center left;
   }
   .bbit-grid div.fbutton .delete{
       padding-left:20px;
       background: url(images/icons/close.png) no-repeat center left;
   }
    
</style>
</head>
<body>
<div id="ptable" style="margin:10px">
	<table id="flex1" style="display:none"></table>
</div>  
<input id="action" type="hidden" name="action" value="null" />
<input id="method" type="hidden" name="method" value="null" />
<script>
   		
</script>

</body>
</html>


import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.*;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FlexiGridServlet extends HttpServlet {
	private DBConnection db;

	public void init() throws ServletException {
		db = new DBConnection();// 打开链接
		try {
			db.getCurrentConnection();
		} catch (SQLException e1) {
		}
	}

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		// response相关处理
		response.setContentType("html/txt");
		response.setCharacterEncoding("utf-8");
		response.setHeader("Pragma", "no-cache");
		response.setHeader("Cache-Control", "no-cache, must-revalidate");
		response.setHeader("Pragma", "no-cache");

		String action = request.getParameter("action");
		System.out.println("action================" + action);
		String tableName = "job_info1";
		 if ("add".equals(action)) {
			System.out.println("--------------------add--------------------");
			return;
		} else if ("delete".equals(action)) {
			System.out.println("--------------------delete------------------");
			String ids=request.getParameter("id");
			System.out.println("ids="+ids);
			String sql = "delete from "+tableName+" where id in ("+ids+")";
			
			System.out.println("sql="+sql);
			try {
				db.executeUpdate(sql, null);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("delete success!!!");
			response.getWriter().write("success");
			response.getWriter().flush();
			response.getWriter().close();
			return;
		} else if ("modify".equals(action)) {
			System.out.println("--------------------modify-------------------");
			String id=request.getParameter("id");
			System.out.println("id="+id);
			return;
		} else {

		}
		 System.out.println("--------------------下来了-------------------");
		
		// 获得当前页数
		String pageIndex = request.getParameter("page");
		System.out.println("pageIndex=" + pageIndex);
		// 获得每页数据最大量
		String pageSize = request.getParameter("rp");
		System.out.println("pageSize=" + pageSize);
		// 获得模糊查询文本输入框的值
		String query = new String(request.getParameter("query").getBytes("ISO8859-1"), "UTF-8");
				
		System.out.println("query=" + query);
		// 获得模糊查询条件
		String qtype = request.getParameter("qtype");
		System.out.println("qtype=" + qtype);
		// 排序的字段
		String sortname = request.getParameter("sortname");
		System.out.println("sortname=" + sortname);
		// desc or asc
		String sortorder = request.getParameter("sortorder");
		System.out.println("sortorder=" + sortorder);

		int count = 0;
		String sql = "";
		List list = null;
		
		try {
			sql = "select count(*) from " + tableName;
			if (!query.equals("")) {
				sql += " where " + qtype + "='" + query + "'";
			}
			System.out.println("sql=" + sql);
			count = db.executeQuery(sql);
			System.out.println("count=" + count);

			sql = "select * from " + tableName;
			if (!query.equals("")) {
				sql += " where " + qtype + "='" + query + "'";
			}
			sql += " order by " + sortname + " " + sortorder;
			sql += " limit "
					+ ((Integer.parseInt(pageIndex) - 1) * Integer
							.parseInt(pageSize)) + "," + pageSize;
			System.out.println("sql=" + sql);
			list = db.executeQueryList(sql);
			System.out.println("list.size=" + list.size());
			if (list == null) {
				System.out.println("======出错啦======");
				return;
			}
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		Map map = new HashMap();
		map.put("page", pageIndex);
		map.put("total", count + "");
		// 数据JSON格式化
		String json = toJSON(list, map);

		response.getWriter().write(json);
		response.getWriter().flush();
		response.getWriter().close();

	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

	public void destroy() {
		db.closeCurrentConnection();
	}

	/**
	 * 数据JSON格式化
	 * 
	 * @param list
	 * @param pageInfo
	 * @return
	 */
	private String toJSON(List list, Map map) {
		List mapList = new ArrayList();
		for (int i = 0; i < list.size(); i++) {
			Map cellMap = new HashMap();
			cellMap.put("id", ((Map) list.get(i)).get("id").toString());
			cellMap.put("cell", new Object[] { 
					//"<input type='checkbox'/>",
					((Map) list.get(i)).get("id"),
					((Map) list.get(i)).get("job_name"),
					((Map) list.get(i)).get("work_address"),
					((Map) list.get(i)).get("salary"),
					((Map) list.get(i)).get("date"),
					((Map) list.get(i)).get("language") });
			mapList.add(cellMap);
		}
		map.put("rows", mapList);
		JSONObject object = new JSONObject(map);
		return object.toString();
	}

}

  • 大小: 50.7 KB
分享到:
评论
2 楼 我最爱刘 2014-07-30  
尊敬的大神 您好 我看了您“基于jQuery的FlexiGrid的插件使用和改造”这篇文章,现在正好用到这个控件,麻烦您能给发一份您自己测试的demo吗  小弟感激不尽   我的qq邮箱为 253537333@qq.com   非常感谢
1 楼 菜菜菜 2011-03-20  
求教,请问我要在里面加入自己的查询条件呢?应该怎么做?

相关推荐

Global site tag (gtag.js) - Google Analytics