• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

细说jquery ui和jqgrid的ASP.NET实现

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

数据显示的方式可以通过很多控件来实现,例如服务端的原生GridView,第三方控件ComponentArt、Telerik等,客户端的flexgrid, extgrid, easyui, jqgrid等等。在这里我要讲解的是jqgrid,它也是我最近在项目中尝试用到的。

我选择使用jqgrid主要是因为它基于jquery ui,在没有美工、契合系统主题并且快速完成系统的前提下,我选择了可以定制theme的jquery ui.

这篇文章主要涉及到jquery ui和jqgrid的使用,我对每一步的讲解都尽量做到细化,结合详细的截图,以期能够通过step by step让初学者们熟悉一些原理和实现步骤。
文中涉及到一些其他知识点,也做了较为详细的说明,希望这些内容能够对web开发者们有较好的增益作用。
每一个页面的在线demo我还在配置中,一会儿放出来,可以让大家有个直观的感受。
本章概要:

在开始项目之前,需要做的一些准备我也会逐步在下面的内容中进行介绍,或者你可以直接在这里下载本文所有demo的源代码,源代码中已经为你准备好这些文件,并且这些都是可以运行的。

源代码下载:KFBlogDemo.zip
数据库:Northwind(2005,2008 Northwind下载

一、 Json标准格式和验证

由于自己在使用jqgrid的过程中曾经使用过不规范的json,导致数据jqgrid一直无法显示,所以在此有必要简单讲一下json的标准格式和验证方式。

虽然在js中字符串也可以用单引号来表示,但是json的标准格式是用双引号把属性和值给括起来的,注意是属性和值(当然数值类型的值可以省去双引号)。下列Json格式中除了最后一条是标准的,前面几条都是不标准的。

 

    { 'name' : 'keepfool' }  // 错误格式,proerty和value应用双引号
     { name: 'keepfool' }    // 错误格式,property应用双引号括起来,value应用双引号
     { name: "keepfool" }    // 错误格式,property应用双引号括起来
     { "name" : 'keepfool' } // 错误格式,value应用双引号
     { "name" : "keepfool" } // 标准格式

有时候手动生成json格式的字符串,可能会不符合标准,可以通过下面两个在线验证工具执行验证,我推荐使用第一个,因为它能够准确的定位出json串出错的地方,下面的几个例子也是通过第一个在线工具做验证的。

例子1(属性没带引号):

{ id: "1", "invdate": "2010-05-24", "name": "test", "note": "note", "tax": "10.00", "total": "2111.00" }

例子2(属性带单引号):

{ "id": "1", "invdate": '2010-05-24', "name": "test", "note": "note", "tax": "10.00", "total": "2111.00" }

例子3(正确):

{ "id": "1", "invdate": "2010-05-24", "name": "test", "note": "note", "tax": "10.00", "total": "2111.00" }

 

二、jquery ui theme的使用

在文章的开篇我已经提到过jquery ui,它的使用方式我会在下面一步一步列出来,希望对那些还不太会使用jquery ui theme的童鞋们有所帮助。

1. 项目创建

在VS下创建一个Web网站或者Web应用程序,创建一个themes目录。如下图:

2. Base Theme的使用

先到http://jqueryui.com/themeroller/下载一个theme,就选那个最基本的灰色调的。
如果你已经熟悉下面的步骤并且对于下面的步骤不感兴趣,可以直接跳至关键的代码区域

 

然后会看到下面这个画面,甭管左边有哪些组件,直接download.

把下载得到的jquery-ui-1.8.16.custom.zip文件解压出来,找到base目录(\jquery-ui-1.8.16.custom\development-bundle\themes\base),将base目录复制到themes文件夹下。

找到ui目录(\jquery-ui-1.8.16.custom\development-bundle\ui\),同样将其复制到themes目录下,ui目录包含三部分:
(1). jquery ui组件 
(2). 压缩后的jquery ui组件(在minified文件夹中)
(3). 本地化语言文件(i18n)

现在基本的准备都已经做好了,下面我们来创建第一个页面BaseTheme.html,并演示一个手风琴的效果(accordion组件),请看基础并且关键的步骤:

(1). 引用jquery ui css

<link rel="Stylesheet" type="text/css" href="themes/base/jquery.ui.all.css" />

(2). 引用jquery ui js

<script type="text/javascript" src="themes/ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="themes/ui/jquery.ui.widget.js"></script>
<script type="text/javascript" src="themes/ui/jquery.ui.accordion.js"></script>

(3). 手风琴html代码

<div class="demo">
     <h1> Base Demo</h1>
     <div id="accordion">
     <h3><a href="#">Section 1</a></h3>
     <div>
     <p>A.</p>
     </div>
     <h3><a href="#">Section 2</a></h3>
     <div>
     <p> B. </p>
     </div>
     </div>
</div>

(4). 实现jquery 手风琴效果

<script type="text/javascript">
     $(function() {
     $("#accordion").accordion({
     collapsible: true
     });
     });
</script>

最终的效果如下图,当然完整的代码已经包含在下载文件中了,您也可以直接运行里面的代码。

3. theme的使用方式

Base Theme的使用方式我们已经使用过了,但是这个灰色调的主题可能并不符合您网站的主题色调,不过幸运的是http://jqueryui.com/themeroller/已经为我们提供了很多种不同色调而且比较美观的主题,你可以自行去下载。当然如果你觉得某一款主题看起来不错,但某些样式还需要一些轻微的改动才能应用到自己的程序中,你可以使用Edit去进行编辑,然后生成自己需要的主题。

在第2步中已经列出了jquery ui的使用方式,如果你想换一个主题使用,方式和上面的代码步骤是相同的。
以lightness主题为例: 
 

唯一不同之处是对css的引用

<link rel="Stylesheet" type="text/css" href="themes/theme_lightness/jquery.ui.all.css"/>
   

这里演示的例子都是accordion的,如果你想尝试其他的jquery ui组件,可以自行更换。但关键的两行代码是必不可少的,它们是jquery ui组件的基础:
<script type="text/javascript" src="themes/ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="themes/ui/jquery.ui.widget.js"></script>

4. 主题切换的实现

有了前面的基础,要实现主题切换已经很简单了,因为我们已经知道jquery theme的关键之处——引用jquery.ui.all.css,请看代码:

步骤I

<link rel="Stylesheet" type="text/css" href="themes/theme_lightness/jquery.ui.all.css" id="theme" >

步骤II

<div>
     请选择主题:
     <select id="theme_changer">
     <option value="themes/base/jquery.ui.all.css">Base Theme</option>
     <option value="themes/theme_lightness/jquery.ui.all.css" selected="selected">Lightness Theme</option>
     </select>
</div>

步骤III

<script type="text/javascript">
     $(document).ready(function() {
     $('#theme_changer').change(function() {
     var theme = $(this).find("option:selected").val();
     $('#theme').attr('href', theme);
     });
     });
</script>

效果图:

5. 单个页面多主题的实现

单个页面多主题的实现需要在http://jqueryui.com/download页面下载时多做一个步骤——指定css scope
点开Advanced Theme Settings,指定css scope,一般为css class的命名方式 

点击CSS Scope后面的 按钮,你会发现css scope是专门针对多主题应用。

下面是完整的代码:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     <html xmlns="http://www.w3.org/1999/xhtml">
     <head>
     <title>多主题</title>
     <link rel="shortcut icon" href="/images/favicon.ico" />
     <!--应用base主题和lightness主题-->
     <link rel="Stylesheet" type="text/css" href="themes/base/jquery.ui.all.css" />
     <link rel="Stylesheet" type="text/css" href="themes/theme_lightness/jquery.ui.all.css" />
     <link rel="Stylesheet" type="text/css" href="themes/demos.css" />
     <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
     <script type="text/javascript" src="themes/ui/jquery.ui.core.js"></script>
     <script type="text/javascript" src="themes/ui/jquery.ui.widget.js"></script>
     <script type="text/javascript" src="themes/ui/jquery.ui.accordion.js"></script>
     <script type="text/javascript">
     $(function() {
     $(".accordion").accordion({
     collapsible: true
     });
     });
</script>
     </head>
     <body>
     <div class="demo">
     <h1> Base Demo</h1>
     <div class="accordion">
     <h3> <a href="#">Section 1</a></h3>
     <div>
     <p> A.</p>
     </div>
     <h3> <a href="#">Section 2</a></h3>
     <div>
     <p> B. </p>
     </div>
     </div>
     <div class="space"> </div>
     <h1> Lightness Demo</h1>
     <!--主题中如果包含css scope,需要指定css scope,才能让主题生效-->
     <div class="lightness">
     <div class="accordion">
     <h3> <a href="#">Section 1</a></h3>
     <div>
     <p> A.</p>
     </div>
     <h3> <a href="#">Section 2</a></h3>
     <div>
     <p> B. </p>
     </div>
     </div>
     </div>
     </div>
     </body>
     </html>
     

效果如下:

三、jqgrid的使用方式

上面的两大步都是为了使用jqgrid做准备,冗长的叙述和截图看起来很多,其实知道是jquery ui是怎么回事儿以后就会觉得很简单,步骤也不多。

jqgrid的项目地址:http://www.trirand.com/blog/,目前最新的版本是4.3的,也是我正在使用的版本。

1. jqgrid的local data使用方式

请看代码示例1

<script type="text/javascript">
     var mydata = [
     { id: "1", invdate: "2010-05-24", name: "test", note: "note", tax: "10.00", total: "2111.00" },
     { id: "2", invdate: "2010-05-25", name: "test2", note: "note2", tax: "20.00", total: "320.00" },
     { id: "3", invdate: "2007-09-01", name: "test3", note: "note3", tax: "30.00", total: "430.00" },
     { id: "4", invdate: "2007-10-04", name: "test", note: "note", tax: "10.00", total: "210.00" },
     { id: "5", invdate: "2007-10-05", name: "test2", note: "note2", tax: "20.00", total: "320.00" },
     { id: "6", invdate: "2007-09-06", name: "test3", note: "note3", tax: "30.00", total: "430.00" },
     { id: "7", invdate: "2007-10-04", name: "test", note: "note", tax: "10.00", total: "210.00" },
     { id: "8", invdate: "2007-10-03", name: "test2", note: "note2", amount: "300.00", tax: "21.00", total: "320.00" },
     { id: "9", invdate: "2007-09-01", name: "test3", note: "note3", amount: "400.00", tax: "30.00", total: "430.00" },
     { id: "11", invdate: "2007-10-01", name: "test", note: "note", amount: "200.00", tax: "10.00", total: "210.00" },
     { id: "12", invdate: "2007-10-02", name: "test2", note: "note2", amount: "300.00", tax: "20.00", total: "320.00" },
     { id: "13", invdate: "2007-09-01", name: "test3", note: "note3", amount: "400.00", tax: "30.00", total: "430.00" },
     { id: "14", invdate: "2007-10-04", name: "test", note: "note", amount: "200.00", tax: "10.00", total: "210.00" },
     { id: "15", invdate: "2007-10-05", name: "test2", note: "note2", amount: "300.00", tax: "20.00", total: "320.00" },
     { id: "16", invdate: "2007-09-06", name: "test3", note: "note3", amount: "400.00", tax: "30.00", total: "430.00" },
     { id: "17", invdate: "2007-10-04", name: "test", note: "note", amount: "200.00", tax: "10.00", total: "210.00" },
     { id: "18", invdate: "2007-10-03", name: "test2", note: "note2", amount: "300.00", tax: "20.00", total: "320.00" },
     { id: "19", invdate: "2007-09-01", name: "test3", note: "note3", amount: "400.00", tax: "30.00", total: "430.00" },
     { id: "21", invdate: "2007-10-01", name: "test", note: "note", amount: "200.00", tax: "10.00", total: "210.00" },
     { id: "22", invdate: "2007-10-02", name: "test2", note: "note2", amount: "300.00", tax: "20.00", total: "320.00" },
     { id: "23", invdate: "2007-09-01", name: "test3", note: "note3", amount: "400.00", tax: "30.00", total: "430.00" },
     { id: "24", invdate: "2007-10-04", name: "test", note: "note", amount: "200.00", tax: "10.00", total: "210.00" },
     { id: "25", invdate: "2007-10-05", name: "test2", note: "note2", amount: "300.00", tax: "20.00", total: "320.00" },
     { id: "26", invdate: "2007-09-06", name: "test3", note: "note3", amount: "400.00", tax: "30.00", total: "430.00" },
     { id: "27", invdate: "2007-10-04", name: "test", note: "note", amount: "200.00", tax: "10.00", total: "210.00" },
     { id: "28", invdate: "2007-10-03", name: "test2", note: "note2", amount: "300.00", tax: "20.00", total: "320.00" },
     { id: "29", invdate: "2007-09-01", name: "test3", note: "note3", amount: "400.00", tax: "30.00", total: "430.00"}];
     $(document).ready(function() {
     $("#gridTable").jqGrid({
     data: mydata,
     datatype: "local",
     height: 150,
     rowNum: 10,
     rowList: [10, 20, 30],
     colNames: ['Inv No', 'Date', 'Client', 'Amount', 'Tax', 'Total', 'Notes'],
     colModel: [
     { name: 'id', index: 'id', width: 60, sorttype: "int" },
     { name: 'invdate', index: 'invdate', width: 90, sorttype: "date", formatter: "date" },
     { name: 'name', index: 'name', width: 100 },
     { name: 'amount', index: 'amount', width: 80, align: "right", sorttype: "float", formatter: "number" },
     { name: 'tax', index: 'tax', width: 80, align: "right", sorttype: "float" },
     { name: 'total', index: 'total', width: 80, align: "right", sorttype: "float" },
     { name: 'note', index: 'note', width: 150, sortable: false }
     ],
     sortname: 'id',
     sortorder: 'desc',
     pager: "#gridPager",
     viewrecords: true,
     caption: "Manipulating Array Data"
     });
     });
</script>
<table id="gridTable">
</table>
<div id="gridPager">
</div>

jqgrid有几个较为关键的属性:

  • data:指定jqgrid的数据源
  • datatype:数据源的格式——local,javascript,function,json,jsonstring,xml。默认的数据源格式为xml
  • colNames:列名
  • colModels:指定列的属性,例如name用于关联数据源,index用于排序时的索引
  • sortname和sortorder分别指定jqgrid首次加载时的排序字段和排序方式
  • pager:指定分页容器。

上面这个例子的效果如下图:

2. jqgrid的server data之loadonce方式

实际的应用中数据都来源于后端,local方式基本不会使用。jqgrid中有一种loadonce的方式,当然后台提供所有的数据,分页、排序功能都由客户端自己去实现。数据少的时候用这种方式是最为快速的,毕竟只做一次请求后台除了输出数据外不需要再写其他的代码了。

请看代码示例:

 <script type="text/javascript">
     $(document).ready(function() {
     $("#gridTable").jqGrid({
     url : 'data/test.json',
     datatype: 'json',
     height: 150,
     rowNum: 10,
     rowList: [10, 20, 30],
     colNames: ['Inv No', 'Date', 'Client', 'Amount', 'Tax', 'Total', 'Notes'],
     colModel: [
     { name: 'id', index: 'id', width: 60, sorttype: "int" },
     { name: 'invdate', index: 'invdate', width: 90, sorttype: "date", formatter: "date" },
     { name: 'name', index: 'name', width: 100 },
     { name: 'amount', index: 'amount', width: 80, align: "right", sorttype: "float", formatter: "number" },
     { name: 'tax', index: 'tax', width: 80, align: "right", sorttype: "float" },
     { name: 'total', index: 'total', width: 80, align: "right", sorttype: "float" },
     { name: 'note', index: 'note', width: 150, sortable: false }
     ],
     loadonce: true,
     sortname: 'id',
     sortorder: 'desc',
     pager: "#gridPager",
     viewrecords: true,
     caption: "Manipulating Array Data"
     });
     });
</script>
<table id="gridTable">
</table>
<div id="gridPager">
</div>

这段代码和local data的形式中不同之处在于:

(1). url:指定了请求的数据源。(test.json文件的内容和第1个例子中的mydata 内容一样)
(2). datatype:将数据格式改为json,而不是local
(3). loadonce: true(默认情况下为false,显示指定只加载一次数据)

OK,编译运行,但是结果却没有出现例子1中的效果图,jqgrid里面完全没有数据显示。
页面LoadOnce.aspx效果:

这时候jqgrid中一个更为关键的属性出现了,jsonReader。既然指定了数据格式为json,那么后端传过来的数据格式总不能我说什么就是什么吧,{"id":1, "name":"keepfool"}和{1,"keepfool"}都是正确的json数据,当传到前端时,前端怎么会知道要匹配哪一种形式?jsonReader顾名思义,就是用来读取json的,当然也要给它定个规矩。

让我们来看看http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data中默认的json格式是怎么样的吧

当没有设置jsonReader属性时,提供的json格式应该是下面这种形式的: 

它让你指定total,page,records属性(分别对应总页数、当前页、记录总数);rows属性,还必须指定id和cell属性,cell属性里面仅仅是单元格的值,还不能包括列名。如果按照默认的jsonReader来读取数据,你可能会写出如下构造json的代码:

public class MyOrder : IHttpHandler
     {
     public void ProcessRequest(HttpContext context)
     {
     context.Response.ContentType = "application/json";
     string sql = "select top 100 OrderID,CustomerID,ShipName,OrderDate from Orders ";
     DataTable dt = SqlHelper.ExecuteDataset(sql).Tables[0];
     IList<object> rowObjects = new List<object>();
     // 每页显示记录数
     int pageSize = 10;
     // 记录总数
     int rowCount = dt.Rows.Count;
     // 列数
     int columnCount = dt.Columns.Count;
     // 总页数
     int pageCount = rowCount%pageSize == 0 ? rowCount/pageSize : rowCount/pageSize + 1;
     int ID = 1;
     foreach (DataRow dr in dt.Rows)
     {
     var cellValue = new string[columnCount];
     for (var i = 0; i < cellValue.Length; i++)
     {
     cellValue[i] = dr[i].ToString();
     }
     // 创建row对象
     var rowObj = new
     {
     id = ID,
     cell = cellValue
     };
     rowObjects.Add(rowObj);
     ID++;
     }
     var resultObj = new
     {
     total = pageCount, // 总页数
     page = 1, // 由于客户端是loadonce的,page也可以不指定
     records = rowCount, // 总记录数
     rows = rowObjects // 数据
     };
     string json = JsonConvert.SerializeObject(resultObj);
     context.Response.Write(json);
     }
     public bool IsReusable
     {
     get
     {
     return false;
     }
     }
     }

请求页面LoadOnceOrders.aspx效果:

 

但是这里存在一个小bug,下面的分页按钮不起作用了,当点击排序或者选择每页显示记录数时,分页按钮又可以用了。这个bug仅在loadonce为true时会出现。

http://www.trirand.com/jqgridwiki/doku.php?id=wiki:options页面中也对loadonce属性有所说明

3. jqgrid的jsonReader

上面的例子中没有设置jsonReader属性,那么就得按照默认的jsonReader提供json数据。上面的json数据会让我们感觉有一些怪异,rows属性中的id和cell我们不需要,total应该表示为pagecount, records应该表示为total在语义上更易读通,而且row中的每一列都应当是键值对这种形式。

寻常情况下我们提供的json格式应该是这样的:

{
     "pagecount":10,
     "pageindex":1,
     "total":100,
     "rows":[
     {
     "id":1,
     "name":"keepfool"
     },
     {
     "id":2,
     "name":"pai"
     }
     ...
     ]
}

pagecount表示总页数,pageindex表示当前页,total表示总记录数,rows表示记录。既然这样,我们的jsonReader就得改写,而且后台也应当提供这样的数据。

LoadOnceOrder2.aspx页面的jsonReader(其他设置和LoadOnceOrders.aspx页面一致)

jsonReader: {
     root: "rows",
     page: "pageindex",
     total: "pagecount",
     records: "total",
     repeatitems: false,
     id: "0"
}

请注意这里的repeatitems属性,当repeatitems=false时,jqgrid会根据返回的json数据搜索列名,这个列名对应colModel中的名字
为LoadOnceOrder2.aspx页面提供Json数据的MyOrder2.ashx的http处理程序

public class MyOrder2 : IHttpHandler
     {
     public void ProcessRequest(HttpContext context)
     {
     context.Response.ContentType = "application/json";
     string sql = "select top 100 OrderID,CustomerID,ShipName,OrderDate from Orders ";
     DataTable dt = SqlHelper.ExecuteDataset(sql).Tables[0];
     // 每页显示记录数
     int pageSize = 10;
     // 记录总数
     int rowCount = dt.Rows.Count;
     // 总页数
     int pageCount = rowCount % pageSize == 0 ? rowCount / pageSize : rowCount / pageSize + 1;
     var resultObj = new DataResult
     {
     // 总页数
     PageCount = pageCount,
     // 当前页
     PageIndex = 1,
     // 总记录数
     Total = rowCount,
     // 数据
     Data = dt
     };
     string resultJson = JsonHelper.Serialize(resultObj);
     context.Response.Write(resultJson);
     }
     public bool IsReusable
     {
     get { return false; }
     }
     }

DataResult类的代码很简单:

      /// <summary>
     /// 数据结果
     /// </summary>
     public class DataResult
     {
      
                       
                    
                    

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
asp.net2.0中通过压缩ViewState改善性能发布时间:2022-07-10
下一篇:
ASP.NETWebAPI使用记录发布时间:2022-07-10
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap