ASP.NET中使用JqGrid完整实现

文章提纲

  • 介绍 & 使用场景
  • JqGrid的一些说明
  • JqGrid和ASP.NET整合详细步骤

  前置准备

  框架搭建

  数据填充

  数据增/删/改

  其他 

介绍&使用场景

JqGrid不是一个新鲜玩意,已经是一个久经证明的开源数据显示控件了。

园子里也有一些介绍文章,为什么还要写这篇文章呢?

因为还找不到可以完整讲述JqGrid集成的文章,我指的是从头至尾的完整的讲述,而不是其中一些片段或介绍一些参数。

正好在看到一篇文章完整的讲述了这个步骤: http://www.codeproject.com/Articles/609442/Using-JqGrid-in-ASP-NET

本文主要参考了这篇文章,讲述jqGrid和ASP.NET集成。

使用场景:

数据多且杂时,如果想要给表格数据的显示增加方便的查询/删选功能。

JqGrid免费,开源,使用方便,是一个不错的选择。

 

JqGrid的一些说明

  • 外观时髦,功能齐全
  • JS控件,用来显示和操作表格数据
  • 使用AJAX方式
  • 可以被集成到任何服务器端技术,例如ASP, JavaServelets, JSP, PHP 等等.
  • 由Trirand公司Tony Tomov开发.
  • 和ASP.NET集成非常简单

JqGrid和ASP.NET整合详细步骤

  • 下载JqGrid,添加所需的文件到ASP.NET应用程序 (主要是一些Scripts and CSS).
  • 在需要使用的页面中初始化JqGrid.
  • 绑定数据
  • 其他一些操作,如增删改
 

1. 我提到的第一点,你可以在以下地址下载JqGrid和相关的文件

http://www.trirand.com/blog/?page_id=6 

下载得到jquery.jqGrid-4.5.2.zip

将文件解压,里面是一些css和script文件夹, 让我们去看看如何去使用这些文件。
为了更好的理解, 按照国际惯例我新建了一个demo程序:JQGridPOC,用来展示集成的步骤和所具有的功能。

我们需要引入的主要文件是jQuery, 因为jqGrid依赖于jQuery .

在解决方案中专门新建一个文件夹JQGridReq用来放JqGrid相关的文件。

第一步,添加jQuery文件(我添加了jQuery 1.9)。

第二步,如果我们要如何使用jQuery中任何UI相关的东西? 是的,CSS文件. 去jQuery的官网下载。 

最后一步,添加Jquery-ui-1.9.2.custom.css 到程序中。

请确保你同时添加了相关的图片文件夹,因为我们添加的CSS可能也会用到相关的图片。

这样jQuery的东西就准备好了。

下面再开始逐个添加我们JqGrid文件。

  1. jquery.jqGrid-4.5.2\src\ jquery.jqGrid.js 
  2. jquery.jqGrid-4.5.2\js\i18n\ grid.locale-en.js
  3. jquery.jqGrid-4.5.2\js\i18n\ grid.locale-cn.js
  4. jquery.jqGrid-4.5.2\css\ ui.jqgrid.css

你看到上面添加的locale-en.js/local-en.js文件了吗? 他们非常重要,可以在里面更改一些预设的参数。

同样的,我们也添加了CSS文件.

现在我们先决条件都完成了。

如下图,你可以看到我们添加后的文件和文件夹结构.

 

让我们去.aspx 页面添加JqGrid吧。

这个简单的示例项目中我使用了简单的客户管理的案例,使用Default.aspx 做为例子。

需要将所有需要的文件先引用到HTML页的head部分,如下图。

现在需要做的是先将HTML table标签放置到页面中,给这个table指定一个ID jQgridPOC (这个table就是我们即将要转变成的JqGrid)。

 

 

 

2. 在需要使用的页面中初始化JqGrid.

下面将要将这个table转变成JqGrid.

准备好我们将要打算显示在Grid中的字段,我们初始化table的时候必须带上这些字段。

我们准备显示的是:

  1. UniqueID
  2. First Name
  3. Last Name
  4. City
  5. State
  6. Address.

