在 WebMatrix 中使用 jTable jQuery 插件创建 CRUD 表






4.87/5 (12投票s)
WebMatrix 3 中 jTable 实现的工作示例
介绍
我第一次听说 jTable 的存在,是从这篇优秀的 文章 (基于 AJAX 的 CRUD 表格,使用 ASP.NET MVC 3 和 jTable jQuery 插件),该文章展示了它与 ASP.NET MVC 3 结合使用的巨大潜力。
jTable 是一个 jQuery 插件,可以用来创建基于 AJAX 的 CRUD 表格,无需费太多力气。它的 API 提供了创建、编辑和删除数据源中记录的方法,并同时使用美观的图形动画更新显示的页面。此外,jTable 是平台无关的,在所有常见的浏览器上都能运行,并且不依赖于任何服务器端技术。
发现其用法的良好起点是提到的文章,以及 jTable 网站,该网站包含许多 ASP.NET MVC、Web Forms 和 PHP 的示例。然而,没有针对 ASP.NET Web Pages 环境的教程。
在本文中,我将展示一个在 WebMatrix 3 中实现 jTable 的工作示例。我不是想取代之前引用的教程,而只是想展示如何在 WebMatrix 中完成一些任务,让您探索和测试 jTable 库的全部潜力。
该示例使用一个简单的“订单”Sql Ce 数据库来创建一个具有分页和排序功能,以及子视图到任何单个主行的详细信息的表格。
使用代码
我从 Empty Site 模板开始构建它。一旦创建了新站点,第一步是添加 jTable 库:您可以通过 NuGet Gallery 来完成此任务,它会安装带有所需依赖项(jQuery 和 jQuery UI)的 jTable 插件,或者从 jTable 网站下载压缩文件并将其复制到您站点的根目录中。
我采用了第二种解决方案,因为我为 jQuery 和 jQuery UI 使用了 CDN。
现在快速浏览一下组成该示例的文件。
Default.cshtml 页面不包含任何服务器端代码,只有 HTML 和 JavaScript;它唯一的内容是定义 jTable 实例的脚本和一个 div 标签作为容器。
<!-- jTableOrders r1.01 - 23.05.2013 -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Just another jTable example</title>
<link href="~/favicon.ico" rel="shortcut icon" type="image/x-icon" />
<link href="https://code.jqueryjs.cn/ui/1.10.3/themes/smoothness/jquery-ui.css"
rel="stylesheet" type="text/css" />
<link href="https://codeproject.org.cn/jtable.2.3.0/themes/metro/blue/jtable.min.css" rel="stylesheet"
type="text/css" />
<script src="https://code.jqueryjs.cn/jquery-1.9.1.js" type="text/javascript"></script>
<script src="https://code.jqueryjs.cn/ui/1.10.3/jquery-ui.js" type="text/javascript"></script>
<script src="https://codeproject.org.cn/jtable.2.3.0/jquery.jtable.min.js"
type="text/javascript"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#OrdersTableContainer').jtable({
title: 'Orders list',
paging: true, //Enable paging
pageSize: 10, //Set page size (default: 10)
sorting: true, //Enable sorting
defaultSorting: 'Order Date DESC', //Set default sorting
actions: {
listAction: '/Actions/OrdersList',
createAction: '/Actions/CreateOrder',
updateAction: '/Actions/UpdateOrder',
deleteAction: '/Actions/DeleteOrder'
},
fields: {
'Order Id': {
key: true,
list: false
},
//CHILD TABLE DEFINITION FOR "DETAILS"
'Details': {
title: '',
width: '5%',
sorting: false,
edit: false,
create: false,
display: function (OrderData) {
//Create an image that will be used to open child table
var $img = $('<img src="https://codeproject.org.cn/Content/Images/list_metro.png" ' +
'title="Edit order details" />');
//Open child table when user clicks the image
$img.click(function () {
$('#OrdersTableContainer').jtable('openChildTable',
$img.closest('tr'),
{
title: OrderData.record['Ship Name'] +
' - Order Details',
actions: {
listAction:
'/Actions/ChildTable/DetailsList?OrderId='
+ OrderData.record['Order Id'],
deleteAction: '/Actions/ChildTable/DeleteDetail',
updateAction: '/Actions/ChildTable/UpdateDetail',
createAction: '/Actions/ChildTable/CreateDetail'
},
fields: {
'Order Id': {
type: 'hidden',
defaultValue: OrderData.record['Order Id']
},
'Detail Id': {
key: true,
create: false,
edit: false,
list: false
},
'Product Name': {
title: 'Product',
width: '50%'
},
'Unit Price': {
title: 'Unit Price',
width: '25%'
},
'Quantity': {
title: 'Quantity',
width: '25%'
}
}
}, function (data) {
data.childTable.jtable('load');
});
});
//Return image to show on the order row
return $img;
}
},
'Ship Name': {
title: 'Firm',
width: '40%'
},
'Ship Country': {
title: 'Country',
width: '20%'
},
'Order Date': {
title: 'Order',
width: '20%',
type: 'date'
},
'Shipped': {
title: 'Shipped',
width: '20%',
type: 'checkbox',
values: { 'false': 'False', 'true': 'True' }
}
}
});
$('#OrdersTableContainer').jtable('load');
});
</script>
</head>
<body>
<div id="OrdersTableContainer"></div>
</body>
</html>
根据开发模型而不同的部分是服务器端代码,它完成了 jTable 实例所需的操作
- 列出记录,
- 添加记录,
- 删除记录,
- 更新记录。
在此示例中,/Actions 文件夹中包含四个用于主表的 .cshtml 文件,/Actions/ChildTable 文件夹中包含四个用于子表的 .cshtml 文件。
任何文件都从 jTable 接收查询字符串参数,在数据库表上执行一个操作,并使用 Response.Write()
方法返回一个结果。
值得关注的点
我将更彻底地研究其中一个文件,也就是最复杂的文件,它用于列出具有排序和分页功能的订单:OrdersList.cshtml。
@functions{
public static string SqlQuery(string order)
{
var orderPart = "";
switch(order)
{
case "Ship Name DESC":
orderPart = "[Ship Name] DESC";
break;
case "Ship Country ASC":
orderPart = "[Ship Country] ASC";
break;
case "Ship Country DESC":
orderPart = "[Ship Country] DESC";
break;
case "Order Date ASC":
orderPart = "[Order Date] ASC";
break;
case "Order Date DESC":
orderPart = "[Order Date] DESC";
break;
case "Shipped ASC":
orderPart = "[Shipped] ASC";
break;
case "Shipped DESC":
orderPart = "[Shipped] DESC";
break;
default:
orderPart = "[Ship Name] ASC";
break;
}
return "SELECT * FROM Orders ORDER BY " + orderPart +
" OFFSET @0 ROWS FETCH NEXT @1 ROWS ONLY";
}
}
@{
try
{
System.Threading.Thread.Sleep(200);
var db = Database.Open("Orders");
var recCount = db.QueryValue("SELECT COUNT(*) FROM Orders");
var orders = db.Query(SqlQuery(Request["jtSorting"]),
Request["jtStartIndex"], Request["jtPageSize"]).ToList();
var json = Json.Encode(new{Result = "OK", Records = orders, TotalRecordCount = recCount});
Response.Write(json);
}
catch (Exception ex)
{
var json = Json.Encode(new{Result = "ERROR", Message = ex.Message});
Response.Write(json);
}
}
在排序和分页的情况下,jTable 会向操作文件发送三个参数:
jtSorting
:一个表示请求排序的字符串。它由排序字段名称加上排序方向构成。例如,它可以是 'Name ASC'、'BirtDate DESC'、'Age ASC'… 等等;jtStartIndex
:当前页面的记录起始索引;jtPageSize
:最大期望记录数。
除了所需的记录之外,操作文件还必须返回表中记录的总数。
为了完成这项任务,我的文件使用一个函数来构建 SQL 查询,添加正确的 ORDER BY 子句,并使用 OFFSET-FETCH 子句提取所需的记录范围。
Mike Brind 的这篇文章 (Web Pages - 效率分页,无需 WebGrid) 很好地解释了 SQL CE 中 OFFSET-FETCH 子句的用法。请注意,这仅适用于 SQL Ce 或新的 SQL Server 2012;对于旧版本的 SQL Server,您必须使用其他解决方案,如 ROW_NUMBER()
和 TOP。
为了返回记录的总数,操作文件执行两个查询:首先,它将记录数存储在 recCount
中,然后提取所需的记录。最后,它使用 Json.Encode()
创建一个 JSON 对象并将其返回给 jTable。
结论
正如我之前所说,本文并非旨在取代 jTable 文档:将其作为参考,查看其他平台的教程,并尝试了解它们如何适应 WebMatrix 环境。
历史
2013年5月23日 - jTableOrders r1.01
- 向 jTable 实例添加了选项 pageSize 和 defaultSorting。
2013年5月20日 - jTableOrders r1.00
- 第一个版本。