转载请注册作者及出处

前些天写了一篇有关jqGrid的文章,因为是公司项目的原因一直没有提供源代码,今天又要用jqGrid,顺便做一个示例,以便有需要的人参考。源代码下载

为了使用方便起见,将jqGrid的一些选项放在了_Layout.cshtml中,这样就不用在每一个页面中重复输入了,见代码:

<!DOCTYPE html>
<html>
<head><title>@ViewBag.Title</title><link href="@Url.Content("~/Content/themes/base/site.css")" rel="Stylesheet" type="text/css" /><link href="@Url.Content("~/Content/themes/base/jquery.ui.css")" rel="Stylesheet" type="text/css" /><link href="@Url.Content("~/Content/themes/base/jquery.jqgrid.css")" rel="Stylesheet" type="text/css" /><script src="@Url.Content("~/Scripts/jquery.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/jquery.ui.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/i18n/grid.locale-cn.js")" type="text/javascript"></script><script src="@Url.Content("~/Scripts/jquery.jqgrid.js")" type="text/javascript"></script><script type="text/javascript">var gridContainerId = '#gridview', gridId = '#list';$(function () {$.extend($.jgrid.defaults, {ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },datatype: 'json',mtype: 'GET',hidegrid: false,rownumbers: true,rowNum: 10,rowList: [10, 15, 20],sortorder: 'asc',viewrecords: true,pager: $('#pager'),height: 'auto',editfunc: function (id, data) { return false; },delfunc: function (id, data) { return false; },cleverjqgridactions: 'clever_jqgrid_actions',colActionsTitle: '操作'});});function cleverActions(cellvalue, options, rowObject) {return '<a href="javascript:void(0)" id="' + options.rowId + '" class="ui-corner-all clever-jqgrid-action clever-jqgrid-edit" style="float: left; margin-left: 5px; padding: 0px;" title="' + $.jgrid.nav.edittitle + '" οnclick="actionClick(this,event)" οnmοuseοver="actionMouseover(this,event)" οnmοuseοut="actionMouseout(this,event)" ><span class="ui-icon ui-icon-pencil"></span></a>'+ '<a href="javascript:void(0)" id="' + options.rowId + '" class="ui-corner-all clever-jqgrid-action clever-jqgrid-del" style="float: left; margin-left: 5px; padding: 0px;" title="' + $.jgrid.nav.deltitle + '" οnclick="actionClick(this,event)" οnmοuseοver="actionMouseover(this,event)" οnmοuseοut="actionMouseout(this,event)" ><span class="ui-icon ui-icon-trash"></span></a>';}function actionMouseover(el, ev) {$(el).addClass('ui-state-hover');if ($.browser.msie) {ev.cancelBubble = true;} else {ev.stopPropagation();}}function actionMouseout(el, ev) {$(el).removeClass('ui-state-hover');if ($.browser.msie) {ev.cancelBubble = true;} else {ev.stopPropagation();}}function actionClick(el, ev) {var id = $(el).attr('id');var data = $(gridId).jqGrid('getRowData', id);if (data.clever_jqgrid_actions) {delete data.clever_jqgrid_actions;}if ($(el).hasClass('clever-jqgrid-edit')) {$(gridId).getGridParam('editfunc')(id, data);} else if ($(el).hasClass('clever-jqgrid-del')) {if (confirm($.jgrid.del.msg)) {$(gridId).getGridParam('delfunc')(id, data);}}if ($.browser.msie) {ev.cancelBubble = true;} else {ev.stopPropagation();}}</script>@RenderSection("header", false)<script type="text/javascript">$(function () {$(window).bind('resize', function () {var width = $(gridContainerId).width();if (width == null || width < 1) {width = $(gridContainerId).attr('offsetWidth');}width = width - 2;if (width > 0 && Math.abs(width - $(gridId).width()) > 5) {$(gridId).setGridWidth(width);}}).trigger('resize');});    </script>
</head>
<body>@RenderBody()
</body>
</html>

为了使jqGrid能随着浏览器的缩放而自适应宽度,因此我在视图页面执行完javascript后又为jqGrid指定了resize事件。

在这里值的一提的是,要为jqGrid指定默认选项,需要使用$.jgrid.defaults,方法嘛当然是继承了,这里我把部分默认选项的说明给出来:

//指定请求数据时的ContentType,我使用了json

ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },

//返回数据格式为json

datatype: 'json',

//Http方法为GET

mtype: 'GET',

//隐藏Grid的头

hidegrid: false,

//是否显示行号

rownumbers: true,

//默认显示数据行的个数

rowNum: 10,