你可以使用下面脚本将HTML table初始化成grid.

代码片段:

    <script>
        $(function () {
            $("#jQgridPOC").jqGrid({
                url: 'http://localhost:58404/JQGridHandler.ashx',
                datatype: "json",
                colNames: ['Id''大名''尊姓'"地址"'城市''州'],
                colModel: [
                            { name: 'id', index: 'id', width: 20, stype: 'text' },
                            { name: 'FirstName', index: 'FirstName', width: 80, stype: 'text', sortable: true, editable: true },
                            { name: 'LastName', index: 'LastName', width: 80, align: "right", editable: true },
                            { name: 'Address1', index: 'Address1', width: 150, align: "right", editable: true },
                            { name: 'City', index: 'City', width: 80, align: "right", editable: true },
                            { name: 'State', index: 'State', width: 100, sortable: false, editable: true }
                ],
                rowNum: 10,
                loadonce: true,
                sortname: '_id',
                viewrecords: true,
                sortorder: 'desc',
                caption: "客户列表"
 
            });
        });
 

    </script>

运行程序,你将会得到下图所示表格(目前还没数据)。

我想根据表格显示内容,你应该能读懂我写的初始化脚本。

colNames代表表格头部.

colModel是JSON对象数据的属性,用来配置表格中的每一列。

可以说要在表格中显示的数据模型。colNames中的属性顺序应该和colModel中数组的顺序相匹配。

3. 绑定数据

你也许注意到url属性留着没有填。

那是供AJAX调用的,下面就完成这部分内容,填充这个grid.

我使用SQL Server的示例数据库PETSHOP作为后端.

URL如何完成填充数据?

我所做的是, 创建一个HTTP handler, handler里面的函数去取表 [MSPetShop4Profile].[dbo].[Account] 中的数据并且写到HTTP Response中去。

HTTP response将会是一个JSON字符串,按照之前提到的colModel的格式。

我们的JqGrid读取JSON返回字符串,在colModel的帮助下显示在JqGrid里。

你需要留意一下,目前我们使用JSON对象。

JqGrid可以使用XML,JSON,数组,我们使用的是JSON。

正如我所说的,我创建了一个.ashx handler,叫JQGridHandler.ashx

相应的url地址为:http://localhost:58404/JQGridHandler.ashx.

下面就向你展示数据如何从handler中读取。从grid中访问handler仅仅只需要调用URL

通常,如果我们需要传递数据到handler或从handler中读取数据,我们在哪找传递的参数?

是的,我们显然会首先去context.Request中找,不是吗?

此时我们也会去看看在 context request 中是否有表单参数数据传递进来。
让我们去调试看看。

通过查看调试器(如上图),你可以看到我在通过调用forms.Get(“oper”) oper  的值。

希望你已经注意到了 Form{} 属性是空的。

那么为什么我会取oper的值呢?

我想你已经猜到了,grid操作数据时会依赖oper 参数。

继续往下看,我将会向你展示oper中的所有数据。

现在我们假设 oper==null 时代表grid是第一次加载。不要感到困惑。

下面我使用SQL Server数据库作为我的数据存储。

关于ADO.NET这块我不做讨论,主要用了一个类文件SQLHelper和两个函数
private DataTable GetAccountInfo()
public string GetJson(DataTable dt)

可自行在代码中查看。

另外需要说明的是我取回的数据源是DataTable,需要转换成JSON,用了public string GetJson(DataTable dt)进行转换。

你也可以使用其他数据源,用你熟悉的就好。

你可以看到取数据的代码在if语句中。

我希望到现在为止一切都说的很清楚。

现在好了,我们为JqGrid铺好了数据管道,让我们看看是否可以工作。

 

数据会被装载进来吗?

CTRL+F5

 

数据已经被装载进来了。

 

现在可以在这个基础上做一些变化了。

你也许会想这个表格有什么特别呢?和一个简单的gridview一样。。。

 你点一下第二列的表头"大名"试试,直接就能排序了。

我们给排序写代码了吗?

