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

jQuery DataTables 在 ASP.NET MVC 中的高级过滤(jQuery DataTables 与 ASP.NET MVC 集成 - 第 V 部分)

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.88/5 (25投票s)

2012 年 3 月 13 日

CPOL

11分钟阅读

viewsIcon

277322

downloadIcon

11369

如何使用 jQuery DataTables 实现高级列过滤。

目录

  1. 引言
  2. 背景
  3. Using the Code
    1. 模型
    2. 视图
    3. 控制器 (Controller)
  4. 结论
  5. 历史

引言

在本文中,我将解释如何使用 jQuery DataTables 插件和 ASP.NET MVC 在完全 AJAX 化的表中实现高级过滤。下图中显示了一个带有列过滤器的表示例。

331855/jquery-datatables-column-filter.png

您可以看到,除了表格的其他功能(分页、排序)之外,此表格还在每一列中放置了单独的过滤器。本文的目标是展示如何实现这样的表格,每当用户更改过滤器时,表格的内容都会通过 AJAX 调用刷新。

jQuery DataTables^ 插件主要有两种工作模式:

  1. 客户端处理模式 - 在此模式下,您只需在页面上放置一个普通的 HTML 表格,插件就会将所有必要的操作添加为 JavaScript 功能。在此模式下,插件将直接处理表格中的行,因此您无需实现任何内容 - 插件将使用它在表格中找到的行来处理过滤、分页和排序。
  2. 服务器端处理模式 - 其中表格完全 AJAX 化。在此模式下,您应在页面 HTML 中放置一个空表格,并指定 jQuery DataTables^ 插件应从哪个 URL 获取要显示的行。在此模式下,jQuery DataTables^ 插件将处理所有用户交互,并通过 AJAX 调用将有关当前页面、过滤器条件和排序的信息发送到您的服务器端页面。您需要做的就是创建一个控制器,该控制器将接收参数并返回加载到表格正文中的结果。

如果要添加客户端模式下的分页、排序和过滤,您只需要一行 JavaScript 代码:

$("table#myTable").dataTable().columnFilter();

此行查找 ID 为 myTable 的表格,应用 dataTable 插件(该插件添加分页和排序功能),然后应用 columnFilter 插件(该插件将过滤器放置在各个列中)。这就是您在客户端模式下需要做的全部。可选地,您可以通过传递不同的参数来自定义插件 - 有关更多示例,请参阅 DataTables Column Filter^ 网站。

但是,如果您处理大型数据集,您可能希望实现一些 AJAX 化的表格,并将过滤条件发送到服务器。这需要您添加更多代码,因此我将在本文中介绍这种情况。

本文是关于 jQuery DataTables^ 插件与 ASP.NET MVC Web 应用程序集成系列的一部分。您可能还想查看此组中的其他文章:

  1. jQuery DataTables 与 ASP.NET MVC 集成
  2. ASP.NET MVC 可编辑表格
  3. 使用 Ajax 在 ASP.NET MVC 中刷新 DataTable 的内容
  4. 创建可展开的主-明细表格

在这些文章中,您可能会找到大量关于在 ASP.NET MVC 中使用 jQuery DataTables^ 插件的有用信息。如果您还没有阅读第一篇文章,我建议您也阅读一下,因为它包含有关 jQuery DataTables 与 ASP.NET MVC 应用程序集成的一些重要细节。

背景

jQuery DataTables 是一个出色的 jQuery 插件,可让您在表格中显示和管理信息。要在 MVC 应用程序中使用 jQuery Datatables 插件,您需要执行以下设置步骤。

首先,您需要在页面中放置一个表示表格结构的空表格。下面的代码显示了一个表格示例:

<table class="display" id="example">
    <thead>
        <tr>
            <th>ID</th><th>Company</th><th>Town</th><th>Date</th>
        </tr>
    </thead>
    <tbody>

    </tbody>
    <tfoot>
        <tr>
            <th>ID</th><th>Company</th><th>Town</th><th>Date</th>
        </tr>
    </tfoot>
</table>