//允许显示数据行个数的选项

rowList: [10, 15, 20],

//默认排序策略(升序)

sortorder: 'asc',

//是否显示表脚,即翻页所在的那行

viewrecords: true,

//页脚的容器

pager: $('#pager'),

//Grid高度自动调整

hieght: 'auto',

//这是我自定义的一个功能,后面会提到

editfunc: function (id, data) { return false; },

//自定义功能,同上

delfunc: function (id, data) { return false; },

//自定义功能,同上

cleverjqgridactions: 'clever_jqgrid_actions',

//自定义功能,同上

colActionsTitle: '操作'

一般情况下,在管理系统中,需要尽可能的减少用户的操作步骤,因此,把"编辑","删除"按钮直接放在数据行中,这样用户点一下就可以了,而不需要先选中一行,然后再去点击编辑/删除按钮,因此,使用自定义Formatter的方式,使每行增加一个"编辑","删除"按钮,方法如下:

在colModel中添加一个列:

 { name: $.jgrid.defaults.cleverjqgridactions, width: 80, fixed: true, sortable: false, resize: false, formatter: cleverActions }

上文中$.jgrid.defaults.cleverjqgridactions就是这个用途,为这个列提供一个不大可能重复的固定列定,以标示这个列,重点是formatter,为这个选项提供一个方法便是,这个方法的签名如下:
function (cellvalue, options, rowObject){
}

cellValue不用理会,因为它本来是指json为这个列提从的值,因为我们这个项不是json提供的,所以它肯定为undefined;
options里提供了这个列的定义(colModel中列的定义选项),该字段所在行的主键值(当然,得是你指定了某行为主键),以及jqGrid的id; 
rowObject是一个数组,为截止目前,所在行的json数据,为啥是截止目前呢?因为当你这一列定义成功后,本列也成为行数据的一员了,在实际应用中,你肯定不希望这列的数据(其实就是你定义的按钮的HTML字符串)作为正式数据传入到业务逻辑里吧,所以使用delete方法要删除行数据中的这个字段值,那如何获取这个字段的名称呢?当..当..当,还记得$.jgrid.defaults.cleverjqgridactions吗?当然是使用它了(貌似是一个锉方法哦?)。
ok,知道了这些,我们来定义一个自定义的formatter:
        function cleverActions(cellvalue, options, rowObject) {return '<a href="javascript:void(0)" id="' + options.rowId + '" class="ui-corner-all clever-jqgrid-action clever-jqgrid-edit" style="float: left; margin-left: 5px; padding: 0px;" title="' + $.jgrid.nav.edittitle + '" οnclick="actionClick(this,event)" οnmοuseοver="actionMouseover(this,event)" οnmοuseοut="actionMouseout(this,event)" ><span class="ui-icon ui-icon-pencil"></span></a>'+ '<a href="javascript:void(0)" id="' + options.rowId + '" class="ui-corner-all clever-jqgrid-action clever-jqgrid-del" style="float: left; margin-left: 5px; padding: 0px;" title="' + $.jgrid.nav.deltitle + '" οnclick="actionClick(this,event)" οnmοuseοver="actionMouseover(this,event)" οnmοuseοut="actionMouseout(this,event)" ><span class="ui-icon ui-icon-trash"></span></a>';}

使用$.jgrid.nav.edittitle和$.grid.nav.deltitle能获取到本地化的"编辑","删除"字符串,这样当用户把鼠标移动上按钮上时,就可以知道这两个按钮是什么用途了,所以将它哥俩的值指定给了a的title。
另外,我希望在我点击了"编辑"或是"删除"按钮时,就不要再触发行选中事件了,因此,我中止了事件冒泡,同样,我也中止了按钮的mouseover和mouseout事件冒泡:
        function actionMouseover(el, ev) {$(el).addClass('ui-state-hover');if ($.browser.msie) {ev.cancelBubble = true;} else {ev.stopPropagation();}}function actionMouseout(el, ev) {$(el).removeClass('ui-state-hover');if ($.browser.msie) {ev.cancelBubble = true;} else {ev.stopPropagation();}}function actionClick(el, ev) {var id = $(el).attr('id');var data = $(gridId).jqGrid('getRowData', id);if (data.clever_jqgrid_actions) {delete data.clever_jqgrid_actions;}if ($(el).hasClass('clever-jqgrid-edit')) {$(gridId).getGridParam('editfunc')(id, data);} else if ($(el).hasClass('clever-jqgrid-del')) {if (confirm($.jgrid.del.msg)) {$(gridId).getGridParam('delfunc')(id, data);}}if ($.browser.msie) {ev.cancelBubble = true;} else {ev.stopPropagation();}}

