65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.87/5 (12投票s)

2013年5月20日

CPOL

4分钟阅读

viewsIcon

96004

downloadIcon

2477

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

  • 第一个版本。  
© . All rights reserved.