第一次看到ACE模板,有种感动,有种相见恨晚的感觉,于是迅速来研究。它本身是基于bootstrap和jqueryui,但更nice,整合之后为后台开发节省了大量时间。 发现虽然不是完美,整体效果还是不错,特此分享给园友。这一节先讲其中的Jqgrid。按照国际惯例,先上两张图。
集成了button,form,treeview以及日历,时间轴、chart等控件,非常丰富。下面是Jqgrid在MVC中的使用。
jqgrid的加载,排序,查找都是基于后台方法,不是在内存中完成,但也有一些小坑。下面一一道来。
一、引入ace模板
ace本身考虑了对ie的兼容,加上bootstrap和jqueryui所以引入的样式和脚本文件比较多。我拿掉了一下googlefont的链接,请求太慢了,你懂的。现在MVC最关心的就是RenderBody的位置。在page-content下的Row,也可以将page-header放入子页面中去,自己多写几个元素,这个就在于你自己的选择了。
<div class="page-content"> <div class="page-header"> <h1> <span>控制台span> <small> <i class="icon-double-angle-right">i> <span>查看span> small> h1> div> <div class="row"> <div class="col-xs-12"> @RenderBody() div> div> div>
全部的layout.cshtml

DOCTYPE html>
<html >
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>@ViewBag.Titletitle>
<link href="~/Content/CSS/bootstrap.min.css" rel="stylesheet" />
<link rel="stylesheet" href="~/Content/CSS/font-awesome.min.css" />
<script src="~/Content/Js/jquery-2.0.3.min.js">script>
<link href="~/Content/CSS/niqiu.css" rel="stylesheet" />
<link rel="stylesheet" href="~/Content/CSS/ace.min.css" />
<link rel="stylesheet" href="~/Content/CSS/ace-rtl.min.css" />
<link rel="stylesheet" href="~/Content/CSS/ace-skins.min.css" />
<script src="~/Content/Js/ace-extra.min.js">script>
head>
<body>
<div class="navbar navbar-default" id="navbar">
<script type="text/javascript">
try { ace.settings.check('navbar', 'fixed') } catch (e) { }
script>
<div class="navbar-container" id="navbar-container">
<div class="navbar-header pull-left">
<a href="#" class="navbar-brand">
<small>
<i class="icon-leaf">i>
XiaoNao Admin
small>
a>
div>
<div class="navbar-header pull-right" role="navigation">
<ul class="nav ace-nav">
<li class="green">
<a data-toggle="dropdown" class="dropdown-toggle" href="#">
<i class="icon-envelope icon-animated-vertical">i>
<span class="badge badge-success">5span>
a>
<ul class="pull-right dropdown-navbar dropdown-menu dropdown-caret dropdown-close">
<li class="dropdown-header">
<i class="icon-envelope-alt">i>
5 Messages
li>
<li>
<a href="#">
<img src="~/Content/avatars/avatar.png" class="msg-photo" alt="Alex's Avatar" />
<span class="msg-body">
<span class="msg-title">
<span class="blue">Alex:span>
Ciao sociis natoque penatibus et auctor ...
span>
<span class="msg-time">
<i class="icon-time">i>
<span>a moment agospan>
span>
span>
a>
li>
<li>
<a href="#">
<img src="~/Content/avatars/avatar3.png" class="msg-photo" alt="Susan's Avatar" />
<span class="msg-body">
<span class="msg-title">
<span class="blue">Susan:span>
Vestibulum id ligula porta felis euismod ...
span>
<span class="msg-time">
<i class="icon-time">i>
<span>20 minutes agospan>
span>
span>
a>
li>
<li>
<a href="#">
<img src="~/Content/avatars/avatar4.png" class="msg-photo" alt="Bob's Avatar" />
<span class="msg-body">
<span class="msg-title">
<span class="blue">Bob:span>
Nullam quis risus eget urna mollis ornare ...
span>
<span class="msg-time">
<i class="icon-time">i>
<span>3:15 pmspan>
span>
span>
a>
li>
<li>
<a href="#">
See all messages
<i class="icon-arrow-right">i>
a>
li>
ul>
li>
<li class="light-blue">
<a data-toggle="dropdown" href="#" class="dropdown-toggle">
<img class="nav-user-photo" src="~/Content/avatars/user.jpg" alt="Jason's Photo" />
<span class="user-info">
@if( Session["uname"]!=null){
<small>Welcome,small>
@Session["uname"].ToString();
}
span>
<i class="icon-caret-down">i>
a>
<ul class="user-menu pull-right dropdown-menu dropdown-yellow dropdown-caret dropdown-close">
<li>
<a href="#">
<i class="icon-cog">i>
Settings
a>
li>
<li>
<a href="#">
<i class="icon-user">i>
Profile
a>
li>
<li class="divider">li>
<li>
<a href="@Url.Action("LogOff","User")">
<i class="icon-off">i>
Logout
a>
li>
ul>
li>
ul>
div>
div>
div>
<div class="main-container" id="main-container">
<script type="text/javascript">
try { ace.settings.check('main-container', 'fixed') } catch (e) { }
script>
<div class="main-container-inner">
<a class="menu-toggler" id="menu-toggler" href="#">
<span class="menu-text">span>
a>
<div class="sidebar" id="sidebar">
<script type="text/javascript">
try { ace.settings.check('sidebar', 'fixed') } catch (e) { }
script>
<div class="sidebar-shortcuts" id="sidebar-shortcuts">
<div class="sidebar-shortcuts-large" id="sidebar-shortcuts-large">
<button class="btn btn-success">
<i class="icon-signal">i>
button>
<button class="btn btn-info">
<i class="icon-pencil">i>
button>
<button class="btn btn-warning">
<i class="icon-group">i>
button>
<button class="btn btn-danger">
<i class="icon-cogs">i>
button>
div>
<div class="sidebar-shortcuts-mini" id="sidebar-shortcuts-mini">
<span class="btn btn-success">span>
<span class="btn btn-info">span>
<span class="btn btn-warning">span>
<span class="btn btn-danger">span>
div>
div>
<ul class="nav nav-list">
<li class="active">
<a href="@Url.Action("Index","Admin")">
<i class="icon-dashboard">i>
<span class="menu-text"> 控制台 span>
a>
li>
<li>
<a href="#" class="dropdown-toggle">
<i class="icon-list">i>
<span class="menu-text"> 产品 span>
<b class="arrow icon-angle-down">b>
a>
<ul class="submenu">
<li>
<a href="@Url.Action("Index","Product")">
<i class="icon-double-angle-right">i>
产品管理
a>
li>
<li>
<a href="@Url.Action("CategoryList","Product")">
<i class="icon-double-angle-right">i>
分类管理
a>
li>
ul>
li>
<li>
<a href="#" class="dropdown-toggle">
<i class="icon-desktop">i>
<span class="menu-text"> 用户 span>
<b class="arrow icon-angle-down">b>
a>
<ul class="submenu">
<li>
<a href="@Url.Action("Index","User")">
<i class="icon-double-angle-right">i>
用户管理
a>
li>
<li>
<a href="@Url.Action("EditInfo","User")">
<i class="icon-double-angle-right">i>
个人设置
a>
li>
ul>
li>
ul>
<div class="sidebar-collapse" id="sidebar-collapse">
<i class="icon-double-angle-left" data-icon1="icon-double-angle-left" data-icon2="icon-double-angle-right">i>
div>
<script type="text/javascript">
try { ace.settings.check('sidebar', 'collapsed') } catch (e) { }
script>
div>
<div class="main-content">
<div class="breadcrumbs" id="breadcrumbs">
<script type="text/javascript">
try { ace.settings.check('breadcrumbs', 'fixed') } catch (e) { }
script>
<ul class="breadcrumb">
<li>
<i class="icon-home home-icon">i>
<a href="@Url.Action("Index","Admin")">Homea>
li>
<li id="currentpart" class="active">控制台li>
ul>
<div class="nav-search" id="nav-search">
<form class="form-search">
<span class="input-icon">
<input type="text" placeholder="Search ..." class="nav-search-input" id="nav-search-input" autocomplete="off" />
<i class="icon-search nav-search-icon">i>
span>
form>
div>
div>
<div class="page-content">
<div class="page-header">
<h1>
<span>控制台span>
<small>
<i class="icon-double-angle-right">i>
<span>查看span>
small>
h1>
div>
<div class="row">
<div class="col-xs-12">
@RenderBody()
div>
div>
div>
div>
<div class="ace-settings-container" id="ace-settings-container">
<div class="btn btn-app btn-xs btn-warning ace-settings-btn" id="ace-settings-btn">
<i class="icon-cog bigger-150">i>
div>
<div class="ace-settings-box" id="ace-settings-box">
<div>
<div class="pull-left">
<select id="skin-colorpicker" class="hide">
<option data-skin="default" value="#438EB9">#438EB9option>
<option data-skin="skin-1" value="#222A2D">#222A2Doption>
<option data-skin="skin-2" value="#C6487E">#C6487Eoption>
<option data-skin="skin-3" value="#D0D0D0">#D0D0D0option>
select>
div>
<span> Choose Skinspan>
div>
<div>
<input type="checkbox" class="ace ace-checkbox-2" id="ace-settings-navbar" />
<label class="lbl" for="ace-settings-navbar"> Fixed Navbarlabel>
div>
<div>
<input type="checkbox" class="ace ace-checkbox-2" id="ace-settings-sidebar" />
<label class="lbl" for="ace-settings-sidebar"> Fixed Sidebarlabel>
div>
<div>
<input type="checkbox" class="ace ace-checkbox-2" id="ace-settings-breadcrumbs" />
<label class="lbl" for="ace-settings-breadcrumbs"> Fixed Breadcrumbslabel>
div>
<div>
<input type="checkbox" class="ace ace-checkbox-2" id="ace-settings-rtl" />
<label class="lbl" for="ace-settings-rtl"> Right To Left (rtl)label>
div>
<div>
<input type="checkbox" class="ace ace-checkbox-2" id="ace-settings-add-container" />
<label class="lbl" for="ace-settings-add-container">
Inside
<b>.containerb>
label>
div>
div>
div>
div>
<a href="#" id="btn-scroll-up" class="btn-scroll-up btn btn-sm btn-inverse">
<i class="icon-double-angle-up icon-only bigger-110">i>
a>
div>
<script type="text/javascript">
if ("ontouchend" in document) document.write("" + "<" + "/script>");
script>
<script src="~/Content/Js/bootstrap.min.js">script>
<script src="~/Content/Js/typeahead-bs2.min.js">script>
<script src="~/Content/Js/jquery-ui-1.10.3.custom.min.js">script>
<script src="~/Content/Js/jquery.ui.touch-punch.min.js">script>
<script src="~/Content/Js/bootbox.min.js">script>
<script src="~/Content/Js/ace-elements.min.js">script>
<script src="~/Content/Js/ace.min.js">script>
<script type="text/javascript">
jQuery(function ($) {
/* initialize the external events
-----------------------------------------------------------------*/
$('#external-events div.external-event').each(function () {
// create an Event Object (http://arshaw.com/fullcalendar/docs/event_data/Event_Object/)
// it doesn't need to have a start or end
var eventObject = {
title: $.trim($(this).text()) // use the element's text as the event title
};
// store the Event Object in the DOM element so we can get to it later
$(this).data('eventObject', eventObject);
// make the event draggable using jQuery UI
$(this).draggable({
zIndex: 999,
revert: true, // will cause the event to go back to its
revertDuration: 0 // original position after the drag
});
});
/* initialize the calendar
-----------------------------------------------------------------*/
})
script>
<div style="display:none"><script src='http://v7.cnzz.com/stat.php?id=155540&web_id=155540' language='JavaScript' charset='gb2312'>script>div>
<script src="~/Content/Js/niqiu.js">script>
@RenderSection("scripts", required: false)
body>html>
二、引入Jqgrid
如果你的表格比较多,建议你做一个分部试图,重复利用,我的partview JqgridInit.cshtml 如下,
<link rel="stylesheet" href="~/Content/CSS/ui.jqgrid.css" /> <script src="~/Content/Js/jqGrid/jquery.jqGrid.min.js">script> <script src="~/Content/Js/jqGrid/i18n/grid.locale-en.js">script> <style> #pager2 { height: 40px; } .FormGrid ,#DelTb1_list2{ position: relative; overflow: visible; float: left; } .ui-jqgrid-sortable { height: 30px !important; } style> <table id="list">table> <div id="pager">div> <span class="errorinfo">span>
list用来呈现数据,pager用来分页,errorinfo用来提示错误。jqgrid,涉及的配置比较多。需要后台代码的全面的支持,所以在介绍配置之前,先介绍下模型和仓库。
1.Product: 我们需要呈现的一个是一个产品,有很多不同的价格及其他,这些都将成为表格的列名。