代码看到这里,我直是讨厌IE,就是整得和别人不一样。好好的就使用stopPropagation嘛,非得整啥cancelBubble呢?
            var id = $(el).attr('id');var data = $(gridId).jqGrid('getRowData', id);

鉴于在点击按钮后再获取行的主键值比较困难,我在生成铵钮时就将行主键值存在a标签的id中了,因此此时取出来,再使用getRowData方法获取该主键所在的行的数据对象,getRowData方法,据官方文档中说,性能不高,使用需谨慎,不要使用在for或是while中。
            if (data.clever_jqgrid_actions) {delete data.clever_jqgrid_actions;}

如果行数据包含了按钮HTML文本,则删除数据的这个属性
                $(gridId).getGridParam('editfunc')(id, data);

使用getGridParam方法调用当点击了编辑按钮时的回调方法。
ok,至此,在_Layout.cshtml中的故事就讲完了,接下来我们来看看在实际使用的页面中是如何编码的:
@{ViewBag.Title = "Index";
}
@section header{<script type="text/javascript">$(function () {$('#list').jqGrid({url: '@Url.Action("Index", "User")',colNames: ['Primary Key', 'User Name', 'Email', $.jgrid.defaults.colActionsTitle],colModel: [{ name: 'ID', index: 'ID', width: 1, hidden: true, key: true },{ name: 'Name', index: 'Name', width: 100, align: 'left' },{ name: 'Mail', index: 'Mail', width: 100, align: 'left' },{ name: $.jgrid.defaults.cleverjqgridactions, width: 80, fixed: true, sortable: false, resize: false, formatter: cleverActions }],sortname: 'Name',multiselect: true,editfunc: function (id, data) {alert(id);},delfunc: function (id, data) {alert(id);}});});</script>
}
<div id="gridview"><table id="list"></table><div id="pager"></div>
</div>