在此表格中定义了表格的固定部分,如表头、表尾,但正文是空的。使用 DataTables 插件,将在正文中显示的数据将通过 AJAX 调用动态加载。

然后,您需要一个控制器,该控制器具有一个用于向 DataTables 插件提供数据的操作。此控制器显示在以下列表中:

public class HomeController
{
   public JsonResult DataProviderAction(string sEcho, int iDisplayStart, int iDisplayLength)
   {
    //Implementation of action body 
   }
}

此处未显示控制器方法的实际实现。如果您不熟悉将 DataTables 插件集成到 MVC 应用程序中,您可以在本系列的第一篇文章中找到更多信息 - jQuery DataTables 与 ASP.NET MVC 集成。在那里,您可以找到集成插件和实现此控制器操作所需的一切。此外,您在附加的代码示例中也有此方法。

最后,您需要将空 HTML 表格与控制器绑定,以便开始显示数据。这可以通过以下 jQuery 调用完成:

<script type="text/javascript" charset="utf-8">
$(document).ready( function () {
      $('#example').dataTable({
                                "bServerSide": true,
                                "sAjaxSource": "/Home/DataProviderAction"
                              });
});
</script>

此初始化调用定义将通过 AJAX 调用从服务器端获取数据,并且 AJAX 源将使用 URL "/Home/DataProviderAction" 上的操作。结果是,您将获得一个功能齐全的表格,其中包含分页、排序和过滤功能,就像下图所示的那样:

此表格完全 AJAX 化 - 每次用户在客户端进行某些更改时(例如,更改页面或排序顺序,在搜索文本框中键入任何内容),都会向控制器发送 AJAX 请求,并在表格中显示新数据集。

本文的目标是向您展示如何将默认的、全局的单关键字搜索替换为高级多列过滤器。我将向您展示如何使用各种类型的过滤器,例如下拉列表、日期范围和数字范围。

使用代码

代码遵循标准的模型-视图-控制器(MVC)架构。

模型

模型是一个简单的类,包含公司数据。我们需要以下字段:公司 ID、名称、日期和城市。下面显示了公司模型类的源代码:

public class Company
{
    public int ID { get; set; }
    public string Name { get; set; }
    public DateTime DateCreated { get; set; }
    public string Town { get; set; }
}

视图

由于数据展示是在客户端完成的,因此经典的视图页面非常简单。它包含一个简单的 HTML 表格,并用 jQuery DataTables 插件“装饰”。例如

@{
    Layout = null;
}

<!DOCTYPE html>
<html>    
    <head>   
        <title>jQuery DataTables/ASP.NET MVC Filtering</title>
        <link href="~/Content/dataTables/demo_table.css" rel="stylesheet" type="text/css" />
        <script src="~/Scripts/jQuery-1.4.4.min.js" type="text/javascript"></script>
        <script src="~/Scripts/jQuery.dataTables.min.js" type="text/javascript"></script>
        <script src="~/Scripts/init.js" type="text/javascript"></script>
    </head>
    <body>
        <table id="myDataTable" class="display">
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Company name</th>
                    <th>Town</th>
                    <th>Date</th>
                </tr>
            </thead>
            <tbody> 
            </tbody>
            <thead>
                <tr>
                    <th>ID</th>
                    <th>Company name</th>
                    <th>Town</th>
                    <th>Date</th>
                </tr>
            </thead>
        </table>
    </body>
</html>

此外,作为视图的一部分,我们需要使用 jQuery DataTables 插件初始化表格并设置单个列过滤。这部分将在下面的列表所示的 init.js 文件中实现:

$(document).ready(function () {
               
    // Setup JQuery UI date picker format to dd/mm/yy
    $.datepicker.regional[""].dateFormat = 'dd/mm/yy';
    $.datepicker.setDefaults($.datepicker.regional['']);

    $('#myDataTable').dataTable({
                                        "bServerSide": true,
                                        "sAjaxSource": "/Home/DataProviderAction"
        }).columnFilter({
                        "aoColumns": [
                                       { "type": "number-range" },
                                       { "type": "text" },
                                       { "type": "select" },
                                       { "type": "date-range" }
                                     ]
                     });
});

