在Web中基于表格的操作,比如添加行、单元格内容编辑等等功能,是完全基于js实现的。但如果程序员完全使用js或者jquery去编写表格控件,则会导致样式不统一,代码量较大等问题,尤其对于不太熟悉js的后端程序员来说,可能会是一个挑战。因此,网络上出现了很多基于表格操作的js控件,帮助程序员尤其是后端程序员也能够编写出漂亮的基于表格的应用。本篇博客以ASP.NET MVC+BUI为例,看如何实现基于表格的分页查询、编辑、删除等功能。
首先介绍一下BUI。BUI是基于jQuery开发的轻量级的控件库,官网链接为:http://www.builive.com/demo/index.php。程序员只要参照示例中的js代码,提供后端数据源部分,就能实现数据操作。要使用bui首先要去官网下载bui控件包,将其文件放入到ASP.NET MVC项目中的Scripts目录下,然后在cshtml文件中引用css、js即可。
我们这篇博客要实现的功能大概如下。首先点击查询按钮,显示出当前的数据(支持分页)。
点击修改时出现的界面,会加载选中表格的行的数据。
点击删除,会出现对话框。点击确定按钮,会删除对应表格的行的信息,并自动刷新表格内容。
完整的cshtml部分代码:
@{ Layout = null; } DOCTYPE html> <html> <head> <meta name="viewport" content="width=device-width" /> <title>档案修改title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <link href[email protected]("~/Scripts/bui/css/dpl-min.css") rel="stylesheet" type="text/css" /> <link href[email protected]("~/Scripts/bui/css/bui-min.css") rel="stylesheet" type="text/css" /> <link href[email protected]("~/Scripts/bui/css/page-min.css") rel="stylesheet" type="text/css" /> head> <body> <div class="container"> <form id="searchForm" class="form-horizontal"> <div class="row"> <div class="control-group span8"> <label class="control-label"> 单位代码: label> <div class="controls"> <input type="text" class="control-text" name="dwdm" id="dwdm" /> div> div> <div class="control-group span8"> <label class="control-label"> 工作单位: label> <div class="controls"> <input type="text" class="control-text" name="gzdw" id="gzdw" /> div> div> <div class="control-group span8"> <label class="control-label"> 个人社保代码: label> <div class="controls"> <input type="text" class="control-text" name="grsbdm" id="grsbdm" /> div> div> div> <div class="row"> <div class="control-group span8"> <label class="control-label"> 姓名: label> <div class="controls"> <input type="text" class="control-text" name="xm" id="xm" /> div> div> <div class="control-group span8"> <label class="control-label"> 身份证号码: label> <div class="controls"> <input type="text" class="control-text" name="sfzhm" id="sfzhm" /> div> div> <div class="control-group span8"> <label class="control-label"> 档案号: label> <div class="controls"> <input type="text" class="control-text" name="dah" id="dah" /> div> div> div> <div class="row"> <div class="control-group span8"> <label class="control-label"> 工作年月: label> <div class="controls"> <input type="text" name="gzny" id="gzny" /> div> div> <div class="control-group span8"> <label class="control-label"> 退休年月: label> <div class="controls"> <input type="text" name="txny" id="txny" /> div> div> <div class="span3 offset1"> <button type="button" id="btnSearch" class="button button-primary"> 查询 button> div> div> form> <div id="content" class="hide"> <form class="form-horizontal"> <div class="row"> <div class="control-group span8"> <label class="control-label"> <s>*s>单位代码label> <div class="controls"> <input name="DWDM" type="text" data-rules="{required:true}" class="input-normal control-text"> div> div> <div class="control-group span8"> <label class="control-label"> <s>*s>工作单位label> <div class="controls"> <input name="GZDW" type="text" data-rules="{required:true}" class="input-normal control-text"> div> div> div> <div class="row"> <div class="control-group span8"> <label class="control-label"> <s>*s>个人社保代码label> <div class="controls"> <input id="grsbdm_val" name="GRSBDM" type="text" data-rules="{required:true}" class="input-normal control-text"> <input id="grsbdm_old_val" name="GRSBDM" type="hidden" /> <input id="smr_old_val" name="SMR" type="hidden" /> div> div> <div class="control-group span8"> <label class="control-label"> <s>*s>档案号label> <div class="controls"> <input id="dah_val" name="DAH" type="text" data-rules="{required:true,number : true}" class="input-normal control-text"> <input id="dah_old_val" name="DAH" type="hidden" /> div> div> div> <div class="row"> <div class="control-group span8"> <label class="control-label"> <s>*s>姓名label> <div class="controls"> <input name="XM" type="text" data-rules="{required:true}" class="input-normal control-text"> div> div> <div class="control-group span8"> <label class="control-label"> <s>*s>身份证号label> <div class="controls"> <input name="SFZHM" type="text" data-rules="{required:true}" class="input-normal control-text"> div> div> div> <div class="row"> <div class="control-group span8 "> <label class="control-label"> 工作年月label> <div class="controls"> <input type="text" name="GZNY" id="gzny" /> div> div> <div class="control-group span8 "> <label class="control-label"> 退休年月label> <div class="controls"> <input type="text" name="TXNY" id="txny" /> div> div> div> <div class="row"> <div class="control-group span15"> <label class="control-label"> 退休类型label> <div class="controls control-row4"> <textarea name="TXLX" class="input-large" type="text">textarea> div> div> div> form> div> <div class="search-grid-container"> <div id="grid"> div> div> div> <script src='@Url.Content("~/Scripts/bui/js/jquery-1.8.1.min.js")' type="text/javascript">script> <script src='@Url.Content("~/Scripts/bui/js/bui-min.js")' type="text/javascript">script> <script src='@Url.Content("~/Scripts/bui/js/config-min.js")' type="text/javascript">script> <script type="text/javascript"> BUI.use(['common/search', 'common/page'], function (Search) { var Grid = BUI.Grid, Data = BUI.Data; var Grid = Grid, Store = Data.Store, enumObj = { "1": "男", "0": "女" }, columns = [ { title: '档案号', dataIndex: 'DAH', width: 50 }, { title: '单位代码', dataIndex: 'DWDM', width: 60 }, { title: '工作单位', dataIndex: 'GZDW', width: 200 }, { title: '个人社保代码', dataIndex: 'GRSBDM', width: 100 }, { title: '姓名', dataIndex: 'XM', width: 60 }, { title: '身份证号码', dataIndex: 'SFZHM', width: 150 }, { title: '工作年月', dataIndex: 'GZNY', width: 80 }, { title: '退休年月', dataIndex: 'TXNY', width: 80 }, { title: '退休类型', dataIndex: 'TXLX', width: 60 }, { title: '状态', dataIndex: 'YXBZ', width: 60, renderer: function (v) { if (v == "0") { delStr = '正常'; } else if(v == "1"){ delStr = '死亡'; }else if(v == "2"){ delStr = '删除'; } return delStr; }}, { title: '扫描人', dataIndex: 'SMR', width: 80 }, { title: '操作', width: 80, renderer: function () { // var editStr = Search.createLink({ //链接使用 此方式 // id: 'edit' + obj.id, // title: '编辑档案信息', // text: '编辑', // href: 'search/edit.html' // }), var editStr = '修改'; delStr = '删除'; //页面操作不需要使用Search.createLink return editStr + delStr; } } ], store = new Store({ url: '@Url.Action("DACXResult", "CXDY")', params: { dwdm: $("#dwdm").val(), gzdw: $("#gzdw").val(), grsbdm: $("#grsbdm").val(), xm: $("#xm").val(), sfzhm: $("#sfzhm").val(), dah: $("#dah").val(), gzny: $("#gzny").val(), txny: $("#txny").val() }, autoLoad: true, //自动加载数据 pageSize: 10// 配置分页数目 }), editing = new Grid.Plugins.DialogEditing({ contentId: 'content', //弹出框显示的内容的id triggerCls: 'btn-edit', //点击表格行时触发编辑的 css autoUpdate: false, editor: { title: '退休人员信息修改', success: function () { var editor = this, form = editor.get('form'), editType = editing.get('editType'); form.valid(); if (form.isValid()) { form.ajaxSubmit({ dataType: "text", url: '@Url.Action("ModifyRY", "DAManage")', data: { 'grsbdm_val': $("#grsbdm_val").val(), 'grsbdm_old_val': $("#grsbdm_old_val").val(), 'dah_val':$("#dah_val").val(), 'dah_old_val': $("#dah_old_val").val(), }, success: function (data) { if (data == 'fail') { BUI.Message.Alert(data.Message, 'error'); } if (data == 'success') { if (editType == 'add') { // store.add(data.Data); } if (editType == 'edit') { record = form.serializeToObject(); editing.saveRecord(record); } editor.accept(); } }, error: function () { BUI.Message.Alert('修改信息时发生错误', 'error'); } }); } } } }), gridCfg = Search.createGridCfg(columns, { // tbar: { // items: [ // { text: '新建', btnCls: 'button button-small', handler: function () { alert('新建'); } }, // { text: '编辑', btnCls: 'button button-small', handler: function () { alert('编辑'); } }, // { text: '删除', btnCls: 'button button-small', handler: delFunction } // ] // }, plugins: [editing] }); var search = new Search({ store: store, gridCfg: gridCfg }), grid = search.get('grid'); function delFunction() { var selections = grid.getSelection(); delItems(selections); } function delItems(items) { var grsbdm = []; BUI.each(items, function (item) { grsbdm.push(item.GRSBDM); }); if (grsbdm.length) { BUI.Message.Confirm('确认要删除选中的记录么?', function () { $.ajax({ url: '@Url.Action("DelRY", "DAManage")' + '?grsbdm=' + grsbdm, method: 'get', //dataType: 'json', //data: { grsbdm: grsbdm }, success: function (data) { if (data == "success") { //删除成功 search.load(); } else { //删除失败 BUI.Message.Alert('删除失败!'); } } }); }, 'question'); } } //监听事件,删除一条记录 grid.on('cellclick', function (ev) { var sender = $(ev.domTarget); //点击的Dom if (sender.hasClass('btn-del')) { var record = ev.record; delItems([record]); } }); }); script> <script type="text/javascript"> function selectDate(id) { var Calendar = BUI.Calendar var inputEl = $('#' + id), monthpicker = new BUI.Calendar.MonthPicker({ trigger: inputEl, // month:1, //月份从0开始,11结束 autoHide: true, align: { points: ['bl', 'tl'] }, //year:2000, success: function () { var month = this.get('month'), year = this.get('year'); inputEl.val(year + '-' + (month + 1)); //月份从0开始,11结束 this.hide(); } }); monthpicker.render(); monthpicker.on('show', function (ev) { var val = inputEl.val(), arr, month, year; if (val) { arr = val.split('-'); //分割年月 year = parseInt(arr[0]); month = parseInt(arr[1]); monthpicker.set('year', year); monthpicker.set('month', month - 1); } }); } selectDate('gzny'); selectDate('txny'); script> body> html>
CXDYController中的DACXResult方法代码:
////// 档案查询结果 /// /// [HttpGet] public JsonResult DACXResult() { using (dao as IDisposable) { int start = int.Parse(Request["start"] ?? "20"); int limit = int.Parse(Request["limit"] ?? "10"); int pageIndex = int.Parse(Request["pageIndex"] ?? "1") + 1; int all = 0; #region where条件 string strWhere = string.Empty; if (!string.IsNullOrEmpty(Request["dwdm"])) { strWhere += "and dwdm = '" + Request["dwdm"] + "'"; } if (!string.IsNullOrEmpty(Request["gzdw"])) { strWhere += "and gzdw = '" + Request["gzdw"] + "'"; } if (!string.IsNullOrEmpty(Request["grsbdm"])) { strWhere += "and grsbdm = '" + Request["grsbdm"] + "'"; strWhere += "and (yxbz = '0' or yxbz = '1' or yxbz = '2')"; } if (!string.IsNullOrEmpty(Request["xm"])) { strWhere += "and xm = '" + Request["xm"] + "'"; strWhere += "and (yxbz = '0' or yxbz = '1' or yxbz = '2')"; } if (!string.IsNullOrEmpty(Request["sfzhm"])) { strWhere += "and sfzhm = '" + Request["sfzhm"] + "'"; } if (!string.IsNullOrEmpty(Request["dah"])) { strWhere += "and dah = '" + Request["dah"] + "'"; strWhere += "and (yxbz = '0' or yxbz = '1' or yxbz = '2')"; } if (!string.IsNullOrEmpty(Request["gzny"])) { strWhere += "and gzny = '" + Request["gzny"] + "'"; } if (!string.IsNullOrEmpty(Request["txny"])) { strWhere += "and txny = '" + Request["txny"] + "'"; } if (string.IsNullOrEmpty(Request["grsbdm"])&& string.IsNullOrEmpty(Request["xm"])&& string.IsNullOrEmpty(Request["dah"])) { strWhere += "and yxbz = '0'"; } #endregion string orderBy = "order by yxbz,to_number(dah) asc,gxsj desc"; DataSet ds = dao.GetListByPage2(strWhere, orderBy, start, limit, pageIndex, out all); int count = ds.Tables[0].Rows.Count; RYXX[] ryxxs = new RYXX[count]; for (int i = 0; i < count; i++) { RYXX ryxx = dao.DataRowToModel(ds.Tables[0].Rows[i]); ryxxs[i] = ryxx; } return new JsonResult() { Data = new PageData () { rows = ryxxs, results = all, hasError = false, error = "" }, MaxJsonLength = int.MaxValue, ContentType = "application/json", JsonRequestBehavior = JsonRequestBehavior.AllowGet }; } }
PageData泛型类代码(分页对象):
public class PageDatawhere T : class { public T[] rows { get; set; } public int results { get; set; } public bool hasError { get; set; } public string error { get; set; } }
RYXX实体类代码:


////// 人员信息 /// public class RYXX { /// /// 单位代码 /// public string DWDM { get; set; } /// /// 工作单位 /// public string GZDW { get; set; } /// /// 个人社保代码 /// public string GRSBDM { get; set; } /// /// 姓名 /// public string XM { get; set; } /// /// 身份证号码 /// public string SFZHM { get; set; } /// /// 工作年月 /// public string GZNY { get; set; } /// /// 退休年月 /// public string TXNY { get; set; } /// /// 档案号 /// public string DAH { get; set; } /// /// 退休类型 /// public string TXLX { get; set; } /// /// 有效标志(0表示正常,1表示死亡) /// public string YXBZ { get; set; } /// /// 档案扫描人 /// public string SMR { get; set; } /// /// 数据导入人 /// public string DRR { get; set; } }
GetListByPage2分页代码(基于Oracle的分页查询):
////// 分页获取数据 /// /// where条件 /// 排序 /// 开始记录的起始数,如第 20 条,从0开始 /// 单页多少条记录 /// 第几页,同start参数重复,可以选择其中一个使用 /// 记录总数 /// 分页数据 public DataSet GetListByPage2(string strWhere, string orderBy, int start, int limit, int pageIndex, out int all) { string sql1 = "SELECT * FROM T_RYXX where 1=1 " + strWhere + " " + orderBy; all = OracleHelper.Query(sql1).Tables[0].Rows.Count; string sql = @"SELECT * FROM (SELECT A.*, ROWNUM RN FROM (SELECT * FROM T_RYXX where 1=1" + strWhere + " " + orderBy + ") A WHERE ROWNUM <= '" + limit * pageIndex + "') WHERE RN > '" + start + "'"; return OracleHelper.Query(sql); }
DAManage中的ModifyRY和DelRY方法代码就不贴了,与上述Action中的查询代码思路类似(Request获取参数,然后后端执行一下sql返回标志,前端success回调函数处理)。通过上面的例子可以看出,现在Web开发大部分都是js代码,C#代码只占很少部分。因此熟练掌握js对于web开发来说是第一位的。