public class Product { ////// Gets or sets the id. /// /// The id. [Key] public int ProductId { get; set; } /// /// 直接做型号处理 /// public string ProductName { get; set; } /// /// Gets or sets the category. /// /// The category. public string Category { get; set; } /// /// Gets or sets the brand. /// /// The brand. public string Brand { get; set; } public string Size { get; set; } /// /// Gets or sets the 规格. /// /// The standard. public string Standard { get; set; } /// /// 专柜 /// public decimal ZhuanGui { get; set; } /// /// Gets or sets the 莎莎 price. /// /// The sa sa price. public decimal SaSaPrice { get; set; } /// /// Gets or sets the 卓越 price. /// /// The zhuoyue price. public decimal ZhuoyuePrice { get; set; } /// /// Gets or sets the 卡莱美 price. /// /// The ka lai price. public decimal KaLaiPrice { get; set; } /// /// 雅施 /// public decimal YaShi { get; set; } /// /// Gets or sets the 万宁 price. /// /// The wanning price. public decimal WanningPrice { get; set; } /// /// Gets or sets the 屈臣氏 price. /// /// The quchengshi price. public decimal QuchengshiPrice { get; set; } /// /// Gets or sets the 药店 price. /// /// The drugstore price. public decimal DrugstorePrice { get; set; } /// /// Gets or sets the others. /// /// The others. public string Others { get; set; } /// /// Gets or sets the create time. /// /// The create time. public DateTime CreateTime { get; set; } public string ImgUrl { get; set; } public Product() { CreateTime = DateTime.Now; } }
2.ProductRepository (仓库真的很好,独立了业务逻辑,可测试,复用快),add、remove、update不用讲了,主要讲一讲排序。
1)排序查询的意义在于根据不同的属性进行排序。
public class ProductRepository:IProductRepository { private readonly XNDb _db = new XNDb(); //.... public IEnumerableFind(string sort = "asc", string property = "ProductName", int skip = 0, int take = 10) { var propertyInfo = typeof(Product).GetProperty(property);//反射出这个属性 Func object> expn = e => propertyInfo.GetValue(e, null);//委托 var rawpros = _db.Products; IEnumerable pros = sort == "asc" ? rawpros.OrderBy(expn).Skip(skip).Take(take).ToArray() : rawpros.OrderByDescending(expn).Skip(skip).Take(take).ToArray();//分页排序 return pros; }
//.... }
在只考虑排序的情况下,控制器的代码就相对简单:
public JsonResult GetAllPros( string sord = "asc", string sidx = "ProductName",int page = 1, int rows = 10) { var pros = _repository.Find(sord, switchSidx(sidx), (page - 1) * rows, rows); var objpros = new List<object>(pros); var jsonData = JqGridModel.GridData(page, rows, _repository.Count, objpros); return Json(jsonData, JsonRequestBehavior.AllowGet); }
如果涉及到复杂些的查询,等于不等于,包含之类的,会多了后面mark部分的参数,这里我用很笨的办法实现了单列查询,也就就是根据包含、等于、不等于先查出来,再排序,如果是多重查询,大家可以参考博客:http://www.codeproject.com/Articles/58357/Using-jqGrid-s-search-toolbar-with-multiple-filter
public JsonResult GetAllPros( string sord = "asc", string sidx = "ProductName",int page = 1, int rows = 10, bool _search = false,string searchField="", string searchOper="", string searchString="") { var rawpros = GetRawPros(_search, searchField, searchOper, searchString); var propertyInfo = typeof(Product).GetProperty(switchSidx(sidx)); Funcobject> expn = e => propertyInfo.GetValue(e, null); var enumerable = rawpros as Product[] ?? rawpros.ToArray(); IEnumerable pros = sord == "asc" ? enumerable.OrderBy(expn).Skip((page - 1) * rows).Take(rows).ToArray() : enumerable.OrderByDescending(expn).Skip((page - 1) * rows).Take(rows).ToArray(); var objpros = new List<object>(pros); var jsonData = JqGridModel.GridData(page, rows, enumerable.Count(), objpros); return Json(jsonData, JsonRequestBehavior.AllowGet); }
需要说明的是,这里的switchsidx就是将中文列名转为对象属性名,一堆case语句,然后JqgridModel的getdata,是jqgrid定义好的一种json格式,包含了每页行数和总页数等信息,因为前段的每页行数是可以变化的。
public class JqGridModel { ////// Grids the data. /// /// 当前页数. /// 每页显示数目. /// /// 集合对象 /// System.Object. public static object GridData(int page1, int rows, int total, IEnumerable<object> objects) { int pageSize = rows; var totalPages = (int)Math.Ceiling((float)total / pageSize); //可根据具体情况,实现排序。 var jsonData = new { total = totalPages, page = page1, records = total, rows = objects.ToArray() }; return jsonData; } }
2)需要一个新增:(记住返回json的时候要allowGet,不然可能造成添加失败,其他地方同理)
[HttpPost] public ActionResult Create(Product product) { _repository.Add(product); var fu = _repository.FindByName(product.ProductName); return Json(fu, JsonRequestBehavior.AllowGet); }
3)编辑和删除:这里的编辑有三个参数,一个对象,一个操作,一个id,id是个鸡肋,居然返回的是table的行号(会随着排序变化),oper可能是add,del,这里我只用到了edit,del传回的id尝试改变它为对象的id,但没成功。用了因外一种方式实现删除。
[HttpPost] public ActionResult Edit(Product pro, string oper, int id) { if (oper == "edit") { _repository.Update(pro); pro.CreateTime = DateTime.Now; } return Json(pro, JsonRequestBehavior.AllowGet); } [HttpPost] public ActionResult Delete(int id) { _repository.Remove(id); return Json(id, JsonRequestBehavior.AllowGet); ; }
有了这四个方法就ok了。下面来讲配置。先打个预防针,主要关心两个方法,一个设置table,一个设置分页。然后代码比较长..... 希望没有打消你驾驭它的渴望。
全部控制器代码:包含了分类的一些,道理一样