没错,这就是jqGrid的优雅之处。不光是第一列,每一列的表头都可以进行排序。

除非你加了如下sortable : false属性,如下:

{ name: 'State', index: 'State', width: 80, sortable: false, editable: true }

(这里State这个字段是不能排序的)

 

继续向下,你能看到其他一些激动人心的功能 :)

在JqGrid table  (jQGridPOC)下面再添加一个div. 如下

<table id="jQGridPOC"></table><div id="jQGridPOCPager"></div>

是的,我在底部又添加了一个div jQGridPOCPager.

脚本做一些修改,如下 

注意方框部分是我新增加的。

 

看看现在Grid是什么样了.

 

页码工具栏出现了。

这个底部工具栏的优雅之处在于,不用写一行代码就能完成搜索功能。

不光是搜索,排序功能也能同样不需要写代码就能实现,JqGrid原生就能实现这些功能。

下面对这个工具栏做一些设置相关配置如下(如图9,10)。

让我们试一下查找功能. (如图11)

说明一下,你可以在grid.locale-cn.js-->nav 片段中修改底部工具栏中的一些default设置(显示文字,跳出模态框的标题等),如图12.

当然 ,你可以在JqGrid初始化时修改这些默认设定,如图13。

另外你应该注意到了图11中的筛选条件例如等于,不等,开始于等等。

我不需要用这么多的筛选条件,怎样移除?

如果已经把grid.locale-cn.js都浏览一遍,你应该已经发现这些条件在grid.locale-cn.js-->search片段中。

是的,只要修改这些就可以了,你可以移除一些试试看。(如下图方框处)

这个文件中的其他片段的作用相信你能根据代码猜测出来,自己去探索一下吧 :)

希望到此处你都能理解。

下一步打算给grid添加数据库交互功能,即增删改功能。

让我们一起来看看吧。

 

 

4.JqGrid Edit/Add/Delete

JqGrid所有的事件和属性都是可配置的,用起来很简单。

不过要注意,即使是一点小改动也可能让grid不能按你期望的工作.

为了完成我们的增删改功能,搭建下面代码的框架。注意按照我下面示例的顺序。

 

            $('#jQgridPOC').jqGrid('navGrid', '#jQGridPOCPager',
                 {
                     edit: true,
                     add: true,
                     del: true,
                     search: true,
                     searchtext: "查找",
                     addtext: "添加",
                     edittext: "编辑",
                     deltext: "删除",
                     refreshtext:"刷新"
                 },
                 {   
                     //EDIT EVENTS AND PROPERTIES GOES HERE

                 },
                 {
                     //ADD EVENTS AND PROPERTIES GOES HERE
                 },
                 {   //DELETE EVENTS AND PROPERTIES GOES HERE           
                 },
                 {
                     //SEARCH EVENTS AND PROPERTIES GOES HERE

                 }
          );
 
View Code

 

 

你可以看到代码中的注释,我将会将事件和属性填充进去。

在第一个大括号里,我们已经添加了一些参数并设定为true, 添加了按钮后面的文字说明。这个部分我上面已经提到过了。

这代表在grid的底部导航栏中,所有的button将会显示,并且分别显示相对应的文字。(如下图15)

 

仅接着的几个大刮号是对应的JqGrid的初始化事件和参数。

 

让我们看一下grid,上面的改动都生效了。

 

 

请注意上图的方框部分。我们点击 “添加” 来增加一笔资料。

将会跳出一个小窗(如下面的截图)

 

填写后点提交会提示 没有设置url 错误。因为我们还没完成这部分功能呢。

要想执行增删改操作,你需要在grid中添加一个URL属性即editurl.

这个url将会去调用.ashx handler去执行添加功能。

我在caption下面添加一行,你需要设置 editurl: 'http://localhost:58404/JQGridHandler.ashx'

 

保存修改,在handler入口处加个断点,调试。

重复上面添加提交步骤,看到 context.Request.Form 中的值了吗,完全和我们预期的一样。

我们要的数据已经都可以获得了,可以看到forms.Get("oper")已经可以得到值 "add" 了。

 

 

根据上面调试的截图你应该可以对我们之前提到的 oper 有更多的了解,前面是在加载数据到grid中提到的。

键值对中键对应grid中的字段,例如FirstName, LastName等。  

 

理解了吗?

示例代码中我将增加和编辑都放在了同一个分支中,根据相应的if分支就可以执行插入数据到DB的功能了。

string strFirstName = forms.Get("FirstName").ToString();

如上面的写法,同样方法你可以从HTTP request读取表单中其他值.

插入成功后handler将会写一笔插入成功的字符串到HTTP response中. 

这个字符串将会显示在弹出框中,如下图“资料添加成功”。

这个返回的信息是从handler中发送的,从示例代码中应该很容易找到。

 

 

你也许会想客户端哪些事件会接收server端的response, 完整的脚本如下,我将编辑和删除也加上了。

 

 $(function () {
            $("#jQgridPOC").jqGrid({
                url: 'http://localhost:58404/JQGridHandler.ashx',
                datatype: "json",
                colNames: ['Id', '大名', '尊姓', "地址", '城市', '州','国家'],
                colModel: [
                            { name: 'id', index: 'id', width: 20, stype: 'text' },
                            { name: 'FirstName', index: 'FirstName', width: 80, stype: 'text', sortable: true, editable: true },
                            { name: 'LastName', index: 'LastName', width: 80, align: "right", editable: true },
                            { name: 'Address1', index: 'Address1', width: 150, align: "right", editable: true },
                            { name: 'City', index: 'City', width: 100, align: "right", editable: true },
                            { name: 'State', index: 'State', width: 80, sortable: false, editable: true },
                            { name: 'Country', index: 'Country', width: 80, sortable: false, editable: true }
                ],
                rowNum: 10,
                loadonce: true,
                rowList: [10, 20, 30],
                pager: '#jQGridPOCPager',
                sortname: 'LastName',
                viewrecords: true,
                sortorder: 'desc',
                caption: "客户列表",
                editurl: 'http://localhost:58404/JQGridHandler.ashx'
            });


            $('#jQgridPOC').jqGrid('navGrid', '#jQGridPOCPager',
                 {
                     edit: true,
                     add: true,
                     del: true,
                     search: true,
                     searchtext: "查找",
                     addtext: "添加",
                     edittext: "编辑",
                     deltext: "删除",
                     refreshtext:"刷新"
                 },
                 {   //EDIT
                     //                       height: 300,
                     //                       width: 400,
                     //                       top: 50,
                     //                       left: 100,
                     //                       dataheight: 280,
                     closeOnEscape: true,//Closes the popup on pressing escape key
                     reloadAfterSubmit: true,
                     drag: true,
                     afterSubmit: function (response, postdata) {
                         if (response.responseText == "") {

                             $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid');//Reloads the grid after edit
                             return [true, '']
                         }
                         else {
                             $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid'); //Reloads the grid after edit
                             return [false, response.responseText]//Captures and displays the response text on th Edit window
                         }
                     },
                     editData: {
                         EmpId: function () {
                             var sel_id = $('#jQGridDemo').jqGrid('getGridParam', 'selrow');
                             var value = $('#jQGridDemo').jqGrid('getCell', sel_id, '_id');
                             return value;
                         }
                     }
                 },
                 {
                     closeAfterAdd: true,//Closes the add window after add
                     afterSubmit: function (response, postdata) {
                         if (response.responseText == "") {

                             $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
                             return [true, '']
                         }
                         else {
                             $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')//Reloads the grid after Add
                             return [false, response.responseText]
                         }
                     }
                 },
                 {   //DELETE
                     closeOnEscape: true,
                     closeAfterDelete: true,
                     reloadAfterSubmit: true,
                     closeOnEscape: true,
                     drag: true,
                     afterSubmit: function (response, postdata) {
                         if (response.responseText == "") {

                             $("#jQGridDemo").trigger("reloadGrid", [{ current: true }]);
                             return [false, response.responseText]
                         }
                         else {
                             $(this).jqGrid('setGridParam', { datatype: 'json' }).trigger('reloadGrid')
                             return [true, response.responseText]
                         }
                     },
                     delData: {
                         EmpId: function () {
                             var sel_id = $('#jQGridDemo').jqGrid('getGridParam', 'selrow');
                             var value = $('#jQGridDemo').jqGrid('getCell', sel_id, '_id');
                             return value;
                         }
                     }
                 },
                 {//SEARCH
                     closeOnEscape: true

                 }
          );

        });
View Code

 

 

编辑功能时我们会使用一个主键更新,这里的主键是 _id, 即我们数据库中的 UniqueID.

特别需要说明的是,编辑更新时,只有标记为editable才能传递到handler中去。

如果把字段editable标记为false或不标记,就不会在跳出的编辑框中显示。

你可以看一下编辑时_id没显示,因为这个字段没有标记为editable因此就不会传递到handler中去。

说明:原来用的示例数据库中Account表,不过发现有一些主外键约束及多余字段不方便演示,我又新建了个类似的表AccountTEST(删除了一些多余字段)。

为了把_id值从我们的grid中传递到server中,我使用了JqGrid中的editData 属性。

同样我们也可以利用delData属性传递 _id去删除数据。

注意:不光是_id,你可以传递任何数据到handler中去,使用JSON格式的editData,delData 

从上面的代码可以看出,另外一个常用技巧是获取选中行的数据。

通过下面两行代码:先获取选中行,再选取该行中所要的字段。

根据strOperation(forms.Get("oper")) null, add, edit, del执行不同的操作。最后handler的代码也做个总结

    public class JQGridHandler : IHttpHandler
    {

        public void ProcessRequest(HttpContext context)
        {
            NameValueCollection forms = context.Request.Form;
            string strOperation = forms.Get("oper");
            string strResponse = string.Empty;
            if (strOperation == null) //oper = null which means its first load.
            {
                //1.get the sample data
                DataTable dt = GetAccountInfo();
                //2.convert to json
                string jsonRes = GetJson(dt);
                context.Response.Write(jsonRes);
            }
            else if (strOperation == "del")
            { 
                string strEmpId = forms.Get("id").ToString();
                DeleteEmployee(strEmpId);
                strResponse = "删除成功";
                context.Response.Write(strResponse);
          
            }
            else
            {
                string strOut = string.Empty;
                AddEdit(forms, out strOut);
                context.Response.Write(strOut);
            }
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }

        private DataTable GetAccountInfo()
        {
            DataTable dt = null;
            string cmdText = @"SELECT [UniqueID] id
                              ,[FirstName]
                              ,[LastName]
                              ,[Address1]
                              ,[City]
                              ,[State]
                              ,[Country]
                          FROM [MSPetShop4Profile].[dbo].[AccountTest]";
            SQLHelper sqlhelper = new SQLHelper();
            dt = sqlhelper.ExecuteQuery(cmdText, CommandType.Text);
            return dt;
        }

        //convert a data table to JSON format 
        public string GetJson(DataTable dt)
        {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            List<Dictionary<string, object>> rows =
              new List<Dictionary<string, object>>();
            Dictionary<string, object> row = null;

            foreach (DataRow dr in dt.Rows)
            {
                row = new Dictionary<string, object>();
                foreach (DataColumn col in dt.Columns)
                {
                    row.Add(col.ColumnName.Trim(), dr[col]);
                }
                rows.Add(row);
            }
            return serializer.Serialize(rows);
        }

        private void AddEdit(NameValueCollection forms, out string strResponse)
        {
            string strOperation = forms.Get("oper");
            string strEmpId = string.Empty;
            string strFirstName = forms.Get("FirstName").ToString();
            string strLastName = forms.Get("LastName").ToString();
            string strAddress = forms.Get("Address1").ToString();
            string strCity = forms.Get("City").ToString();
            string strState = forms.Get("State").ToString();
            string strCountry = forms.Get("Country").ToString();

            Employee objEmp = new Employee();
            objEmp._id = strEmpId;
            objEmp.FirstName = strFirstName;
            objEmp.LastName = strLastName;
            objEmp.Address1 = strAddress;
            objEmp.City = strCity;
            objEmp.State = strState;
            objEmp.Country = strState;
            if (strOperation == "add")
            {
                InsertEmployee(objEmp);
                strResponse = "资料添加成功";
                return;

            }
            else if (strOperation == "edit")
            {
                strEmpId = forms.Get("id").ToString();
                objEmp._id = strEmpId;
                UpdateEmployee(objEmp);
                strResponse = "资料更新成功";
            }

            strResponse = "更新有问题,请联系管理员";
        }

        //insert
        public bool InsertEmployee(Employee employee)
        {

            bool flag = false;
            SQLHelper sqlhelper = new SQLHelper();

            string cmdText = @"INSERT INTO [MSPetShop4Profile].[dbo].[AccountTest]
                               ([FirstName]
                               ,[LastName]
                               ,[Address1]
                               ,[City]
                               ,[State]
                               ,[Country])
                         VALUES
                               (@FirstName
                               ,@LastName
                               ,@Address1
                               ,@City
                               ,@State
                               ,@Country)";

            SqlParameter[] paras = new SqlParameter[]{
                    new SqlParameter("@FirstName",employee.FirstName),
                    new SqlParameter("@LastName",employee.LastName),
                    new SqlParameter("@Address1",employee.Address1),
                    new SqlParameter("@City",employee.City),
                    new SqlParameter("@State",employee.State),
                    new SqlParameter("@Country",employee.Country)
                };
            try
            {
                int res = sqlhelper.ExecuteNonQuery(cmdText, paras, CommandType.Text);
                if (res > 0)
                {
                    flag = true;
                }
            }
            catch (Exception ex)
            {

                throw ex;
            }

            return flag;
        }

        //update
        public bool UpdateEmployee(Employee employee)
        {

            bool flag = false;
            SQLHelper sqlhelper = new SQLHelper();

            string sql = @"UPDATE [MSPetShop4Profile].[dbo].[AccountTEST]
                           SET [FirstName] = @FirstName
                              ,[LastName] = @LastName
                              ,[Address1] = @Address1
                              ,[City] = @City
                              ,[State] = @State
                              ,[Country] = @Country
                            WHERE UniqueID=@UniqueID";
            SqlParameter[] paras = new SqlParameter[]{
                    new SqlParameter("@UniqueID",employee._id),
                    new SqlParameter("@FirstName",employee.FirstName),
                    new SqlParameter("@LastName",employee.LastName),
                    new SqlParameter("@Address1",employee.Address1),
                    new SqlParameter("@City",employee.City),
                    new SqlParameter("@State",employee.State),
                    new SqlParameter("@Country",employee.Country)
                };
            int res = sqlhelper.ExecuteNonQuery(sql, paras, CommandType.Text);
            if (res > 0)
            {
                flag = true;
            }
            return flag;
        }

        //delete
        public bool DeleteEmployee(string id)
        {

            bool flag = false;
            SQLHelper sqlhelper = new SQLHelper();

            string sql = @"DELETE FROM [MSPetShop4Profile].[dbo].[AccountTEST]
                           WHERE UniqueID=@UniqueID";
            SqlParameter[] paras = new SqlParameter[]{
                    new SqlParameter("@UniqueID",id)
                };
            int res = sqlhelper.ExecuteNonQuery(sql, paras, CommandType.Text);
            if (res > 0)
            {
                flag = true;
            }
            return flag;
        }
    }
View Code

 

OK, done.

总结

JqGrid优雅,功能丰富易集成,对表格数据进行操作。

JqGrid还有很多功能,各位看官自行探索吧。

参考文章的作者使用了MONGO这个open-source document database,有兴趣的可以去研究下。

第一次写长文章,如果有帮助,请猛戳推荐 :)

 

更新:

源码地址:http://yunpan.cn/QD96IGcIbZyNG

 



posted @ 2013-09-24 11:23  MiroYuan  阅读(19024)  评论(39编辑  收藏  举报