使用MVCJqGrid
使用MVCJqGrid的心得
最近公司网站进行升级,项目要用.net mvc,mysql和轻量级orm框架dapper。由于美工页面出不来啊,让我先写简单写写后台的列表,同事说用MvcJqGrid,也得到了架构的同意。
可是不得不说这个相关文档真不多啊,以前用过jqgrid,但是早忘透了。其实MVCJqGrid这个东西是一个HtmlHelper扩展。不多说,先来看看这个东西吧。
文档的参考地址 http://mvcjqgrid.skaele.it/
下载地址 https://github.com/robinvanderknaap/MvcJqGrid
首先项目中应该添加MvcJqGrid引用。
view视图引用@using MvcJqGrid;
因为jqgrid相对配置麻烦,所以有了MvcJqGrid,使用起来也是简单明了:
@(Html.Grid("search") //设置jqgrid容器,search就是其ID
.SetCaption("Toolbar Search") //设置主标题
.AddColumn(new Column("ID") //添加一列(对应数据集合的列名)
.SetLabel("Id")) //设置列标题
.AddColumn(new Column("NickName"))
.AddColumn(new Column("MobilePhone")
.SetUrl("/Home/GetPagedList_User") //请求数据的地址
.SetAutoWidth(true) //自动宽度
.SetRowNum(10) //每页条数
.SetRowList(new[] { 10, 15, 20 }) //设置可选每页页数
.SetViewRecords(true) //设置显示条数
.SetPager("pager")) //设置分页,pager就是分页容器ID
这样一个简单的列表分页页面前台展示就出来了。
后台取数据简单的这种套路:
public JsonResult GetPagedList_User( GridSettings gridSettings)
{
//参数分别为排序字段,排序方式,当前页,每页条数
List<T> list=获取分页列表(gridSettings.SortColumn, gridSettings.SortOrder, gridSettings.PageIndex, gridSettings.PageSize)
if(list==null)
return Json(new{total=0,page=0,records=0,rows=("")}, JsonRequestBehavior.AllowGet);
var jsonData = new
{
total = 获取总条数(),
page =total / gridSettings.PageSize + 1;,
records = content.TotalCount,
rows = (
from c in list
select new
{
id = c.ID,
cell = new[]
{
c.ID.ToString(),
c.NickName,
c.MobilePhone,
......
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
展示列表其实很简单,但是查询的时候遇到了麻烦。因为google很多示例都是使用EF这样的操作的,例如:
if (gridSettings.IsSearch)
{
name = gridSettings.Where.rules.Any(r => r.field == "Name") ?
gridSettings.Where.rules.FirstOrDefault(r => r.field == "Name").data : string.Empty;
company = gridSettings.Where.rules.Any(r => r.field == "Company") ?
gridSettings.Where.rules.FirstOrDefault(r => r.field == "Company").data : string.Empty;
}
CustomerRepository repository = new CustomerRepository();
var customers = repository.List(name, company, gridSettings.SortColumn, gridSettings.SortOrder);
乍一看看不明觉厉啊。而当需要手写查询,或者用刀轻量级orm框架需要写sql语句时,就有些手足无措了。
索性通过浏览器f12查看网站示例的请求,发现类似这种参数filters=%7B%22groupOp%22%3A%22AND%22%2C%22rules%22%3A%5B%7B%22field%22%3A%22Last+Modified%22%2C%22op%22%3A%22bw%22%2C%22data%22%3A%2208-11-2013%22%7D%5D%7D,经解码得到{"groupOp":"AND","rules":[{"field":"Last+Modified","op":"bw","data":"08-11-2013"}]}。
后来又看其源码,其实filters就是一个过滤条件类,rules是rule类的集合就是匹配的查询条件,rule类有三个属性field,op,data,意思呢就是字段名,查询方式?,值。其实有这三个就够写sql语句了。例如“select * from user where”+ rule.filed+rule.op+rule.data。
op属性目前有14个查询方式,例如:等于,不等于,小于...包含某值,以某值结束等等。这里拼接rule.op字符串要对此查询方式进行解析。
但是这里问题出来了,没有时间范围查询。
这里我找到他的MvcJqGrid.Enums下的SearchOptions枚举,添加一个RangeDate,表示时间范围。然后在用到此枚举的地方加上。MvcJqGrid下的Column类public Column SetSearchOption方法,它是设置搜索条件的方法,我们在最后添加:
好了,到现在可以了解到查询方式基本有了,但是目前来说MvcJqgrid提供的日期查询js插件是DatePicker,好像没有时间查询。于是我找到了一个好用的东西—>daterangepicker.js
下载地址:https://github.com/dangrossman/bootstrap-daterangepicker
打开一看英文的展示啊,于是我用了最笨最直接的方法,直接修改它源文件。实例中需要引用moment.min.js,和主文件daterangepicker.js。前者是一个日期处理类库,直接找到_month和_weekdays关键字,对应后面字符串Jan_Feb_Mar_Apr_......修改成一月_二月_...你懂得,Sun_Mon_Tue_...改成星期日_星期一_...注意文件保存格式应为Unicode,要不有乱码。daterangepicker我也把能看懂的展示的文字改成了中文,另外精简了下它的展示方式。看起来还不错的样子:
好了,现在就是两者关联了,直接在MvcJqgrid类库中搜索DatePicker关键字,于是又在Column类中第585行找到了,代码如下:
// SearchType datepicker
if (_searchType == Searchtype.Datepicker)
{
if (_searchDateFormat.IsNullOrWhiteSpace())
script.Append(
", dataInit:function(el){$(el).datepicker({changeYear:true, onSelect: function() {var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();},dateFormat:'dd-mm-yy'});}");
else
script.Append(
", dataInit:function(el){$(el).datepicker({changeYear:true, onSelect: function() {var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();},dateFormat:'" +
_searchDateFormat + "'});}");
}
看不太明白,只知道有个回调函数onSelect,这里估计就是要触发Jqgrid的查询事件了,但是确定按钮(未修改前叫Apply)daterangepicker中貌似没有事件啊。只能为它添加一个:
var DateRangePicker = function (element, options, cb) {
var hasOptions = typeof options == 'object';
......
this.cb = function () { };
//添加onApplyClick回调函数,用于jqgrid获取事件
this.onApplyClick = function () { };
...... //event listeners(找到它,在下面添加一句)
if (typeof options.onApplyClick == 'function') {
//此处为调用确定按钮回调
this.container.find('.ranges').on('click', 'button.applyBtn', options.onApplyClick);
}
......
}
然后修改Column类下的这里部分
// SearchType datepicker
if (_searchType == Searchtype.Datepicker)
{
if (_searchDateFormat.IsNullOrWhiteSpace())
script.Append(
",dataInit:function(el){$(el).daterangepicker({onApplyClick:function(){var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();}});}");
else
script.Append(
",dataInit:function(el){$(el).daterangepicker({format:'" + _searchDateFormat + "',onApplyClick:function(){var sgrid = $('###gridid##')[0]; sgrid.triggerToolbar();}});}");
}
好了。准备工作完了。下面要有一个通用的模板才行。我在MvcJqgrid类库中加入了一个文件夹,名字叫MyExtend。
首先需要一个枚举来标识查询的字段是不是可以用引号的(当然我的理解很粗俗)。OptionType:
其次通过前面说过的后台列表代码,我们知道其实应该有四个属性,列表List<T>,当前页PageIndex,总条数TotalCount,总页数TotalPage。于是起了个名字叫GridContent的实体类:
然后就是我们要提取出来一个接口,作为获取根据条件查询的数据列表和根据条件查询的总条数。起了名字叫ICanSetGrid:
最后就是主要的了,起名为JqGridHelper:
下面是例子,首先是相关Bll层的操作类实现ICanSetGrid<T>,两个方法对应Dao层的方法应该不难吧,这里举个栗子:
然后是Controller中的例子了:
public JsonResult GetPagedList_User( GridSettings gridSettings)
{
GridContent<UserInfo> content = JqGridHelper.GetGridContent<UserInfo>(gridSettings, UserInfoBll.CreateInstance());
if(content.GList==null)
return Json(new{total=0,page=0,records=0,rows=("")}, JsonRequestBehavior.AllowGet);
var jsonData = new
{
total = content.TotalPage,
page = content.PageIndex,
records = content.TotalCount,
rows = (
from c in content.GList
select new
{
id = c.UserID,
cell = new[]
{
c.UserID.ToString(),
c.NickName,
c.Phone,
c.EMail,
c.LastLoginTime.ToString("yyyy-MM-dd HH:mm"),
c.isAct==1?"激活":"未激活",
}
}).ToArray()
};
return Json(jsonData, JsonRequestBehavior.AllowGet);
}
最后来看下页面展示吧:
@using MvcJqGrid;
@{
ViewBag.Title = "UserList";
}
<link href="~/Content/jqgrid/css/jquery-ui-custom.min.css" rel="stylesheet" />
<link href="~/Content/jqgrid/css/ui.jqgrid.css" rel="stylesheet" />
<link href="~/Content/bootstrap/css/bootstrap.min.css" rel="stylesheet" />
<link href="~/Content/daterangepicker/css/daterangepicker-bs3.css" rel="stylesheet" /> <script src="~/Scripts/jquery-1.8.3.min.js"></script>
<script src="~/Content/jqgrid/js/grid.locale-cn.js"></script>
<script src="~/Content/jqgrid/js/jquery.jqGrid.min.js"></script>
<script src="~/Content/daterangepicker/js/moment.min.js" charset="utf-8"></script>
<script src="~/Content/daterangepicker/js/daterangepicker.js"></script> <h2>用户列表</h2> @(Html.Grid("UserGrid")//定义容器ID
.SetCaption("用户列表")//设置标题
.AddColumn(new Column("UserID").SetLabel("ID").SetSearch(false))
.AddColumn(new Column("NickName").SetLabel("昵称").SetSearchOption(MvcJqGrid.Enums.SearchOptions.Contains))
.AddColumn(new Column("Phone").SetLabel("手机号").SetSearchOption(MvcJqGrid.Enums.SearchOptions.Contains))
.AddColumn(new Column("EMail").SetLabel("邮箱").SetSearchOption(MvcJqGrid.Enums.SearchOptions.Contains))
.AddColumn(new Column("LastLoginTime").SetLabel("最后登录时间").SetSearchType(MvcJqGrid.Enums.Searchtype.Datepicker).SetSearchOption(MvcJqGrid.Enums.SearchOptions.RangeDate))
.AddColumn(new Column("isAct").SetLabel("是否激活").SetSearchType(MvcJqGrid.Enums.Searchtype.Select).SetSearchTerms(new Dictionary<string, string>() { {"0","未激活"},{"1","激活"}}).SetSearchOption(MvcJqGrid.Enums.SearchOptions.Equal))
.SetUrl(Url.Action("GetPagedList_User", "UserInfo")).SetRowNumbers(true)//设置取数据的地址
.SetSortName("UserID")//默认排序
.SetAutoWidth(true)
.SetHeight(450)
.SetRowNum(10)//设置每页条数
.SetRowList(new[] { 10, 15, 20 })//可选择每页条数
.SetViewRecords(true)//显示条数
.SetSearchToolbar(true).SetSearchOnEnter(true)//设置可以搜索
.SetPager("pager")//设置分页
.SetLoadText("请等待")
.SetMultiSelect(true)
.SetToolbar(true).SetToolbarPosition(MvcJqGrid.Enums.ToolbarPosition.Bottom)
)
好了,大概就是这么个样子。数据库拼接字符串查询确实不太好,我再看看别的方法。
另外bootstrap是个好东西啊,建议大家看看。
使用MVCJqGrid的更多相关文章
- 使用MVCJqGrid的心得
最近公司网站进行升级,项目要用.net mvc,mysql和轻量级orm框架dapper.由于美工页面出不来啊,让我先写简单写写后台的列表,同事说用MvcJqGrid,也得到了架构的同意. 可是不得不 ...
- csharp: using HtmlAgilityPack and ScrapySharp reading Url find text
https://github.com/exaphaser/ScrapySharp https://github.com/zzzprojects/html-agility-pack https://gi ...
随机推荐
- Android复制WIN8点击下沉倾斜系统瓷砖效果
※效果 ※使用说明 Java代码 import android.app.Activity; import android.os.Bundle; import android.widget.Toast; ...
- Nyoj 虚拟的城市之旅(bfs)
描述 展馆是未来城市的缩影,个人体验和互动是不变的主题.在A国展馆通过多维模式和高科技手段,引领参观者在展示空间踏上一段虚拟的城市之旅. 梦幻国有N个城市和M条道路,每条道路连接某两个城市.任意两 ...
- 华为OJ: 公共字符串计算
有几个需要注意的地方,这个问题是不是大写和小写之间的区别.这样你就输入字符串大写或小写转换的计算前. 第二个,定要清晰.先将s1从[i]处開始与s2的[j]開始匹配,不相等则j++直到j等于s2.le ...
- MVC中,视图的Layout使用
本文目标 1.能够重用Razor模板进行页面的组件化搭建 本文目录 1.母板页_Layout.cshtml 2.用户自定义控件 3.默认Layout引用的使用(_ViewStart.cshtml) 1 ...
- C#关于HttpClient的应用(二):极光推送IM集成
public class JPushClient:BaseHttpClient { private String appKey; private String masterSecret; public ...
- 浅谈JavaScript中继承的实现
谈到js中的面向对象编程,都有一个共同点,选择原型属性还是构造函数,两者各有利弊,而就片面的从js的对象创建以及继承的实现两个方面来说,官方所推荐的是两个相结合,各尽其责,各取其长,在前面的例子中,我 ...
- Meteor入门
转载Meteor入门介绍 Meteor是什么 基于nodejs的实时web APP开发框架. Meteor能带来什么 简单的说,你可以用js搞定客户端.服务端的开发.另外,客户端.服务端的界限被极 ...
- POJ 3373 Changing Digits 好蛋疼的DP
一開始写的高位往低位递推,发现这样有些时候保证不了第四条要求.于是又開始写高位往低位的记忆化搜索,又发现传參什么的蛋疼的要死.然后又发现高位開始的记忆化搜索就是从低位往高位的递推呀,遂过之. dp[i ...
- Coreseek/sphinx全文检索的了解
Coreseek/sphinx全文检索的了解 概述: 全文检索是一种将文件里全部文本与检索项匹配的文字资料检索方法,全文检索是将存储于数据库中整本书.整篇文章中的随意内容信息查找出来的检索.它能够依据 ...
- centos6的安装,一步一图,有图有真相
打开虚拟机VMware,点击文件,选择[新建虚拟机],如图所示