标准的 jQuery DataTables 插件已应用于表格,并以服务器端处理模式进行配置。此初始化脚本将添加标准的 DataTables 功能(分页、关键字过滤和排序)。

为了设置高级列过滤,在此示例中,我们使用了 DataTables Column Filtering 附加组件。这是 DataTables 的一个附加插件,它在每列中添加过滤器,并允许用户按列过滤数据。

此外,您可以在插件配置中定义要在每列中使用哪种类型的过滤器。在上面的示例中,第一列将按数字范围过滤,第二列过滤器将是纯文本,第三列将放置一个选择列表,最后一列将使用两个日期选择器按日期范围过滤。脚本中的前两行用于设置日期选择器中的日期格式。

作为此脚本的结果,将在表格底部注入单个列过滤器,如下图所示。这只是过滤的可选配置 - 作为替代,您可以将过滤器放置在标题中,甚至放置在外部表单中。

331855/jquery-datatables-column-filter-xhr.png

列过滤器也是 AJAX 化的。每当用户在列过滤器中键入内容时,值都会发送到控制器操作。在图中,您可以看到发送到控制器操作的 AJAX 请求的一部分。在 sSearch_0sSearch_1sSearch_2sSearch_3 中发送的是来自过滤器的值。请注意,单个过滤器(文本框和选择框)作为单个值发送,而数字范围和日期过滤器则将上限和下限组合在同一个值中,并用波浪号(~)字符分隔。如果过滤器中没有值,则会发送空字符串作为边界。

控制器

控制器是集成中最重要的部分。它应该处理插件发送的 AJAX 请求,接收包含过滤条件的参数,并返回符合条件的公司的列表。完整的控制器代码显示在以下列表中:

public JsonResult DataProviderAction(string sEcho, int iDisplayStart, int iDisplayLength)
{
    var idFilter = Convert.ToString(Request["sSearch_0"]);
    var nameFilter = Convert.ToString(Request["sSearch_1"]);
    var townFilter = Convert.ToString(Request["sSearch_2"]);
    var dateFilter = Convert.ToString(Request["sSearch_3"]);

    var fromID = 0;
    var toID =  0;
    if (idFilter.Contains('~'))
    {
        //Split number range filters with ~
        fromID = idFilter.Split('~')[0] == "" ? 0 : Convert.ToInt32(idFilter.Split('~')[0]);
        toID = idFilter.Split('~')[1] == "" ? 0 : Convert.ToInt32(idFilter.Split('~')[1]);
    }
    DateTime fromDate = DateTime.MinValue;
    DateTime toDate = DateTime.MaxValue;
    if(dateFilter.Contains('~')){
        //Split date range filters with ~
        fromDate = dateFilter.Split('~')[0] == "" ? 
          DateTime.MinValue : Convert.ToDateTime(dateFilter.Split('~')[0]);
        toDate = dateFilter.Split('~')[1] == "" ? 
          DateTime.MaxValue : Convert.ToDateTime(dateFilter.Split('~')[1]);  
    }

    var filteredCompanies = DataRepository.GetCompanies()
                            .Where(c => (fromID == 0 || fromID < c.ID)
                                        &&
                                        (toID == 0 || c.ID < toID)
                                        &&
                                        (nameFilter == "" || 
                                         c.Name.ToLower().Contains(nameFilter.ToLower()))
                                        &&
                                        (townFilter == "" || c.Town == townFilter)
                                        &&
                                        (fromDate == DateTime.MinValue || 
                                                     fromDate < c.DateCreated)
                                        &&
                                        (toDate == DateTime.MaxValue || c.DateCreated < toDate)
                                    );

    //Extract only current page
    var displayedCompanies = filteredCompanies.Skip(iDisplayStart).Take(iDisplayLength);
    var result = from c in displayedCompanies 
                    select new[] { 
                                    Convert.ToString(c.ID),
                                    c.Name,
                                    c.Town,
                                    c.DateCreated.ToShortDateString() 
                                };
    return Json(new
                    {
                        sEcho = sEcho,
                        iTotalRecords = DataRepository.GetCompanies().Count(),
                        iTotalDisplayRecords = filteredCompanies.Count(),
                        aaData = result
                    },
                JsonRequestBehavior.AllowGet);
}

这里的第一项操作是从 Request 对象中获取过滤器框的值。jQuery DataTables 插件在 sSearch_0sSearch_1、...、sSearch_N 参数中发送这些参数,其中 N 是列数。使用两个值的范围过滤器(数字范围和日期范围过滤器)会将范围用 ~ 分隔,因此它们会按此字符拆分,第一个部分设置为下限,第二个部分设置为上限。此外,如果页面上只输入了下限或上限,则会设置默认值(数字范围边界为 0,日期范围边界为 MinDate/MaxDate)。如果范围过滤器中的值包含默认值,则不会应用过滤器。

加载过滤条件后,公司将被过滤。实现这一点有很多方法,例如,通过数据库中的 SQL 查询或存储过程,使用 LINQ 查询等。在本例中,我使用了 Where LINQ 函数,其中我构建了一个 lambda 表达式来根据过滤参数过滤公司。请注意,您可以根据您的需求更改此查询的逻辑。在此查询中,我使用了 AND 条件,但您也可以使用 OR。我还对范围过滤器使用了小于运算符,但如果需要,您可以使用小于等于。从 DataTables 的角度来看,这种服务器端逻辑是无关紧要的 - 只要您为过滤条件提供了一些结果,它就会正常工作。

一旦公司被过滤,它们就会被格式化为 JSON 数组,并作为视图的响应返回给插件。您可以在文章 jQuery DataTables 与 ASP.NET MVC 集成 中找到有关将 JSON 响应返回给插件的更多详细信息。此外,您可能会注意到在此代码中,我们使用了有关要在表格中显示的第一个记录(iDisplayStart)和要在表格中显示的当前页面的记录数(iDisplayLength)的信息。此 LINQ 查询有一个简单的分页命令(Skip(iDisplayStart).Take(iDisplayLength) 部分),它只显示用户当前正在查看的页面。在实际代码中,您应该同时处理按列排序,但这在此示例中并未显示。但是,您可以在 jQuery DataTables 与 ASP.NET MVC 集成 文章中找到有关集成的详细描述。

结论

在本文中,我解释了如何实现一个功能齐全的 AJAX 化表格,其中包含高级过滤器。如您所见,您只需要在视图端进行最少的工作 - 只有一个空表格和简单的 JavaScript,这些都可以轻松更改。

您需要做的就是创建一个控制器操作方法,该方法将处理插件发送的 AJAX 调用,并根据插件发送的条件进行过滤。

在本文中,我展示了 DataTables 和 Column filter 插件的一些基本功能,但是还有很多其他设置可以自定义。其中一些是:

  1. 能够将过滤器放置在标题行中,甚至放置在表格外部,而不是放置在底部行中。
  2. 能够定义所谓的过滤延迟。为了防止过多的 AJAX 调用,您可以定义当用户键入至少 N 个字符后,表格才会刷新,并发送新的 AJAX 请求。
  3. 能够在过滤器中使用正则表达式。

下图显示了一个过滤配置示例,其中过滤器放置在一个单独的表单中:

每次更改表单中的过滤条件时,表格都会刷新。您可以在 插件站点 上查看 Column filter 插件的其他功能。此外,DataTables 和 Column Filter 插件不需要以 AJAX 化的服务器端处理模式工作。如果您不想创建处理请求的操作,可以仅将所有行输出到表格的 TBODY 中,让它们在纯客户端模式下工作。如果您想在此模式下使用它们,可能需要查看 使用 jQuery DataTables 插件增强 HTML 表格 文章,其中我解释了在纯客户端模式下可以使用这些插件做什么。请注意,不应将客户端模式用于大量数据。如果您有大量记录需要处理,则应考虑使用服务器端处理模式。

历史

  • 2012 年 3 月 13 日:初始版本
© . All rights reserved.