接触mvc不久,突然没有了viewstate和服务端控件处处都觉得不顺手,很多在webform时不必要考虑的问题都出现在眼前,这其中分页时查询条件保持的问题又是最让我头疼的事情,权衡再三,决定用ajax局部刷新列表的方式来解决这个问题。网上基于jquery的grid组件很多,jquerygrid,jqgrid等等,分别试用了一下,功能确实非常强大,但感觉上有点重,配置项太多,用起来依然感觉束手束脚,所以想来想去,还是用最笨的办法自己做了一个组件,很简陋,唯一的好处就是灵活,容易修改和控制。

没图没真相,先来个截图看看:

功能:

  1. 指定url,支持post或get方式加载数据
  2. 自定义数据查询条件
  3. 列定义时可以对数据项进行简单的转换处理。如:数据源[{ "name": "张三",  "age": 12, "sex": 1 }],渲染时希望把sex的值 1 显示为 男性
  4. 支持多选
  5. 支持分页
  6. 点击行时自动选中,多选时,点击checkbox进行选中和取消选中
  7. 能够返回选中项目的值,多选时返回选中值的数组

根据个人的习惯和对功能的分解,定义了这样一个setting:

var list = $('#list').GridView({'apiUrl': '/Student/List',  // 指定数据请求的URL路径'apiType': 'post',  // 请求的方式'columns': [    // 要显示的列,title对应表头,column对应数据项的属性名称,width指定列的宽度,func指定绑定时调用的函数名称{ title: '姓名', column: 'Name', width: 160 },{ title: '年龄', column: 'Age' },{ title: '性别', column: 'Sex', width: 100, 'func': 'convertToSex' }],'valueColumn': 'StudentId', // data-value 取值的属性名'pageSize': 20, // 每页显示的数量'isMultiy': false,  // 是否支持多选'isTreeView': false,   // 是否支持树形'pager': 'pager',   // 指定包含分页的divid,主要是为了能单独控制pager中的一些数据,把pager给拆出来了,后来发现似乎用处不大'onRowClick': function(id) { }, // 当数据行被点击时执行的回调,参数是tr中的data-value'convertSource': function (data) { return data.body; }, // 使用数据源之前对数据进行转换。因为我的api返回的都是{ code: 200, body: [] }这种类型,需要在这里直接返回body'onDataBindComplete': function() {}, // 当数据加载完成,也就是列表渲染完成后的回调。比如说提醒用户加载完成之类的'getSearchData': function() { return $('#form1').serialize(); },    // 获取查询参数,这个很重要,想了很多办法,最终采用了这种方案,在查询前运行这个函数,将返回值作为ajax的查询参数'listCssClass': 'table',    // 列表table的样式名'pagerCssClass': 'pager',   // 分页最外面div的样式名'beforeSend': function() { }    // ajax请求之前调用的函数,原本是为了提醒一下加载已开始,请稍后之类的,现在没怎么用到});

OK,接下来就是这个扩展的具体实现了,代码很多,但思路很简单,主要就是代码的拼接。大家自己看吧!

(function ($) {$.fn.GridView = function (settings) {// 系统变量var self = this;self.selected = [];var pageindex = 1, pageSize = 20;if (settings.pageSize && $.isNumeric(settings.pageSize) && settings.pageSize > 0) {pageSize = settings.pageSize;}var rand = Math.floor(Math.random() * 1000);var table = $("<table" + (settings.listCssClass ? " class='" + settings.listCssClass + "'" : "") + " id='myList" + rand + "'></table>");var colgroup = colgroup2 = "<colgroup>"$.each(settings.columns, function (idx, item) {colgroup += "<col" + item.width ? " style='width:" + item.width + "px;'" : "" + ">";colgroup2 += "<col" + item.width ? " style='width:" + item.width + "px;'" : "" + ">";});colgroup += "<col style='width:18px;'></col>";colgroup += "</colgroup>";colgroup2 += "</colgroup>";var table = $("<table" + (settings.listCssClass ? " class='" + settings.listCssClass + "'" : "") + " id='myList" + rand + "'></table>");var pagerHtml = '<div' + (!settings.pagerCssClass ? '' : ' class="' + settings.pagerCssClass + '"') + '>';//var pagerHtml = '';pagerHtml += '<a class="disabled" id="first' + rand + '"><i class="fa fa-fast-backward"></i></a>';pagerHtml += '<a class="disabled" id="prev' + rand + '"><i class="fa fa-backward"></i></a>';pagerHtml += '<div class="pager-index"><b>第</b><input value="1" type="text" maxlength="4" id="index' + rand + '"><b>页</b></div>';pagerHtml += '<a class="disabled" id="next' + rand + '"><i class="fa fa-forward"></i></a>';pagerHtml += '<a class="disabled" id="last' + rand + '"><i class="fa fa-fast-forward"></i></a>';pagerHtml += '<div class="pager-info2"> 共计 <span class="totalCount" id="total' + rand + '">0</span> 条记录,';pagerHtml += '每页显示 <span class="pageSize' + rand + '">' + pageSize + '</span> 条,';pagerHtml += '共 <span class="totalPage" id="page' + rand + '">1</span> 页,';pagerHtml += '用时 <span class="loadTime" id="time' + rand + '">0</span>毫秒';pagerHtml += "</div></div>";var pagerDom = $(pagerHtml);var firstButton, prevButton, nextButton, lastButton, currentSpan, pageSizeSpan, totalCountSpan, totalPagesSpan, loadTimeSpan;// 临时变量var tbody, pager, cbAll, checkboxes, isPager = false, totalPage = 1;// 创建tableself.append(table);// 创建theadaddChildrenToTable();// 为tbody赋值tbody = $("#tbody" + rand);var colCount = settings.columns.length + 2;tbody.html("<tr class='empty'><td colspan='" + colCount + "'>等待加载数据...</td></tr>");// 创建分页if (settings.pager && $("#" + settings.pager)[0]) {pager = $("#" + settings.pager);isPager = true;pager.append(pagerDom);setPagerButtonEvent();}// 创建渲染函数self.fun = new Function("data", renderFunString());// 渲染第一列self.setFirstCol = function (val) {if (settings.isMulti) {return "<td class='chk'><input type='checkbox' id='cb" + val + "' value='" + val + "'></td>"} else {return "<td class='no'>" + val + "</td>";}}// 渲染最后一列self.setLastCol = function () {return "<td></td>";}// 渲染中间列self.setCol = function (content, width, cssClass, level) {var html = "<td";html += width ? " style='width:" + width + "px'" : "";html += cssClass && cssClass != 'undefined' ? " class='" + cssClass + "'" : "";html += ">";if (settings.isTreeView) {html += level ? "<span class='block' style='width:" + 24 * level + "px'>" + (level > 0 ? "|—" : "") + "</span>" : "";}html += content && content != "undefined" ? content : "";html += "</td>";return html;}// 显示指定页码的数据self.show = function (index, type) {self.selected = [];if (!settings.apiUrl) {return;}if (!type || type.toLowerCase() != "post") {$.get(settings.apiUrl, getAjaxData(), function (data) {var source = [];if (settings.convertSource && $.isFunction(settings.convertSource)) {source = settings.convertSource(data);} else {source = data;}addRowsToTbody(source);});} else {$.post(settings.apiUrl, getAjaxData(), function (data) {var source = [];if (settings.convertSource && $.isFunction(settings.convertSource)) {source = settings.convertSource(data);} else {source = data;}addRowsToTbody(source);});}};// 获取选中的IDself.getSelectedId = function () {if (self.selected.length == 0) {return null;} else {return self.selected[0];}};self.getSelectedIds = function () {return self.selected;};self.clear = function () {self.selected = [];$("tr", "#myList" + rand).removeClass("selected");$(":checkbox", "#myList" + rand).prop("checked", false);};// 为table内的元素绑定事件tbody.on("click", "tr", function () {if ($(this).hasClass("empty")) return;$("tr", tbody).removeClass("selected").find(":checkbox").prop("checked", false);$(this).addClass("selected").find(":checkbox").prop("checked", true);$("#cbAll" + rand).prop("checked", false);self.selected = [$(this).data("value")];});// 绑定复选框点击事件if (settings.isMulti) {cbAll = $("#cbAll" + rand);cbAll.on("click", function () {if (!checkboxes) checkboxes = $(":checkbox", tbody);if ($(this).prop("checked")) {self.selected = [];$.each(checkboxes, function (idx, item) {$(this).prop("checked", true);self.selected.push($(this).val());var tr = $("#tr" + $(item).val());if (!tr.hasClass("selected")) tr.addClass("selected");});} else {checkboxes.prop("checked", false);$("tr", tbody).removeClass("selected");self.selected = [];}});tbody.on("click", ":checkbox", function (event) {event.stopPropagation();if ($(this).prop("checked")) {$("#tr" + $(this).val()).addClass("selected");} else {$("#tr" + $(this).val()).removeClass("selected");}if (!checkboxes) {checkboxes = $(":checkbox", tbody);}self.selected = [];var unCheckedCount = 0;$.each(checkboxes, function () {if ($(this).prop("checked")) {self.selected.push($(this).val());} else {unCheckedCount++;}});if (unCheckedCount > 0) {cbAll.prop("checked", false);} else {cbAll.prop("checked", true);}});}// 返回渲染函数的程序体function renderFunString() {var funString = "var self = this; var html = ''; $.each(data, function(idx, item) { var val = ";funString += (settings.valueColumn ? "item." + settings.valueColumn : "idx");funString += "; html += '<tr id=\"tr' + val + '\" data-value=\"' + val + '\">'; html += self.setFirstCol(val);";var level = null;if (settings.levelColumn) {level = settings.levelColumn;}$.each(settings.columns, function (idx, item) {if (item.func) {funString += " html += self.setCol( " + item.func + "(item), " + item.width + ", '" + item.cssClass + "'" + (level ? " , item." + level : "") + " );";} else {funString += " html += self.setCol( item." + item.column + ", " + item.width + ", '" + item.cssClass + "'" + (level ? " , item." + level : "") + " );";}});funString += " html += self.setLastCol(); html += '</tr>'; idx++; }); return html;";return funString;}// 将数据生成html,并插入到tbody中function addRowsToTbody(data) {if (data && data.body && data.body.length > 0) {var html = self.fun(data.body);tbody.html(html);if (isPager) {setPagerButton(pageSize, pageindex, data.totalCount, new Date().getTime());}} else {var colCount = settings.columns.length + 2;tbody.html("<tr class='empty'><td colspan='" + colCount + "'>请求的数据为空</td></tr>");}}// 创建tablefunction addChildrenToTable() {var body = "<thead>"if (settings.columns) {if (settings.isMulti) {body += "<th class='chk'><input type='checkbox' id='cbAll" + rand + "' /></th>";} else {body += "<th class='no'></th>";}$.each(settings.columns, function (idx, col) {body += "<th>" + col.title + "</th>";});body += "<th></th>";body += "</thead><tbody id='tbody" + rand + "'></tbody>";table.append($(body));}}// 绑定分页按钮的点击事件function setPagerButtonEvent() {firstButton = $("#first" + rand);prevButton = $("#prev" + rand);nextButton = $("#next" + rand);lastButton = $("#last" + rand);currentSpan = $("#index" + rand);pageSizeSpan = $("#size" + rand);;totalCountSpan = $("#total" + rand);;totalPagesSpan = $("#page" + rand);;loadTimeSpan = $("#time" + rand);;firstButton.on("click", function () {if (!$(this).hasClass("disabled")) {pageindex = 1;self.show();}});prevButton.on("click", function () {if (!$(this).hasClass("disabled")) {pageindex -= 1;pageindex = pageindex <= 0 ? 1 : pageindex;self.show();}});nextButton.on("click", function () {if (!$(this).hasClass("disabled")) {pageindex += 1;self.show();}});lastButton.on("click", function () {if (!$(this).hasClass("disabled")) {pageindex = totalPage;self.show();}});currentSpan.on("change", function () {var nc = Number($(this).val());if (nc && nc <= totalPage && nc > 0) {pageindex = nc;self.show();} else {$(this).val(pageindex);}});}// 配置 Pager 按钮function setPagerButton(size, index, total, start) {if (total == 0) {pager.hide();} else {pager.show();}// 总页数var pages = Math.ceil(total / size);pages = (pages == 0 ? 1 : pages);totalPage = pages;if (pages == 1) {if (!firstButton.hasClass("disabled")) {firstButton.addClass("disabled");}if (!prevButton.hasClass("disabled")) {prevButton.addClass("disabled");}if (!nextButton.hasClass("disabled")) {nextButton.addClass("disabled");}if (!lastButton.hasClass("disabled")) {lastButton.addClass("disabled");}} else {if (index == 1) {if (!firstButton.hasClass("disabled")) {firstButton.addClass("disabled");}if (!prevButton.hasClass("disabled")) {prevButton.addClass("disabled");}} else {if (firstButton.hasClass("disabled")) {firstButton.removeClass("disabled");}if (prevButton.hasClass("disabled")) {prevButton.removeClass("disabled");}}currentSpan.val(index);if (index == pages) {if (!nextButton.hasClass("disabled")) {nextButton.addClass("disabled");}if (!lastButton.hasClass("disabled")) {lastButton.addClass("disabled");}} else {if (nextButton.hasClass("disabled")) {nextButton.removeClass("disabled");}if (lastButton.hasClass("disabled")) {lastButton.removeClass("disabled");}}}totalCountSpan.text(total);pageSizeSpan.text(this.pageSize);totalPagesSpan.text(pages);loadTimeSpan.text((new Date().getTime() - start));}// 获取ajax的查询参数function getAjaxData() {var param;if ($.isFunction(settings.getSearchData)) {param = settings.getSearchData();}if (isPager) {if ($.isArray(param)) {                                             // $("form").serializationArray()param.push({ "name": "pageSize", "value": pageSize });param.push({ "name": "pageIndex", "value": pageindex });} else if ($.isPlainObject(param)) {                                 // 自定义查询对象$.extend(true, param, { "pageSize": pageSize, "pageIndex": pageindex });} else {                                                             // $("form").serialization()param = (param ? param + "&" : "") + "pageSize=" + pageSize + "&pageIndex=" + pageindex;}}return !!param ? param : {};}return self;}})(jQuery);/**使用范例:*==========================数据格式============================{"code": 200,"describe": "","totalCount": 3,"body": [{"no": 1,"name": "王五","family": {"father": "王老五","mother": "陈静蓉"}},{"no": 2,"name": "张三","family": {"father": "张作霖","mother": "李培芳"}},{"no": 3,"name": "李四","family": {"father": "李宗仁","mother": "江少芬"}}]}*==========================页面调用============================<script src="jquery-1.10.2.js"></script><script src="myGrid.js"></script><script>var list = $("#list").myGrid({apiUrl: "data.json",isMulti: false,isTree: true,cols: [{ col: "no", width: 120, title: "编号", cssClass: "chk", level: 0 },{ col: "name", width: 120, title: "姓名", level: 0 },{ col: "family.father", width: 120, title: "父亲", level: 1, func: "addFix" }],valueCol: "no",pager: "pager",pageSize: 2,cssClass: "default-list-table",convertSource: function(data) {return data;}});// 这个是用来转换数据的方法function addFix(obj) {return "000" + obj;}list.show();</script>

一个修改的操作:

转载于:https://www.cnblogs.com/diwu0510/p/6576453.html

自己写一个轻量的JqueryGrid组件相关推荐

  1. 在 C++ 中实现一个轻量的标记清除 gc 系统

    在 C++ 中实现一个轻量的标记清除 gc 系统 最近想把 engine 做一个简单 C++ 封装,结合 QT 使用.engine 本身是用纯 C 实现的,大部分应用基于 lua 开发.对对象生命期管 ...

  2. 关于VSCode中工作区的讲解与使用工作区还你一个轻量 的VSCode

    VSCode的使用率在逐渐提高,但安装太多的插件会使得VSCode变得臃肿,甚至运行变慢,占用太多内存,此文章介绍了工作区,并如何来使用工作区更好地体验VSCode. 初次使用VSCode,肯定有很多 ...

  3. 我们开源了一个轻量的 Web IDE UI 框架 - Molecule

    Molecule , 一个轻量的 Web IDE UI 框架 https://github.com/DTStack/molecule​github.com/DTStack/molecule 简介 Mo ...

  4. [react] 写一个react的高阶组件并说明你对高阶组件的理解

    [react] 写一个react的高阶组件并说明你对高阶组件的理解 定义高阶组件 import React, { Component } from 'react';const simpleHoc = ...

  5. 手把手教你写一个微信小程序日历组件

    今天我们一起写一个微信小程序日历组件 微信小程序日历组件 github.com/749264345/w- 好,我们先看一下要实现的模样,如下图 由以上截图我们可以看到 1.日历可以通过按钮[切换展示效 ...

  6. Javalin:一个轻量的 Web Framework

    说起 Java 语言下的 Web 框架那就非 Spring Framework 不可了,但是今天在和别人在聊天的过程中发现了一个新奇的项目 Javalin.Javalin 是一个轻量的 Web 框架. ...

  7. windows中常用的一个轻量的扫描软件xray_windows_amd64

    1.xray_windows_amd64现在windows中常用的一个轻量的扫描软件,用法要求各位同学通过物联网查找使用方式 完成对文章管理系统cms页面进行漏洞扫描. ①安装证书,在命令框xray_ ...

  8. Multipass - 一个轻量虚拟机管理器

    Multipass 是一个轻量虚拟机管理器,是由 Ubuntu 运营公司 Canonical 所推出的开源项目.运行环境支持 Linux.Windows.macOS.在不同的操作系统上,使用的是不同的 ...

  9. Nancy总结(一)Nancy一个轻量的MVC框架

    Nancy是一个基于.net 和Mono 构建的HTTP服务框架,是一个非常轻量级的web框架. 设计用于处理 DELETE, GET, HEAD, OPTIONS, POST, PUT 和 PATC ...

最新文章

  1. H3C S5500核心交换机策略路由调度流量到不同的路由设备
  2. 正则表达式及shell
  3. App设计灵感之十二组精美的插画引导页设计案例
  4. C#反射之Assembly.Load,Assembly.LoadFile 与 Assembly.LoadFrom方法介绍
  5. linux 脚本 发送邮件,shell 脚本发送邮件
  6. Spark案例:Java版统计单词个数
  7. xml解析总结-常用需掌握
  8. Android.mk、Makefile、Cmake打印log
  9. SharePoint 2010-在ribbon上添加表单,将默认control加到自定义group中
  10. FreeSwitch视频会议,4路以上CPU占用暴增的原因
  11. matlab lu分解 源代码,矩阵的LU分解(Matlab程序)
  12. 蹩脚的Access分页语句
  13. c++ 输入数字 输出汉语读法(拼音)代码
  14. 苹果笔到底有没有必要买?苹果平板电容笔排行榜
  15. 2014在线旅游业发展的几大趋势
  16. 三维vr全景摄影展示满足产品720立体浏览
  17. Redis高级项目实战,西安java程序员工资
  18. ScrollView和HorizontalScrollView常用属性,及禁止滑动
  19. jquery dataTable 参数详解
  20. 过期策略(TTL)与淘汰策略

热门文章

  1. 用python的turtle画炫酷的图-使用Python的turtle画炫酷图形
  2. python编写程序的一般步骤-Python编写win程序的操作流程
  3. python程序设计报告-20194115 实验二《Python程序设计》实验报告
  4. 软件测试用python一般用来做什么-python软件测试
  5. python3.6手册中文版-python3.6中文手册下载|
  6. python和vb的代码可以通用吗-python和vb哪个简单
  7. python3爬虫实例代码-Python3爬虫带上cookie的实例代码
  8. python3.6安装scrapy-python3.6 安装scrapy
  9. python电脑版微信-python如何实现远程控制电脑(结合微信)
  10. python流程控制语句-Python流程控制语句