ASP.NET MVC 可编辑表格(jQuery DataTables 与 ASP.NET MVC 集成 - 第二部分)






4.90/5 (69投票s)
使用 jQuery DataTables Editable 插件在 ASP.NET MVC 中创建具有标准 CRUD 功能的 datatable
目录
引言
本文的目的是展示如何在 ASP.NET MVC 中使用 jQuery/AJAX 和各种插件实现一个具有完整数据管理功能的表格。以下是目标功能的列表:
- 客户端分页、过滤、排序
- CRUD 操作 - 删除/编辑/添加记录
- 有效的客户端功能,其中大部分交互通过 AJAX 完成
我的意图是展示如何通过最少的努力,使用 jQuery DataTables Editable 插件来实现这些功能,从而轻松扩展 DataTable
的 CRUD 功能。此类表格的示例如下图所示:
图中所示的所有功能都是纯 JavaScript 增强功能 - 在服务器端,您只需生成一个纯 HTML 表格。您在表格中看到的一切都通过以下 JavaScript 调用在客户端实现:
$('table#myDataTable').dataTable().makeEditable();
这行代码找到 ID 为 "myDataTable
" 的表格,并应用两个 jQuery 插件,为表格添加上述所有功能。在本文的其余部分,我将向您展示如何实现和自定义此插件。
本文可视为系列文章的第二部分,该系列文章描述了如何使用 jQuery、ASP.NET MVC 和 jQuery DataTables 插件实现有效的 Web 2.0 界面。在我的上一篇文章中,我描述了如何实现一个具有服务器端分页、过滤和排序功能的 DataTable
,从而能够实现高性能的表格操作。在本文中,不再重复描述服务器端操作,重点仅放在数据管理功能上。这两篇文章可以帮助您创建具有完全 AJAX 化功能的有效 Web 2.0 数据表格。
背景
Web 项目中的常见需求是创建一个表格,除了列出数据外,用户还应该能够编辑信息、添加新记录或删除现有记录。当需要实现一个功能齐全的数据表格/数据网格时,我的选择是 jQuery DataTables 插件。此插件接受一个普通的 HTML 表格,并添加了多项功能,例如分页、按列排序、按关键字过滤、更改每页显示的记录数等。您所需要做的就是包含一个简单的 JavaScript 调用:
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$('#myDataTable').dataTable();
});
</script>
在示例中,myDataTable
是应由 DataTables 插件增强的表格的 ID。jQuery DataTables 功能的完整描述可以在这里找到。下图显示了应用 DataTables 插件后的普通 HTML 表格。
DataTables 本身提供了非常好的数据操作 API(添加行、删除行等)。然而,一个缺点是您需要学习 API 函数并自己实现 CRUD 功能,因为没有开箱即用的解决方案可以轻松实现 CRUD 功能。这可能会让人考虑从 DataTables 转向其他插件,例如 jqGrid(它也是一个很好的插件,类似于 DataTables),仅仅因为它具有开箱即用的 CRUD 功能配置。因此,我的目标是将标准 CRUD 操作所需的 jQuery DataTables 功能封装到一个单独的插件中,该插件在 DataTables 的标准功能集之上添加 CRUD 功能,并使开发人员能够尽可能轻松地激活它。初始化可编辑数据表的代码如下所示:
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$('#myDataTable').dataTable().makeEditable();
});
</script>
这行代码将生成一个表格,允许用户通过双击单元格编辑数据,选择并删除表格中的任何行,以及添加新记录。增强表格的示例可在实时演示网站上找到。除此之外,您还需要创建服务器端代码,以接受当用户更改某些记录时由插件发送的 AJAX 调用,本文将指导您完成此任务。
使用代码
为了说明目的,我们将使用一个简单的 ASP.NET MVC Web 应用程序来列出公司、删除公司、添加新公司或更新现有公司信息。您需要做的第一件事是创建标准的 ASP.NET 模型-视图-控制器结构。此设置需要三个步骤:
- 创建表示将要显示的数据结构的模型类
- 创建将对用户事件做出反应的控制器类
- 创建将渲染数据并创建发送到浏览器窗口的 HTML 代码的视图
首先,我们只在表格中显示公司信息。然后,这个简单的表格将通过 jQuery DataTables Editable 插件进行增强。需要下载以下 JavaScript 组件:
- jQuery 库 v1.4.4.,包含 DataTables 插件使用的标准类
- jQuery UI 库 v1.8.7.,包含用于处理对话框的类
- jQuery DataTables 插件 v1.7.5.,包括用于在页面上应用默认样式的可选 DataTables CSS 样式表
- jQuery Jeditable 插件 v1.6.2.,用于内联单元格编辑
- jQuery 验证 插件 v1.7.,用于实现客户端验证
- jQuery DataTables Editable 插件,它将所有这些插件集成到一个功能齐全的可编辑数据表中。
这些文件应存储在本地文件系统中,并包含在客户端渲染的 HTML 页面中。这些文件的使用示例如下所述。
模型
模型是一个包含公司数据的简单类。我们需要的字段是公司 ID、名称、地址和城镇。company
模型类的源代码如下所示:
public class Company
{
public int ID { get; set; }
public string Name { get; set; }
public string Address { get; set; }
public string Town { get; set; }
}
视图
视图用于在服务器端渲染数据并将 HTML 代码发送到浏览器。该示例包括三个不同的视图页面,它们展示了插件的不同用法和配置。有一个布局页面将由所有这些页面使用。此布局页面如下所示:
<!DOCTYPE html>
<html>
<head>
<title>Customization of Editable DataTable</title>
<link href="@Url.Content("~/Content/dataTables/demo_table.css")"
rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/dataTables/demo_table_jui.css")"
rel="stylesheet" type="text/css" />
<link href="@Url.Content("~/Content/themes/base/jquery-ui.css")"
rel="stylesheet" type="text/css" media="all" />
<link href="@Url.Content("~/Content/themes/smoothness/jquery-ui-1.7.2.custom.css")"
rel="stylesheet" type="text/css" media="all" />
<script src="@Url.Content("~/Scripts/jquery-1.4.4.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.dataTables.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.jeditable.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery-ui.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.validate.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/jquery.dataTables.editable.js")"
type="text/javascript"></script>
@RenderSection("head", required: false);
</head>
<body>
<div id="container">
<a href="/Company/Index">Basic Example</a>
<a href="/Company/Ajax">Getting data with Ajax</a>
<a href="/Company/Customization">Customization</a>
@RenderBody()
</div>
</body>
</html>
此布局页面没有任何呈现逻辑 - 它只包含所有必要的 JavaScript 文件和指向此示例中使用的所有页面的链接。当执行 @RenderBody()
调用时,将呈现页面特定内容。此外,此布局页面允许您在“head
”部分包含特定于页面的自定义 JavaScript。请注意,最后一个 JavaScript 文件是 DataTables Editable 插件,它涵盖了本示例中将介绍的 CRUD 功能。布局页面并非您的项目必需,但它可以简化视图,使其仅包含与示例相关的代码。呈现表格的视图如下所示:
@{
Layout = "~/Views/Company/JQueryDataTableEditableLayout.cshtml";
}
@section head{
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$('#myDataTable').dataTable().makeEditable();
});
</script>
}
<div id="demo">
<h1>Basic Example</h1>
<table id="myDataTable" class="display">
<thead>
<tr>
<th>Company name</th>
<th>Address</th>
<th>Town</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr id="@item.ID">
<td>@item.Name</td>
<td>@item.Address</td>
<td>@item.Town</td>
</tr>
}
</tbody>
</table>
<div class="add_delete_toolbar" />
</div>
此视图使用上述布局页面,并将初始化 JavaScript 放在头部,该 JavaScript 初始化数据表并使其可编辑。主体包含一个带有公司名称、地址和城镇的表格。每个公司的 ID 都放置在围绕 <tr>
标签的 ID 属性中 - 这是 DataTables Editable 插件期望找到将被编辑或删除的记录的 ID 的位置。此外,还有一个带有类 "add_delete_toolbar
" 的 <div>
元素,它告诉 DataTables Editable 插件应该在哪里放置自动生成的添加和删除按钮。
控制器
当用户请求页面时,控制器会返回一个公司列表,该列表将在视图中呈现。这里没有使用数据库,而是使用了 DataRepository
类,它只返回所有公司的列表。下面显示了一个带有操作方法的控制器示例,该操作方法响应 /Company/Index 请求:
public class CompanyController : Controller
{
public ActionResult Index()
{
var companies = DataRepository.GetCompanies();
return View(companies);
}
}
当客户端发送“/Company/Index”请求时,此操作方法被执行,并且从存储库中的所有公司集合被发送到视图。
您唯一需要做的就是创建服务器端动作来处理插件发送的添加、删除和更新请求。这些动作可以作为控制器动作添加:
public class CompanyController : Controller
{
public string DeleteData(int id){ ... }
public string UpdateData(int id, string value, int? rowId,
int? columnPosition, int? columnId, string columnName){ ... }
public int AddData(string name, string address, string town, int? country){ ... }
}
DeleteData
操作接受要删除的行的 ID 作为参数,如果更新成功,则返回“ok
”字符串。任何其他字符串值都表示将显示给用户的错误消息。
UpdateData
操作接受更新单元格的 ID、用户输入的值以及单元格的位置(列和行 ID)。该操作应返回与 value
输入参数相同的文本。任何其他字符串值都表示将显示给用户的错误消息。
AddData
操作具有自定义参数,代表添加新记录时应保存的所有信息。给定示例在新公司记录中使用名称、地址、城镇和国家,但在其他实现中,您将使用任意参数,因此您需要创建一个自定义表单来添加新记录。DataTables Editable 插件负责在对话框中打开您的自定义表单,并将表单值发布到上面显示的服务器端操作。
在下一节中,我将解释此插件如何集成到本文附带的示例中。
示例 - 控制器操作方法的实现
前面部分描述的代码对于渲染数据和初始化 DataTables Editable 插件是必要的。一旦初始化,插件允许您执行以下功能:
- 更新单元格值 - 当用户双击单元格时,它将转换为文本框,当用户完成数据编辑并按下 Enter 键时,将发送一个 AJAX 调用到服务器端。
- 删除行 - 当用户选择一行并按下 Delete 按钮时,将向服务器发送一个 AJAX 请求,以便可以在服务器端删除所选记录。
- 添加新行 - 当用户添加新行时,将发送一个包含新记录信息的 AJAX 请求。
下图显示了当用户执行这些操作时发送到服务器的 AJAX 调用跟踪。“DeleteData
”、“AddData
”和“UpdateData
”是插件调用的默认 AJAX URL,如果需要可以修改。
以下各节描述了所需服务器端操作的实现,这些操作实际上对真实数据执行这些操作。
更新单元格
单元格更新是通过使用名为 Jeditable 的内联可编辑插件完成的。DataTables Editable 插件内部配置为在用户双击单元格时将其内容替换为可编辑的文本框。下图显示了用户如何编辑数据:
当用户完成单元格编辑并按下 Enter 键时,插件会发送 AJAX 调用,其中包含有关编辑值的信息。新的单元格内容与新值、记录 ID 和单元格坐标一起发送到服务器。发送到服务器端的 AJAX 调用如下所示:
AJAX 请求包含以下参数:
id
是从围绕已编辑单元格的<tr>
标签的ID
属性中获取的行 ID。使用此值查找应更新的记录。value
是在单元格中输入的值。此值应写入公司记录中。columnName
- 列名(例如,列标题中的文本)。您可以使用此信息来确定应更新哪个属性。rowId
来自表格。如果每页显示 10 行,则此值将在 0 到 9 之间。columnPosition
- 列值的位置,从 0 到表格中可见列数 - 1。隐藏列不计算在内。此值可以代替列名来标识应更新的属性。如果列名可以动态更改,请使用此值。columnId
- 列 ID,从 0 到总列数 - 1。隐藏列计算在内。此值可以代替列名来标识应更新的属性。如果表格中有隐藏列(无论是最初隐藏还是动态隐藏),则应使用columnId
而不是columnPosition
。
您还需要一个控制器操作,它将接受上述请求,接收从插件发送的信息,更新实际数据,并返回响应。例如:
public class CompanyController : Controller
{
/// <summary>Action that updates data
/// </summary>
/// <param name="id">Id of the record</param>
/// <param name="value">Value that should be set</param>
/// <param name="rowId">Id of the row</param>
/// <param name="columnPosition">Position of the
/// column(hidden columns are not counted)</param>
/// <param name="columnId">Position of the column(hidden columns are counted)</param>
/// <param name="columnName">Name of the column</param>
/// <returns>value if update succeed - any other value
/// will be considered as an error message on the client-side</returns>
public string UpdateData(int id, string value, int? rowId,
int? columnPosition, int? columnId, string columnName)
{
var companies = DataRepository.GetCompanies();
if (columnPosition == 0 && companies.Any(
c => c.Name.ToLower().Equals(value.ToLower())))
return "Company with a name '" + value + "' already exists";
var company = companies.FirstOrDefault(c => c.ID == id);
if (company == null)
{
return "Company with an id = " + id + " does not exists";
}
switch (columnPosition)
{
case 0:
company.Name = value;
break;
case 1:
company.Address = value;
break;
case 2:
company.Town = value;
break;
default:
break;
}
return value;
}
}
此操作接受有关已更新记录的 ID、已更新单元格所在行的 ID 以及已更新单元格所在列的 ID、位置和名称的信息。代码很简单。通过 ID 找到公司,并根据列的位置更新找到记录的其中一个属性。可以使用列名代替列位置——这取决于服务器端逻辑。如果一切正常,返回的值应与插件在请求中发送的值相同。否则,DataTables Editable 插件将假定更新失败,并且返回的文本是应显示给用户的错误消息。因此,要通知插件发生错误,您唯一需要做的就是返回错误消息(如示例所示)。
删除行
DataTables Editable 插件支持行选择并初始化删除按钮。当用户选择一行时,删除按钮变为可用,按下后,将向服务器发送一个包含当前选定行 ID 的 AJAX 请求。ID 取自 <tr>
标签的 id
属性。插件发送到服务器端页面的 AJAX 请求如下所示:
如果记录成功删除,服务器端页面应返回“ok
”字符串,否则返回应显示给用户的错误消息。
接受需要删除的行 ID 并实际删除行的控制器操作在以下示例中给出:
public class CompanyController : Controller
{
/// <summary>
/// Method called but plugin when a row is deleted
/// </summary>
/// <param name="id">Id of the row</param>
/// <returns>"ok" if delete is successfully performed - any other
/// value will be considered as an error message on the client-side</returns>
public string DeleteData(int id)
{
try
{
var company =
DataRepository.GetCompanies().FirstOrDefault(c => c.ID == id);
if (company == null)
return "Company cannot be found";
DataRepository.GetCompanies().Remove(company);
return "ok";
}
catch (Exception ex)
{
return ex.Message;
}
}
}
如果一切正常,则返回“ok
”字符串。从代码返回的任何其他字符串,例如“Company cannot be found
”或异常消息,都将在客户端显示为错误消息,并且删除将被取消。
添加新记录
添加新记录有点复杂——在这种情况下,仅仅在控制器中添加一个动作是不够的。要添加新记录,需要添加一个 HTML 表单,该表单将用于添加新记录。该表单应具有 id
"formAddNewRow
",并且应包含用户需要填充的输入元素。表单示例如下所示:
<form id="formAddNewRow" action="#" title="Add new company">
<label for="name">Name</label><input type="text"
name="name" id="name" class="required" rel="0" />
<br />
<label for="name">Address</label><input type="text"
name="address" id="address" rel="1" />
<br />
<label for="name">Postcode</label><input
type="text" name="postcode" id="postcode"/>
<br />
<label for="name">Town</label><input
type="text" name="town" id="town" rel="2" />
<br />
<label for="name">Country</label>
<select name="country" id="country">
<option value="1">Serbia</option>
<option value="2">France</option>
<option value="3">Italy</option>
</select>
<br />
</form>
当 DataTables Editable 插件检测到添加新记录表单时,“添加”按钮将自动生成。当用户按下“添加”按钮时,DataTables Editable 插件会在新的对话框窗口中打开一个表单,用户可以在其中输入新记录的信息(对话框如下所示)。
此表单无法自动生成,因为我假设在每个添加功能中,您都需要一些包含各种元素(如文本框、日历等)的自定义表单。因此,我假设您添加一个最适合您的普通 HTML 表单并对其进行样式设置会更容易,而不是使用一些自动生成的功能。在此表单中,重要的是要向输入元素添加 rel
属性,这些元素的值应在添加记录时复制到表格中。rel
属性由 DataTable Editable 插件用于将新记录的值与表格中的列进行映射。在上述示例中,输入到名称、地址和城镇输入中的值将映射到表格的第 0、1 和 2 列 - rel
属性用于此映射。
可以看出,表单中无需添加确定和取消按钮——DataTables Editable 插件会自动将其添加为表单中的最后一个元素。表单使用 jQuery 验证插件在客户端自动验证。因此,您可以添加“required
”、“email
”、“date
”和其他 CSS 类来自动实现客户端验证。在上述示例中,name
被标记为必填字段,如果此字段未填充,将显示客户端错误消息。您可以在 jQuery 验证插件网站上查看可以使用哪些验证规则。当 DataTables Editable 插件检测到“添加新记录”表单时,它将允许用户通过该表单添加新记录,并将表单中找到的元素发布到服务器端。当用户按下“确定”按钮时,将向服务器发送 AJAX 请求,如果一切正常,对话框将关闭,新行将添加到表格中。下图显示了从上面显示的表单发送的 AJAX 请求示例:
AJAX 调用发送表单中所有输入元素的值,并期望返回新行的 ID。一旦返回 ID,新行将被添加,填充表单中的值,并将返回的记录 ID 设置为新行的 ID 属性。
DataTables Editable 处理常见操作,例如打开对话框,向服务器发布请求,在按下取消时关闭对话框,以及在操作成功时在表格中添加一行。唯一需要做的是创建一个普通的 HTML 表单作为添加新记录的模板,以及一个接受新记录信息的服务器端操作。
接受表单中输入数据的 Controller
操作如下所示:
public class CompanyController : Controller
{
public int AddData(string name, string address, string town, int country)
{
var companies = DataRepository.GetCompanies();
if (companies.Any(c => c.Name.ToLower().Equals(name.ToLower())))
{
Response.Write("Company with the name '" + name + "' already exists");
Response.StatusCode = 404;
Response.End();
return -1;
}
var company = new Company();
company.Name = name;
company.Address = address;
company.Town = town;
companies.Add(company);
return company.ID;
}
}
方法的签名取决于表单参数 - 对于发布到服务器的每个参数,方法中都应添加一个参数。由于名称、地址、城镇和国家/地区从客户端发布,因此这些参数已添加到方法调用中。Action
方法返回一个整数值,该值表示新记录的 ID。如果发生任何错误(例如示例中所示的重复名称约束冲突),则应返回错误消息作为响应文本。此外,响应的状态码应设置为某个 HTTP 错误状态。实际值无关紧要,但有必要返回 4xx 或 5xx 家族中的某个状态码,以通知 DataTables Editable 插件在尝试添加记录时发生错误。在这种情况下,我使用了 404 错误消息,但实际代码无关紧要 - 唯一需要的是插件检测到错误发生并向用户显示响应文本。
服务器端处理模式下的配置
DataTables 插件可以使用表格中的一行作为数据源,或者可以配置为使用服务器端页面的 JSON 源。在服务器端模式下,只有应在当前页面上显示的数据从服务器返回并显示在表格中。DataTables 的标准功能(例如过滤、排序和分页)只是将请求转发到服务器端,在那里信息被处理并返回给 DataTables 插件。此模式需要一些服务器端开发,但可以显著提高性能。DataTables Editable 插件可以检测 DataTables 插件是否在服务器端模式下使用并支持基于 AJAX 的功能。在本节中,我将向您展示在 DataTables Editable 插件中应进行哪些修改才能在此模式下工作。
模型
在服务器端模式下,模型未更改 - 使用与前一个示例相同的公司类。
视图
我创建了一个不同的视图页面,该页面渲染输出以匹配 DataTables AJAX 模式。视图如下所示:
@{
Layout = "~/Views/Company/JQueryDataTableEditableLayout.cshtml";
}
@section head{
<script language="javascript" type="text/javascript">
$(document).ready(function () {
$('#myDataTable').dataTable({
"bProcessing": true,
"bServerSide": true,
"sAjaxSource": 'TableData',
"aoColumns": [
{ "sName": "ID",
"bSearchable": false,
"bSortable": false,
"bVisible": false
},
{ "sName": "COMPANY_NAME" },
{ "sName": "ADDRESS" },
{ "sName": "TOWN" }
]
}).makeEditable();
});
</script>
}
<div id="demo">
<h2>Ajax example</h2>
<table id="myDataTable" class="display">
<thead>
<tr>
<th>ID</th>
<th>Company name</th>
<th>Address</th>
<th>Town</th>
</tr>
</thead>
<tbody>
</tbody>
</table>
</div>
在 JavaScript 中的 DataTables 调用中添加了 bServerside
和 sAjaxSource
参数。此外,还明确定义了列,您可以看到列的 ID 作为隐藏列添加。在 AJAX 模式下,您无法轻易地将记录的 ID 作为包围公司信息的 <TR>
标签的 id
属性。因此,在 AJAX 模式下,要编辑或删除的每个记录的 ID 必须放置在表格的第一个隐藏列中。表格主体为空,因为它未在服务器上生成。每次需要数据时,DataTables 插件都会调用 sAjaxSource
页面以获取将在客户端动态注入到表格主体中的 JSON 数组。唯一需要做的不同之处在于“添加新行”表单。由于我们将第一列设置为公司 ID,因此我们需要在用于添加新行的表单中放置一个匹配的输入元素,其 rel="0"
。最方便的做法是将其添加为一个没有名称的隐藏输入(因此它不会发送到服务器),并带有一些虚拟值。此元素是必需的,这样在表格中添加新行时不会因为表单中输入数量和表格中列数量不匹配而中断。此隐藏字段的值无关紧要,因为 ID 将从服务器获取并在添加行时设置为表格中的 ID。下面显示了“添加新行”表单的示例:
<form id="formAddNewRow" action="#" title="Add new company">
<input type="hidden" id="id" name="id" value="-1" rel="0" />
<label for="name">Name</label>
<input type="text" name="name" id="name" class="required" rel="1" />
<br />
<label for="name">Address</label>
<input type="text" name="address" id="address" rel="2" />
<br />
<label for="name">Postcode</label>
<input type="text" name="postcode" id="postcode"/>
<br />
<label for="name">Town</label>
<input type="text" name="town"
id="town" rel="3" />
<br />
<label for="name">Country</label>
<select name="country" id="country">
<option value="1">Serbia</option>
<option value="2">France</option>
<option value="3">Italy</option>
</select>
<br />
</form>
控制器 (Controller)
在我的上一篇文章中,我解释了如何实现一个控制器以在服务器端模式下与 DataTables 配合使用。简而言之,两个主要区别是:
- 当请求视图页面时执行的控制器操作什么也不做。没有模型与视图关联,因为数据绑定不在服务器端完成。
- 必须实现一个额外的操作,该操作将通过
sAjaxSource
引用,其中所有处理都在服务器端完成。
DataTables 插件与服务器端代码的集成在此处不作介绍,但您可以在文章 将 jQuery DataTables 插件集成到 ASP.NET MVC 应用程序中 找到如何实现此功能。在本文中,您可以找到如何用服务器端操作替换本文中使用的客户端分页、过滤和排序功能,以提高 DataTables 的性能。
完全自定义
在上面的示例中,我展示了 DataTable Editable 插件的一些开箱即用功能,这些功能无需任何更改即可使用。然而,与原始的 DataTables 插件类似,DataTables Editable 插件允许您配置插件的属性并对其进行自定义。在本节中,我将解释如何自定义此插件。
设置 AJAX URL
您可能想要更改的第一件事是用于更新、删除或添加数据的 URL。默认情况下,如果渲染表格页面的 URL 是 /Company/Index,则数据管理操作的 URL 将是 /Company/UpdateData、/Company/AddData 和 /Company/DeleteData。这对于 ASP.NET MVC 应用程序非常方便,因为这些操作可以放在同一个控制器中。如果您有不同的控制器或视图集,例如 /Employee/List 或 /Manager/Details,其中放置了可编辑数据表,您只需将 UpdateData
、DeleteData
和 AddData
放入相应的控制器中,每个页面都将调用其数据管理操作。但是,您可以完全自定义数据管理 URL,并放置任何您想要的 URL。下面的示例演示了如何配置 DataTables Editable 表格以使用 PHP 页面而不是 ASP.NET MVC 页面。您可以放置任何值来代替这些(其他 MVC 页面、ASPX 页面等)。
$('#myDataTable').dataTable().makeEditable({
sUpdateURL: "/Home/UpdateData.php",
sAddURL: "/Home/AddData.php",
sDeleteURL: "/Home/DeleteData.php"
});
配置 DOM
您看到许多元素(例如按钮)都是由插件自动生成的。您唯一需要做的就是定义一个带有类 "add_delete_toolbar
" 的元素,它将作为添加和删除按钮的占位符。如果您希望完全控制内容,可以将这些按钮直接放在视图页面中。如果 DataTables Editable 发现按钮已存在,则不会生成新按钮,并且事件处理程序将附加到现有按钮。您唯一需要做的就是将预期的 ID 放入您想要使用的 HTML 元素中,以便 DataTables Editable 可以找到它们。元素的默认 ID 是:
formAddNewRow
- 在添加新行时将在弹出对话框中显示的表单的 IDbtnAddNewRow
- 打开添加新行对话框的按钮btnAddNewRowOk
- 添加新行对话框中的确认按钮btnAddNewRowCancel
- 添加新行对话框中的取消按钮btnDeleteRow
- 用于删除选定行的按钮
请注意,这些元素不需要是 <button>
HTML 元素——您可以放置任何您想要的内容,例如 <a>
、<span>
、<input>
、<img>
等。唯一的要求是这些元素具有预期的 ID。如果您不喜欢这些 ID,也可以更改它们。这适用于您在同一页面上使用 DataTables Editable 插件增强了两个不同的表格,并且不想混淆它们的控制按钮。下面显示了 DataTables Editable 插件的配置示例,其中定义了控制按钮的 ID:
$('#myDataTable').dataTable().makeEditable({
sAddNewRowFormId: "formAddNewCompany",
sAddNewRowButtonId: "btnAddNewCompany",
sAddNewRowOkButtonId: "btnAddNewCompanyOk",
sAddNewRowCancelButtonId: "btnAddNewCompanyCancel",
sDeleteRowButtonId: "btnDeleteCompany",
});
要使用此配置,您需要放置具有完全相同 ID 的元素,并将它们放置在页面中您喜欢的任何位置。如果您不希望用于添加和删除按钮的占位符是带有类 add_delete_toolbar
的 div
,您也可以更改此设置。我经常用于将按钮注入表格标题右侧“显示 XXX 条记录”的配置如下所示:
$('#myDataTable').dataTable().makeEditable({
'sAddDeleteToolbarSelector': '.dataTables_length'
});
DataTables 插件将“显示 XXX 条记录”放置在带有类“datatable_length
”的 div
中。如果我将此类作为工具栏的选择器,DataTables Editable 插件将在此 div
中注入添加和删除按钮。
自定义错误消息
如果您不喜欢错误发生时显示的浏览器标准消息框,您可以更改此行为。在 DataTables Editable 初始化中,您可以传递自定义错误函数。此函数应接受两个参数:将显示的消息和导致错误的动作。下面显示了一个使用自定义显示消息函数的示例:
$('#myDataTable').dataTable().makeEditable({
fnShowError: function (message, action) {
switch (action) {
case "update":
jAlert(message, "Update failed");
break;
case "delete":
jAlert(message, "Delete failed");
break;
case "add":
$("#lblAddError").html(message);
$("#lblAddError").show();
break;
}
}
});
在此示例中,当添加新记录时发生错误时,消息将放置在 ID 为“lblAddError
”的错误标签中(假设此标签放置在将在对话框中显示的表单中,并且最初是隐藏的)。对于更新和删除,错误消息将用于自定义 jAlert 插件,该插件显示一个“漂亮”的消息框而不是标准消息框。您可以随意使用任何其他插件。自定义消息的实现示例可以在此实时演示网站上找到。
配置列的自定义编辑器
使用文本框编辑单元格是 Jeditable 的默认行为,但此插件允许您为每列使用不同的编辑器。例如,在某些情况下,您希望使用 TextArea
或选择列表进行内联编辑而不是文本框。
如果您将 aoColumns
参数传递给 datatable 的初始化函数,您将能够配置表格中每个列的编辑器。参数 aoColumns
表示一个包含内联编辑器属性的对象数组。自定义编辑器的实现示例可以在此实时演示网站上找到。自定义列编辑器的配置如下所示:
$('#myDataTable').dataTable().makeEditable({
"aoColumns": [
{
//Empty object is used for the default editable settings
},
null,//null for read-only columns
{
indicator: 'Saving...',
tooltip: 'Click to select town',
loadtext: 'loading...',
type: 'select',
onblur: 'submit',
data: "{'London':'London','Liverpool':'Liverpool','Portsmouth':
'Portsmouth','Edinburgh':'Edinburgh', 'Blackburn':'Blackburn',
'Kent':'Kent','Essex':'Essex','Oxon':'Oxon','Lothian':'Lothian',
'West Sussex':'West Sussex','Lanarkshire':'Lanarkshire',
'Birmingham':'Birmingham','East Sussex':'East Sussex','Surrey':'Surrey'}"
}
]
});
aoColumns
数组定义中的第一个对象是空对象 {}
。如果您将一个空对象作为某些列的配置参数传递,将使用默认编辑器。数组中的第二个对象是 null
值。此值使该列只读,即,可编辑插件将不应用于第二列中的单元格。如果您在某些单元格中包含 HTML 链接并且不希望允许用户编辑它们,这会很有用。
第三个元素是最有趣的。这里放置了 Jeditable 编辑器的配置对象,该编辑器将应用于第三列中的单元格。第三列中单元格将使用的编辑器是选择列表(类型:'select'),其列表元素在 data
属性中定义。当用户单击第三列中的单元格时将显示的内联选择列表如下图所示:
data
属性包含一组值:标签对,将用于构建列表。标签将显示在列表中,值将用于更新单元格内容并发送到服务器端。当用户点击任何其他单元格导致 onblur
事件时,所选值将被提交。配置设置为 onblur
选定值应提交到服务器 (onblur:'submit'
)。如果您不希望此行为,可以删除 onblur:'submit'
选项并在配置中放置 submit:'Ok'
选项。这将添加一个带有标签“Ok”的提交按钮到选择列表的左侧,并且当用户按下此按钮时,值将提交到服务器。您甚至可以使用服务器端页面作为列表的数据源,如果您放置 loadurl
参数而不是 data
参数。此配置强制 loadurl
参数从 URL 而不是本地数据数组读取选择列表的值。
列配置中的其他参数设置了工具提示和编辑器在使用 AJAX 调用处理结果时将显示的文本。用于单个编辑器设置的配置参数可以在 Jeditable 网站上找到,因此如果您要为每列配置单个编辑器,最好先查看此网站。
Jeditable 是一个非常强大的插件,它有许多用于自定义输入类型的插件,因此您可以使用日期/时间选择器、蒙版输入、AJAX 上传,甚至轻松创建自己的编辑器。您可以在 Jeditable 自定义输入 演示网站上查看各种输入类型。
总结
本文向您展示了如何使用 jQuery Datatables Editable 插件创建具有集成添加、编辑和删除功能的数据表。此插件使您能够专注于处理数据管理请求的服务器端功能,并仅实现特定于您的应用程序的代码。完整的示例可以从上方下载。
带有文档的插件托管在此处,因此您可以获取插件或使用示例并将其包含在您的项目中。
历史
- 2011年3月6日:初始版本