zoukankan      html  css  js  c++  java
  • ACE模板之Jqgrid

    Asp.Net MVC中使用ACE模板之Jqgrid

     

        第一次看到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><!-- /.page-header -->
    
                            <div class="row">
                                <div class="col-xs-12">
                                    <!-- PAGE CONTENT BEGINS -->
                                     @RenderBody()
                                    <!-- PAGE CONTENT ENDS -->
                                </div><!-- /.col -->
                            </div><!-- /.row -->
                        </div><!-- /.page-content -->
    复制代码

    全部的layout.cshtml

     View Code

    二、引入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: 我们需要呈现的一个是一个产品,有很多不同的价格及其他,这些都将成为表格的列名。

     View Code

    2.ProductRepository (仓库真的很好,独立了业务逻辑,可测试,复用快),add、remove、update不用讲了,主要讲一讲排序。

      1)排序查询的意义在于根据不同的属性进行排序。

    复制代码
     public class ProductRepository:IProductRepository
        {
            private readonly XNDb _db = new XNDb();
            //....
            public IEnumerable<Product> Find(string sort = "asc", string property = "ProductName", int skip = 0, int take = 10)
            {
                var propertyInfo = typeof(Product).GetProperty(property);//反射出这个属性
                Func<Product, object> expn = e => propertyInfo.GetValue(e, null);//委托
                var rawpros = _db.Products;
                IEnumerable<Product> 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));
                Func<Product, object> expn = e => propertyInfo.GetValue(e, null);
    
                var enumerable = rawpros as Product[] ?? rawpros.ToArray();
                IEnumerable<Product> 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
        {
            /// <summary>
            /// Grids the data.
            /// </summary>
            /// <param name="page1">当前页数.</param>
            /// <param name="rows">每页显示数目.</param>
            /// <param name="total"></param>
            /// <param name="objects">集合对象</param>
            /// <returns>System.Object.</returns>
            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,一个设置分页。然后代码比较长..... 希望没有打消你驾驭它的渴望。

    全部控制器代码:包含了分类的一些,道理一样

     View Code

    1)table的设置

    复制代码
       jQuery("#list").jqGrid({
            url: '/Product/GetAllPros', //获取数据源
            datatype: "json",
            colNames: ['操作', 'ProductId', '类别', '品牌', '型号', '规格', '专柜', '莎莎', '卓越', '卡莱美', '雅施', '万宁', '屈臣氏', '药店', '其他', '更新时间'], //定义列名 
            colModel: [ //name 是对应我们的Product模型的属性,Index可以为中文也可以为英文,不必于上面colnames对应,顺序对就行了。查询的时候传到后台的是index。
                {
                    name: 'myac', index: '操作',  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, 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } },//formatter: 'integer', formatter: 'integer', { name: 'SaSaPrice', index: '莎莎', editable: true, 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'ZhuoyuePrice', index: '卓越', editable: true, formatter: 'integer', 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'KaLaiPrice', index: '卡莱美', editable: true, formatter: 'integer', 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'YaShi', index: '雅施', editable: true, formatter: 'integer', 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'WanningPrice', index: '万宁', editable: true, formatter: 'integer', 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'QuchengshiPrice', index: '屈臣氏', editable: true, formatter: 'integer', 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'DrugstorePrice', index: '药店', editable: true, formatter: 'integer', 60, searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'Others', index: '其他', editable: true, edittype: 'textarea', searchoptions: { sopt: ['eq', 'ne', 'cn'] } }, { name: 'CreateTime', index: '更新时间', 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: "产品明细", auto 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 = "<span class='ui-icon ui-icon-pencil'></span>";//修改 // se = "<span class='ui-icon ui-icon-trash'></span>";//删除 // ce = "<span class='icon-ok ui-icon'></span>";//删除 // 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('<div class="widget-header" />');
                    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('<div class="widget-header" />')
                    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("<td class='ui-pg-button ui-corner-all' title data-original-title='Remove a row'><div id='coco'  class='ui-pg-div'>" +
                    "<span class='ui-icon icon-trash blue'></span></div></td>");
            }
    
    }
     //绑定事件 执行删除 
        $("#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);
            }
        });
    复制代码

    形成这个样子:

    全部前台代码:

     View Code

    至此基本告成,还有些可以优化。

    如果本文对你有帮助,请霸气的支持下    :)  tks~

    需要源码的同学,请留邮箱。备注:数据库是EntityFramework + CE4.0,账户密码都是:admin

    模板源码: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/

     
     
    分类: JqueryMVC源码笔记
  • 相关阅读:
    C# .net 中文简体繁体转换
    关于html+js将值传输到后端C#的问题(删减版)
    Error mapping types
    Vs编译时RazorTagHelper
    Sum All Numbers in a Range-freecodecamp算法题目
    Caesars Cipher-freecodecamp算法题目
    Where do I belong-freecodecamp算法题目
    Seek and Destroy-freecodecamp算法题目
    Falsy Bouncer-freecodecamp算法题目
    Mutations-freecodecamp算法题目
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3816987.html
Copyright © 2011-2022 走看看