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






4.88/5 (25投票s)
如何使用 jQuery DataTables 实现高级列过滤。
目录
引言
在本文中,我将解释如何使用 jQuery DataTables 插件和 ASP.NET MVC 在完全 AJAX 化的表中实现高级过滤。下图中显示了一个带有列过滤器的表示例。
您可以看到,除了表格的其他功能(分页、排序)之外,此表格还在每一列中放置了单独的过滤器。本文的目标是展示如何实现这样的表格,每当用户更改过滤器时,表格的内容都会通过 AJAX 调用刷新。
jQuery DataTables^ 插件主要有两种工作模式:
- 客户端处理模式 - 在此模式下,您只需在页面上放置一个普通的 HTML 表格,插件就会将所有必要的操作添加为 JavaScript 功能。在此模式下,插件将直接处理表格中的行,因此您无需实现任何内容 - 插件将使用它在表格中找到的行来处理过滤、分页和排序。
- 服务器端处理模式 - 其中表格完全 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 应用程序集成系列的一部分。您可能还想查看此组中的其他文章:
- jQuery DataTables 与 ASP.NET MVC 集成
- ASP.NET MVC 可编辑表格
- 使用 Ajax 在 ASP.NET MVC 中刷新 DataTable 的内容
- 创建可展开的主-明细表格
在这些文章中,您可能会找到大量关于在 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 的一个附加插件,它在每列中添加过滤器,并允许用户按列过滤数据。
此外,您可以在插件配置中定义要在每列中使用哪种类型的过滤器。在上面的示例中,第一列将按数字范围过滤,第二列过滤器将是纯文本,第三列将放置一个选择列表,最后一列将使用两个日期选择器按日期范围过滤。脚本中的前两行用于设置日期选择器中的日期格式。
作为此脚本的结果,将在表格底部注入单个列过滤器,如下图所示。这只是过滤的可选配置 - 作为替代,您可以将过滤器放置在标题中,甚至放置在外部表单中。
列过滤器也是 AJAX 化的。每当用户在列过滤器中键入内容时,值都会发送到控制器操作。在图中,您可以看到发送到控制器操作的 AJAX 请求的一部分。在 sSearch_0
、sSearch_1
、sSearch_2
和 sSearch_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_0
、sSearch_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 插件的一些基本功能,但是还有很多其他设置可以自定义。其中一些是:
- 能够将过滤器放置在标题行中,甚至放置在表格外部,而不是放置在底部行中。
- 能够定义所谓的过滤延迟。为了防止过多的 AJAX 调用,您可以定义当用户键入至少 N 个字符后,表格才会刷新,并发送新的 AJAX 请求。
- 能够在过滤器中使用正则表达式。
下图显示了一个过滤配置示例,其中过滤器放置在一个单独的表单中:
每次更改表单中的过滤条件时,表格都会刷新。您可以在 插件站点 上查看 Column filter 插件的其他功能。此外,DataTables 和 Column Filter 插件不需要以 AJAX 化的服务器端处理模式工作。如果您不想创建处理请求的操作,可以仅将所有行输出到表格的 TBODY
中,让它们在纯客户端模式下工作。如果您想在此模式下使用它们,可能需要查看 使用 jQuery DataTables 插件增强 HTML 表格 文章,其中我解释了在纯客户端模式下可以使用这些插件做什么。请注意,不应将客户端模式用于大量数据。如果您有大量记录需要处理,则应考虑使用服务器端处理模式。
历史
- 2012 年 3 月 13 日:初始版本