有了_Layout.cshtml中的代码,这个页面上的代码就少多了,至少看起来不那么吓人了,照例来讲讲参数吧:
//地球人都知道,这是请求数据的url
url: '@Url.Action("Index", "User")',
//显示用的表头数据,$.jgrid.defaults.colActionsTitle本来的用途是显示"操作"两个字,但是不见得我在每个视图的资源文件中都定义吧,所以还是定义在_Layout.cshtml中,这样使用js的方式调用好可
colNames: ['Primary Key', 'User Name', 'Email', $.jgrid.defaults.colActionsTitle],
//定义数据列
colModel: [{ 
//列名
name: 'ID',
//排序时的键
index: 'ID',
//宽度,应该是px单位
width: 1, 
//隐藏
hidden: true,
//标示主键列
key: true },{ name: 'Name', index: 'Name', width: 100, align: 'left' },{ name: 'Mail', index: 'Mail', width: 100, align: 'left' },{ name: $.jgrid.defaults.cleverjqgridactions, width: 80, fixed: true, sortable: false, resize: false, formatter: cleverActions }],
//默认使用Name列排序
sortname: 'Name',
//是否允许多选,这个选项为true,则前面会加上一个全是checkbox的列,作用不用我多说了吧
multiselect: true,
//自定义formatter中编辑按钮的回调方法,id是本行的主键值,data是本行的所有数据
editfunc: function (id, data) {alert(ids);},
//自定义formatter中删除按钮的回调方法
delfunc: function (id, data) {alert(ids);}
有了这些差不多jqGrid就能很好的工作起来了,但是服务端的数据处理起来也够麻烦的,think8848一向作人厚道,因此专门写了两个助手类,专为jqGrid提供格式化的数据:
    /// <summary>/// 分页排序助手类/// </summary>public static class DataPagingHelper{public static IQueryable<T> GetQueryable<T>(this IList<T> list, string sidx, string sord, int page, int rows){return GetQueryable<T>(list.AsQueryable<T>(), sidx, sord, page, rows);}public static IQueryable<T> GetQueryable<T>(this IQueryable<T> queriable, string sidx, string sord, int page, int rows){var data = ApplyOrder<T>(queriable, sidx, sord.ToLower() == "asc" ? true : false);return data.Skip<T>((page - 1) * rows).Take<T>(rows);}private static IOrderedQueryable<T> ApplyOrder<T>(IQueryable<T> queriable, string property, bool isASC){PropertyInfo pi = typeof(T).GetProperty(property);ParameterExpression arg = Expression.Parameter(typeof(T), "x");Expression expr = Expression.Property(arg, pi);Type delegateType = typeof(Func<,>).MakeGenericType(typeof(T), pi.PropertyType);LambdaExpression lambda = Expression.Lambda(delegateType, expr, arg);string methodName = isASC ? "OrderBy" : "OrderByDescending";object result = typeof(Queryable).GetMethods().Single(method => method.Name == methodName&& method.IsGenericMethodDefinition&& method.GetGenericArguments().Length == 2&& method.GetParameters().Length == 2).MakeGenericMethod(typeof(T), pi.PropertyType).Invoke(null, new object[] { queriable, lambda });return (IOrderedQueryable<T>)result;}}/// <summary>/// jqGrid数据处理助手类/// </summary>public static class JqGridHelper{public static JsonResult GetJson<T>(this IList<T> datas, string sidx, string sord, int page, int rows, JsonRequestBehavior behavior, params string[] fields){return GetJson<T>(datas.AsQueryable<T>(), sidx, sord, page, rows, behavior, fields);}public static JsonResult GetJson<T>(this IQueryable<T> queriable, string sidx, string sord, int page, int rows, JsonRequestBehavior behavior, params string[] fields){var data = queriable.GetQueryable<T>(sidx, sord, page, rows);var json = new JsonResult();json.JsonRequestBehavior = behavior;if (rows != 0){var totalpages = (decimal)queriable.Count<T>() / (decimal)rows;totalpages = (totalpages == (int)totalpages) ? totalpages : (int)totalpages + 1;var rowsData = GetJsonData<T>(data, fields);json.Data = new{page,records = rows,total = (int)totalpages,rows = rowsData};}return json;}private static object[] GetJsonData<T>(IQueryable<T> queriable, params string[] fields){var properties = typeof(T).GetProperties(BindingFlags.Instance | BindingFlags.Public);T[] datas = queriable.ToArray<T>();object[] result = new object[datas.Length];if (fields.Length == 0){fields = Array.ConvertAll<PropertyInfo, string>(properties.Where<PropertyInfo>(x => x.GetCustomAttributes(typeof(InternalAttribute), false).Length == 0).ToArray<PropertyInfo>(), delegate(PropertyInfo p){return p.Name;});}for (int i = 0; i < datas.Length; i++){object[] values = new object[fields.Length];for (int j = 0; j < fields.Length; j++){var pi = properties.First<PropertyInfo>(x => x.Name == fields[j]);var value = pi.GetValue(datas[i], null);values[j] = value != null ? value.ToString() : "";}result[i] = new { id = i, cell = values };}return result;}}/// <summary>/// 本人项目中使用的,不用深究/// </summary>[AttributeUsage(AttributeTargets.Property)]public class InternalAttribute : Attribute { }