using System; using System.Collections.Generic; using System.Linq; using System.Linq.Expressions; using System.Text; using System.Web; using System.Web.Mvc; using XNManage.Common; using XNManage.Models; using XNManage.Repository; using XNManage.ViewModel; namespace XNManage.Controllers { public class ProductController : Controller { // // GET: /Product/ private readonly IProductRepository _repository; private IEnumerable_categoryViewModels = new List (); public ProductController(IProductRepository repository) { _repository = repository; } #region 产品 [LoginValid] public ActionResult Index() { //CategoryInit(); //ProductsInits(); return View(); } public JsonResult GetAllPros( string sord = "asc", string sidx = "ProductName",int page = 1, int rows = 10, bool _search = false,string searchField="", string searchOper="", string searchString="") { var rawpros = GetRawPros(_search, searchField, searchOper, searchString); var propertyInfo = typeof(Product).GetProperty(switchSidx(sidx)); Func object> expn = e => propertyInfo.GetValue(e, null); var enumerable = rawpros as Product[] ?? rawpros.ToArray(); IEnumerable pros = sord == "asc" ? enumerable.OrderBy(expn).Skip((page - 1) * rows).Take(rows).ToArray() : enumerable.OrderByDescending(expn).Skip((page - 1) * rows).Take(rows).ToArray(); var objpros = new List<object>(pros); var jsonData = JqGridModel.GridData(page, rows, enumerable.Count(), objpros); return Json(jsonData, JsonRequestBehavior.AllowGet); } private IEnumerable GetRawPros(bool search = false, string searchField = "", string searchOper = "", string searchString = "") { var rawpros = _repository.FindAll(); if (!search) return rawpros; switch (switchSidx(searchField)) { case "ProductName": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.ProductName.Contains(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.ProductName == searchString); break; case "ne": rawpros = rawpros.Where(n => n.ProductName != searchString); break; default: rawpros = rawpros.Where(n => n.ProductName.Contains(searchString)); break; } break; case "Category": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.Category.Contains(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.Category == searchString); break; case "ne": rawpros = rawpros.Where(n => n.Category != searchString); break; default: rawpros = rawpros.Where(n => n.Category.Contains(searchString)); break; } break; case "Brand": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.Brand.Contains(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.Brand == searchString); break; case "ne": rawpros = rawpros.Where(n => n.Brand != searchString); break; default: rawpros = rawpros.Where(n => n.Brand.Contains(searchString)); break; } break; case "SaSaPrice": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.SaSaPrice >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.SaSaPrice == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.SaSaPrice != Convert.ToDecimal(searchString)); break; } break; case "ZhuanGui": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.ZhuanGui >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.ZhuanGui == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.ZhuanGui != Convert.ToDecimal(searchString)); break; } break; case "YaShi": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.YaShi >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.YaShi == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.YaShi != Convert.ToDecimal(searchString)); break; } break; case "ZhuoyuePrice": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.ZhuoyuePrice >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.ZhuoyuePrice == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.ZhuoyuePrice != Convert.ToDecimal(searchString)); break; } break; case "WanningPrice": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.WanningPrice >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.WanningPrice == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.WanningPrice != Convert.ToDecimal(searchString)); break; } break; case "QuchengshiPrice": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.QuchengshiPrice >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.QuchengshiPrice == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.QuchengshiPrice != Convert.ToDecimal(searchString)); break; } break; case "DrugstorePrice": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.DrugstorePrice >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.DrugstorePrice == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.DrugstorePrice != Convert.ToDecimal(searchString)); break; } break; case "Others": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.Others.Contains(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.Others ==searchString); break; case "ne": rawpros = rawpros.Where(n => n.Others !=searchString); break; } break; case "KaLaiPrice": switch (searchOper) { case "cn": rawpros = rawpros.Where(n => n.KaLaiPrice >= Convert.ToDecimal(searchString)); break; case "eq": rawpros = rawpros.Where(n => n.KaLaiPrice == Convert.ToDecimal(searchString)); break; case "ne": rawpros = rawpros.Where(n => n.KaLaiPrice != Convert.ToDecimal(searchString)); break; } break; default: break; } return rawpros; } /* public JsonResult GetData(GridSettings grid) { var query = _repository.FindAll(); //filtring if (grid.IsSearch) { //And if (grid.Where.groupOp == "AND") foreach (var rule in grid.Where.rules) query = query.Where ( rule.field, rule.data, (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)); else { //Or var temp = (new List */ //这个函数其实不必要!index中可以写英文。列名和index没有关系 private string switchSidx(string sidx) { switch (sidx) { case "型号": return "ProductName"; case "类别": return "Category"; case "品牌": return "Brand"; case "规格": return "Standard"; case "专柜": return "ZhuanGui"; case "莎莎": return "SaSaPrice"; case "雅施": return "YaShi"; case "卓越": return "ZhuoyuePrice"; case "卡莱美": return "KaLaiPrice"; case "万宁": return "WanningPrice"; case "屈臣氏": return "QuchengshiPrice"; case "药店": return "DrugstorePrice"; case "其他": return "Others"; case "描述": return "Description"; case "更新时间": return "CreateTime"; default: return "ProductName"; } } public string CategorySelectList() { var cs = _repository.AllCategories(); var sb=new StringBuilder(""); foreach (var category in cs) { sb.Append(string.Format("", category.CategoryName, category.CategoryName)); } sb.Append(""); return sb.ToString(); } [HttpPost] public ActionResult Edit(Product pro, string oper, int id) { if (oper == "edit") { _repository.Update(pro); pro.CreateTime = DateTime.Now; } return Json(pro, JsonRequestBehavior.AllowGet); } // // POST: /Product/Create [HttpPost] public ActionResult Create(Product product) { _repository.Add(product); var fu = _repository.FindByName(product.ProductName); return Json(fu, JsonRequestBehavior.AllowGet); } // // POST: /Product/Delete/5 [HttpPost] public ActionResult Delete(int id) { _repository.Remove(id); return Json(id); } private void CategoryInit() { if (!_repository.AllCategories().Any()) { _repository.AddCategorie(new Category { CategoryName = "护肤品", Description = "春天女生护肤专用" }); _repository.AddCategorie(new Category() { CategoryName = "防晒", Description = "夏日喷雾防晒" } ); } } private void ProductsInits() { if (!_repository.FindAll().Any()) { _repository.Add(new Product() { ProductName = "水宝宝", Others = "防晒", SaSaPrice = 78, DrugstorePrice = 98 }); } } #endregion #region 分类 private IEnumerable()).AsQueryable(); foreach (var rule in grid.Where.rules) { var t = query.Where ( rule.field, rule.data, (WhereOperation)StringEnum.Parse(typeof(WhereOperation), rule.op)); temp = temp.Concat (t); } //remove repeating records query = temp.Distinct (); } } //sorting query = query.OrderBy (grid.SortColumn, grid.SortOrder); //count var count = query.Count(); //paging var data = query.Skip((grid.PageIndex - 1) * grid.PageSize).Take(grid.PageSize).ToArray(); //converting in grid format var result = new { total = (int)Math.Ceiling((double)count / grid.PageSize), page = grid.PageIndex, records = count, rows = data.ToArray() }; //convert to JSON and return to client return Json(result, JsonRequestBehavior.AllowGet); } initCategoryViewModels() { if (!_categoryViewModels.Any()) { var cas = _repository.AllCategories(); _categoryViewModels = cas.Select(n => new CategoryViewModel() { CategoryId = n.CategoryId, CategoryName = n.CategoryName, Description = n.Description, ProductCount = _repository.GetCategorieProducts(n.CategoryName).Count() }); } return _categoryViewModels; } public JsonResult GetAllCategorys(string sord = "asc", string sidx = "CategoryName", int page = 1, int rows = 10) { IList<object> pros = new List<object>(FindCategoryViewModels(sord, sidx, (page - 1) * rows, rows)); var jsonData = JqGridModel.GridData(page, rows, initCategoryViewModels().Count(), pros); return Json(jsonData, JsonRequestBehavior.AllowGet); } public IEnumerable FindCategoryViewModels(string sort = "asc", string property = "CategoryName", int skip = 0, int take = 10) { var propertyInfo = typeof(CategoryViewModel).GetProperty(property); Func object> expn = e => propertyInfo.GetValue(e, null); var fakeProfiles =initCategoryViewModels(); IEnumerable pros = sort == "asc" ? fakeProfiles.OrderBy(expn).Skip(skip).Take(take).ToArray() : fakeProfiles.OrderByDescending(expn).Skip(skip).Take(take).ToArray(); return pros; } public ActionResult EditCategory(CategoryViewModel model,string oper, int id) { if (oper == "edit") { var ca = new Category() { CategoryId = model.CategoryId, CategoryName = model.CategoryName, Description = model.Description, }; _repository.UpdateCategorie(ca); } return Json(model, JsonRequestBehavior.AllowGet); } public ActionResult CategoryList() { return View(); } [HttpPost] public ActionResult CreateCategory(Category category) { _repository.AddCategorie(category); var fu = _repository.FindCategorieById(category.CategoryId); var cm = new CategoryViewModel() { CategoryName = fu.CategoryName, CategoryId = fu.CategoryId, Description = fu.Description, ProductCount = _repository.GetCategorieProducts(fu.CategoryName).Count() }; return Json(cm, JsonRequestBehavior.AllowGet); } public ActionResult DeletCategory(int id) { _repository.RemoveCategorie(id); return Json(1); } public PartialViewResult JqgridInit() { return PartialView(); } public JsonResult GetChartData() { var cms = initCategoryViewModels().ToList(); var count =_repository.Count; var chartDatas = cms.Select(n => new ChartData { label = n.CategoryName, data = Math.Round((double)n.ProductCount / count, 3), }).ToArray(); return Json(chartDatas, JsonRequestBehavior.AllowGet); } #endregion } }
1)table的设置
jQuery("#list").jqGrid({ url: '/Product/GetAllPros', //获取数据源 datatype: "json", colNames: ['操作', 'ProductId', '类别', '品牌', '型号', '规格', '专柜', '莎莎', '卓越', '卡莱美', '雅施', '万宁', '屈臣氏', '药店', '其他', '更新时间'], //定义列名 colModel: [ //name 是对应我们的Product模型的属性,Index可以为中文也可以为英文,不必于上面colnames对应,顺序对就行了。查询的时候传到后台的是index。 { name: 'myac', index: '操作', width: 60, fixed: true, sortable: false, resize: false, formatter: 'actions', formatoptions: { keys: true, delOptions: { recreateForm: true, beforeShowForm: beforeDeleteCallback, }, } },
//详细的字段配置信息请见博客:http://www.cnblogs.com/huozhicheng/archive/2012/11/20/2778649.html { name: 'ProductId', index: 'ProductId', hidden: true, editable: true }, { name: 'Category', index: '类别', editable: true, edittype: 'select', editoptions: { dataUrl: "/Product/CategorySelectList" }, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'Brand', index: '品牌', editable: true, editrules: { required: false }, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'ProductName', index: '型号', editable: true, editrules: { required: true }, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'Standard', index: '规格', editable: true, edittype: 'textarea', searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'ZhuanGui', index: '专柜', editable: true, width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } },//formatter: 'integer', formatter: 'integer', { name: 'SaSaPrice', index: '莎莎', editable: true,width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'ZhuoyuePrice', index: '卓越', editable: true, formatter: 'integer', width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'KaLaiPrice', index: '卡莱美', editable: true, formatter: 'integer', width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'YaShi', index: '雅施', editable: true, formatter: 'integer', width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'WanningPrice', index: '万宁', editable: true, formatter: 'integer', width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'QuchengshiPrice', index: '屈臣氏', editable: true, formatter: 'integer', width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'DrugstorePrice', index: '药店', editable: true, formatter: 'integer', width: 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'Others', index: '其他', editable: true, edittype: 'textarea', searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'CreateTime', index: '更新时间', width: 200, formatter: 'date', //时间格式显示 formatoptions: { srcformat: 'Y-m-d H:i:s', newformat: 'Y-m-d H:i:s', searchoptions: { sopt: ['eq', 'ne', 'cn'] } } } ], rowNum: 10, rowList: [10, 20, 30], sortorder: "asc", pager: '#pager2', sortname: 'ProductName', viewrecords: true, caption: "产品明细", autowidth: true, multiselect: true, height: 180, gridComplete: function () { var icons = $(".ui-icon-trash");//隐藏删除键 icons.hide();//我隐藏了删除键 因为id的问题 //var ids = jQuery("#list2").jqGrid('getDataIDs'); //for (var i = 0; i < ids.length; i++) { // be = "";//修改 // se = "";//删除 // ce = "";//删除 // jQuery("#list2").jqGrid('setRowData', ids[i], { act: be + se + ce }); //}
//这个部分是可以添加定义的按钮,自己用脚本去实现。
}, loadComplete: function () { $("#grid-table").hide(); var table = this; enableTooltips(table); updatePagerIcons(table); }, editurl: "/Product/Edit", //编辑的地址 操作栏触发的操作都会丢到这个action中响应。 add edit del //改变传id的方法无效!!!! serializeDelData: function (postdata) { var rowdata = jQuery('#list2').getRowData(postdata.id); return { id: postdata.id, oper: postdata.oper, user: rowdata }; } //edit del });
形成样子如下:
colModel涉及的配置较多,不同的字段有不同的呈现,可以参考博客 http://www.cnblogs.com/huozhicheng/archive/2012/11/20/2778649.html
2)pager 用来形成分页和集成一些操作。
jQuery("#list").jqGrid('navGrid', '#pager2', {
//调整ui 也就是我们看到的:,但这个删除图标是我代码加上去的。 edit: true, editicon: 'icon-pencil blue', add: true, addicon: 'icon-plus-sign purple', del: false, delicon: 'icon-trash red', search: true, searchicon: 'icon-search orange', refresh: true, refreshicon: 'icon-refresh green', view: false, viewicon: 'icon-zoom-in grey', }, { //eidt url: '/Product/Edit', mtype: 'POST', afterSubmit: function (xhr, postdata) { var id = $("#list2").jqGrid('getGridParam', 'selrow'); jQuery("#list2").jqGrid('setRowData', id, postdata); }, closeAfterEdit: true, closeOnEscape: true }, { //add recreateForm: true, url: '/Product/Create', mtype: 'POST', afterSubmit: function (xhr, postdata) { var id = $("#list2").jqGrid('getGridParam', 'selrow'); jQuery("#list2").jqGrid('addRowData', postdata.Id, postdata); return [true, 'successfule!', false]; }, closeAfterAdd: true }, { //delete 此处无效 recreateForm: true, url: '/Product/Delete', mtype: 'POST', beforeShowForm: function (e) { var form = $(e[0]); if (form.data('styled')) return false; form.closest('.ui-jqdialog').find('.ui-jqdialog-titlebar').wrapInner(''); styleDeleteForm(form); form.data('styled', true); return true; }, afterSubmit: function (xhr, postdata) { var consoleDlg = $("#list2"); var selectedRowIds = $("#list2").jqGrid("getGridParam", "selarrrow"); var len = selectedRowIds.length; for (var i = 0; i < len ; i++) { $("#list2").jqGrid("delRowData", selectedRowIds[0]); } }, closeAfterDel: true }, { //search recreateForm: true, afterShowSearch: function(e){ var form = $(e[0]); form.closest('.ui-jqdialog').find('.ui-jqdialog-title').wrap('') styleSearchForm(form); }, afterRedraw: function(){ styleSearchFilters($(this)); } , // multipleSearch: true, closeAfterSearch: true }, { //view } );
在下面加入按钮的方法以及执行删除:jquery2.0中的绑定写法有些不同,也就是on的用法。
function updatePagerIcons() { //... var x = $("#pager2_left").find("#coco"); if (x.length == 0) { $("#pager2_left table tbody>tr").prepend(""); } } //绑定事件 执行删除 $("#pager2_left table tbody>tr").on("click", '#coco', function () { var selectedRowIds = $("#list2").jqGrid("getGridParam", "selarrrow"); var len = selectedRowIds.length; if (len != 0) { if (confirm("确定要删除选中项?")) { for (var i = 0; i < len; i++) { var rowData = $("#list2").jqGrid('getRowData', selectedRowIds[i]); $.post('/Product/Delete', { id: rowData.ProductId }, function (data) { $("#list2").jqGrid("delRowData", selectedRowIds[0]); }); } } } else { $.infoShow("未勾选", 0); } }); " + "
形成这个样子:
全部前台代码:

@{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } @Html.Partial("JqgridInit")
至此基本告成,还有些可以优化。
如果本文对你有帮助,请霸气的支持下 :) tks~
需要源码的同学,请戳下行。备注:数据库是EntityFramework + CE4.0,账户密码都是:admin
http://pan.baidu.com/s/1eSx6E0E 年轻的诸君,记得点赞留名~
模板源码:http://pan.baidu.com/s/1gdEGg2v
参考博客:
参数设定 http://www.cnblogs.com/younggun/archive/2012/08/27/2657922.html
jqgridDemo:http://www.trirand.com/blog/jqgrid/jqgrid.html
多重查询:http://www.codeproject.com/Articles/58357/Using-jqGrid-s-search-toolbar-with-multiple-filter
其他后台模板:http://www.tystudio.net/2013/03/11/back-manage-system-template/