有了这两个助手类,我们再来看提供数据的服务是啥样的:
    public class UserController : Controller{//// GET: /User/public ActionResult Index(string sidx, string sord, int page, int rows){var users = new List<User>();users.Add(new User() { ID = Guid.NewGuid(), Name = "think8848", Mail = "think8848@csdn.net", Password = "abcdefg" });users.Add(new User() { ID = Guid.NewGuid(), Name = "a", Mail = "a@csdn.net", Password = "abcdefg" });users.Add(new User() { ID = Guid.NewGuid(), Name = "b", Mail = "b@csdn.net", Password = "abcdefg" });//...users.Add(new User() { ID = Guid.NewGuid(), Name = "y", Mail = "y@csdn.net", Password = "abcdefg" });users.Add(new User() { ID = Guid.NewGuid(), Name = "z", Mail = "z@csdn.net", Password = "abcdefg" });return users.GetJson<User>(sidx, sord, page, rows, JsonRequestBehavior.AllowGet, new string[] { "ID", "Name", "Mail" });}}

User实体定义:
    public class User{public Guid ID { get; set; }public string Name { get; set; }public string Password { get; set; }public string Mail { get; set; }}

必须得完结了,我的脚被蚊子要抬走了...
效果图:

转载于:https://www.cnblogs.com/think8848/archive/2011/07/15/2107828.html

[原]ASP.NET MVC 3 Razor + jqGrid 示例相关推荐

  1. ASP.NET MVC 自定义Razor视图WorkContext

    概述 1.在ASP.NET MVC项目开发的过程中,我们经常需要在cshtml的视图层输出一些公用信息 比如:页面Title.服务器日期时间.页面关键字.关键字描述.系统版本号.资源版本号等 2.普通 ...

  2. ASP.NET MVC:Razor 引入命名空间

    原文:ASP.NET MVC:Razor 引入命名空间 页面中引用 c# @using MvcApplication83.Models @using MvcApplication83.Common 行 ...

  3. ASP.NET MVC 3 Razor 多国语言参考解决方案 补充四

    ASP.NET MVC 3 Razor 多国语言参考解决方案 补充四 转自 http://www.cnblogs.com/think8848/archive/2011/07/05/2098464.ht ...

  4. ASP.NET MVC 3: Razor视图引擎中 @: 和text 语法【转载】

    ASP.NET MVC 3: Razor视图引擎中 @: 和<text> 语法[转载] (文章没翻译:建议大家读英文原文,看不懂查着看,顺便提高自己的英语水平!) In today's p ...

  5. ASP.NET MVC的Razor引擎:IoC在View激活过程中的应用

    在<ASP.NET MVC的Razor引擎:RazorView>介绍BuildManagerCompiledView的时候,我们谈到默认使用的ViewPageActivator使用当前注册 ...

  6. ASP.NET MVC 利用Razor引擎生成静态页

    实现原理及步骤: 1.通过ViewEngines.Engines.FindView查找到对应的视图,如果是部分视图,则用:ViewEngines.Engines.FindPartialView: 2. ...

  7. ASP.NET MVC 3 Razor基础语法

    Razor的出现,使页面看起更加简洁,Razor的页面后缀为:.cshtml Razor基础语法: 1.代码注释:       多行注释: @*注释信息*@      单行注释: // 注释 1.代码 ...

  8. ASP.NET MVC SportStore 购物网示例(6)

    定义一个订单提供 IoC 组件 在DomainModel项目中新建文件夹Services添加以下接口: namespace DomainModel.Services { public interfac ...

  9. Asp.net MVC在Razor中输出Html的两种方式

    http://qubernet.blog.163.com/blog/static/177947284201485104616368/ Razor中所有的Html都会自动编码,这样就不需要我们手动去编码 ...

  10. ASP.NET MVC (Razor)开发 周报与绩效考核系统 总结与分享

    最新版地址:http://sheng.city/post/and-and 这个周报系统大约写于2015年,缘起当时所带的开发团队需要逐步建立或完善一些项目管理方法. 在调研了网上的诸多项目管理或周报/ ...

最新文章

  1. Edit Control读取与写入踩坑实例与使用方法
  2. 在线生成 CSS3 的工具
  3. Interview:算法岗位面试—10.15下午—上海某公司算法岗位(偏机器学习,合资制造行业)技术面试考点之电话面试—研究项目的技术考察
  4. 管道无损检测python_武汉哪里有便携式X射线探伤机使用方法欢迎咨询
  5. 【PAT甲级 stack queue的使用】1051 Pop Sequence (25 分) C++ 全部AC
  6. python3.7安装pyqt4_Windows下PyQt4的安装(本文已过期)
  7. 自定义用户控件的使用
  8. 【蓝桥杯单片机】IAP15在线仿真实验:Connecting to target system lost!please reset your target system and try again
  9. caffe测试单张图片
  10. python菜鸟编程-Python 基础教程 | 菜鸟教程
  11. “软件工程造价师”和“软件造价评估师”有什么区别?
  12. 计算机无法写入U盘,电脑无法拷贝U盘文件怎么办|解除U盘写保护设置的方法
  13. boost/mpl/assert.hpp:189:21: error: unnecessary parentheses in declaration of ‘assert_arg‘ [-Werror=
  14. 如何设置Google浏览器支持跨域
  15. matlab变量命名中文,Matlab变量及命名规则
  16. 运用Python 模拟太阳-地球-月亮运动模型
  17. 买卖股票的最佳时机——力扣121题
  18. hdfs大概流程和命令操作
  19. XSS漏洞原理及攻击
  20. webpackvue-cli快速构建

热门文章

  1. 47. 避免产生直写型(write-only)的代码
  2. mysql 主从库_MySQL数据库之mysql 主库有数据通过锁库做主从
  3. oracle tochar fm,oracle的to_char中的fm-Oracle
  4. linux ipc 信号量,linux ipc信号量
  5. Java进阶:SpringMVC数据请求全局过滤器
  6. 爬虫:Python爬虫学习笔记之爬虫基础
  7. 三实系统地址是什么意思_终于明白!火灾报警系统的余量应该如何设置?地址数又是什么?...
  8. SLAM_2019-ICCV_GSLAM:通用 SLAM 框架和基准
  9. SLAM_kitti数据集求相机cam2到IMU的变换矩阵
  10. 图像语义分割(6)-RefineNet:用于高分辨率图像语义分割的带有恒等映射的多路精细网络