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

在 ASP.NET MVC3 jQuery 内联编辑器中使用 JEditable 插件

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (48投票s)

2011年10月17日

CPOL

17分钟阅读

viewsIcon

169697

downloadIcon

3516

本文介绍如何使用 jQuery Jeditable 插件在 ASP.NET MVC 应用程序中实现内联编辑。

目录

引言

您可能已经看到过一个名为 contenteditable 的新 HTML5 功能。它允许您使用内联编辑器编辑 HTML 中的任何元素。您只需要做的是附加一些事件处理程序,当编辑完成时会调用它们,并将新内容发送到服务器端。如果您喜欢这个 HTML5 功能,您会爱上这个插件。

虽然 contenteditable 功能很好用,但如果您尝试在 Web 应用程序中使用它,您可能会注意到需要实现许多其他功能,例如将 AJAX 请求发送到服务器端、处理错误、验证等。此外,它在编辑纯文本时效果很好,但是如果您想使用其他编辑器,如日历、复选框或下拉列表,而您不想让用户输入任何内容,您会发现常规的 contenteditable 不够用。

在本文中,我将向您展示一个 content editable 的 jQuery 替代品 - Jeditable 插件。此外,我将在这里解释如何使用 jQuery 在 ASP.NET MVC3 应用程序中实现内联编辑功能。Jeditable 插件使您能够创建一个点击即可编辑的字段,如下所示:

MVC3-Inline-Edit-JQuery/JEditable_example.PNG

左侧显示了一个简单的 HTML 页面,右侧显示了您点击文本时的页面。文本将被文本区域替换,并生成两个按钮用于保存和取消。当您完成编辑并单击“确定”按钮时,文本区域中的文本将被发布到服务器页面,新文本将替换旧文本。您可以在 Jeditable 演示站点 的实时示例中看到这一点。

Jeditable 插件可以轻松定制(例如,使用文本输入或下拉列表而不是文本区域,更改样式/行为等),如本文其余部分所述。在 自定义示例演示页面 上查看各种不同编辑器类型的示例。此外,它还会为您处理与服务器端页面的通信。

背景

Jeditable 插件是一个非常有用的插件,它支持 HTML 的内联编辑。使用 Jeditable 插件,您可以让应用程序的用户只需单击他们想要更改的元素即可立即修改它,而无需单独的编辑表单。

Jeditable 插件背后的想法是用合适的表单元素替换静态元素,用户可以在其中编辑内容并将其提交到服务器端。例如,假设您在页面上放置了一些静态 HTML 元素 - 比如以下 HTML 代码

<span id="txtUser">John Doe</span>

这是一个纯文本字段。您可以通过以下 JavaScript 调用让用户单击此字段并对其进行编辑

$("#txtUser").editable("/ServerSide/Update");

每次用户单击 ID 为 txtUser 的元素时,Jeditable 插件会将该元素转换为文本框,将元素的内容放入文本框值中,并在用户按 **Enter** 键时通过 AJAX 调用将新值发布到 _/ServerSide/Update_ URL。如果值在服务器端页面上成功保存,Jeditable 插件会将元素旧值替换为新值。

Jeditable 插件将处理所有用户界面的交互,您只需要做的是配置插件并实现处理已更改值的服务器端逻辑。

使用代码

在本文中,我将解释如何在 ASP.NET MVC3 应用程序中使用 Jeditable 插件。以下各节将详细介绍示例中使用的模型、视图和控制器。

模型

在此示例中,使用了一个简单的模型来表示公司。模型类的源代码如下所示:

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

视图

视图是一个标准的 Razor 页面,其中显示了公司的详细信息。

@model JQueryMVCEditable.Models.Company
@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Details</h2>
<fieldset>
    <legend>Company</legend>
    <input type="hidden" id="CompanyId" value="@Model.ID" />
    <div class="field">
        <div class="display-label" id="lblName">Name</div>
        <div class="display-field text" id="Name">@Model.Name</div>
    </div>

    <div class="field">
        <div class="display-label" id="lblAddress">Address</div>
        <div class="display-field textarea" id="Address">@Model.Address</div>
    </div>
    <div class="field">
        <div class="display-label" id="lblTown">Town</div>
        <div class="display-field select" id="Country">@Model.Town</div>
    </div>
</fieldset>

控制器

控制器的基本功能是获取公司对象(模型)并将其提供给视图。显示公司详细信息的代码如下所示:

public class CompanyController : Controller
{
    public string Details(){ ... }
}

要显示公司详细信息,您需要输入 URL _/Company/Details_。控制器中还有另外两个方法可以接受来自 Jeditable 插件的 AJAX 调用(稍后将对此进行说明)。

运行此代码后,您将获得一个标准的详细信息页面,如下图所示:

MVC3-Inline-Edit-JQuery/JEditable-basic.png

您可能会注意到,这是一个标准的、未加样式的 Visual Studio 生成的 MVC 详细信息页面。它包含一个带有标签“Company”的 fieldset,其中我放置了三个公司字段(companynameaddresstown)及其标签。在下一节中,我将向您展示如何将此静态视图转换为完全可编辑的元素。

应用 Jeditable 插件

在本节中,我将向您展示如何在详细信息页面中实现完全内联编辑功能。

配置可编辑标签

在第一个示例中,我们将使标签可编辑,以便用户可以直接在页面上更改它们。在页面中,每个输入字段都有自己的标签,例如:

<div class="display-label" id="lblName">Name</div> 

在页面中,我在表示标签的每个 div 中放置了一个 display-label 类。我将使用此类来使标签可编辑。将 Jeditable 插件应用于标签的 jQuery 代码如下所示:

$(".display-label").editable("/Company/UpdateLabel");

每次单击标签时,它都会转换为文本输入,用户可以在其中输入新标签值。如下图所示:

MVC3-Inline-Edit-JQuery/JEditable-label.png

如您所见,单击“Name”标签后,它会转换为文本输入。

当用户按下 **Enter** 键时,新标签的值将被发送到 _/Company/UpdateLabel_ 服务器端页面。请求将发送两个值:

  • id - 标签的 ID。此值可在服务器端用于确定应更新哪个标签。
  • value - 在输入字段中输入的文本。

以下图形显示了此类请求的示例:

MVC3-Inline-Edit-JQuery/JEditable-XHR.png

应在服务器端添加一个控制器,其中包含在发送 _/Company/UpdateLabel_ 请求时将调用的操作方法。控制器和操作方法的示例如下所示:

public class CompanyController : Controller
{
    public string UpdateLabel(string id, string value)
    {
        return value;
    }
}

此操作方法接受标签的 ID 和新值。用于在数据库或配置文件中更新标签值的具体代码被省略,因为它是应用程序特定的,与插件本身没有直接关系。

配置可编辑字段

我们还可以使字段值可编辑。假设我们将当前公司的 ID 放在 ID 为 CompanyId 的隐藏字段中,并且每个字段值都放在类为 display-fielddiv 中。部分 HTML 如下所示:

<input type="hidden" id="CompanyId" value="@Model.ID" />
...
    <div class="display-field text" id="Name">@Model.Name</div>
...
    <div class="display-field text" id="Address">@Model.Address</div>
...
    <div class="display-field text" id="Town">@Model.Town</div>

我们假设每个需要可编辑的字段都有“display-field”类。将 Jeditable 插件应用于可编辑字段的 jQuery 代码如下所示:

$(".display-field").editable("/Company/UpdateField",
{
  submitdata : { 
                 CompanyId: function() {
                                   return $("#CompanyId").val();
                            },
                 RecordType: "COMPANY"
                }
});

每次单击类为 editable 的元素时,它都会转换为文本输入,如下图所示:

MVC3-Inline-Edit-JQuery/JEditable-text.png

当用户按下 **Enter** 键时,元素的新值将被发送到 _/Company/UpdateField_ 服务器端页面。在请求中,将发送四个值:

  • id - 字段的 ID。此值可在服务器端用于确定应更新公司的哪个属性。
  • value - 在输入字段中输入的文本。
  • CompanyId - 这是一个附加参数,将添加到请求中。此参数的值是 ID 为“CompanyId”的隐藏字段的值。
  • RecordType - 这是一个附加参数,用于告知服务器我们正在编辑公司。

如您所见,代码与前面的代码非常相似,只是在两个附加参数 CompanyIdRecordType 上有所不同。由于我们正在编辑特定的公司而不是全局标签,因此服务器端应包含我们正在更改字段值的公司 ID。我将公司 ID 放在 ID 为 'CompanyId' 的隐藏字段中,Jeditable 插件会获取此值并在提交请求时将其添加到请求参数中。

此外,有时我们需要在服务器端知道我们是在编辑公司、作业、人员、产品等。因此,最好有一些附加参数来发送有关正在编辑的记录类型的信息。在此示例中,这是通过第二个自定义 submitdata 参数 RecordType 实现的。服务器端页面将检查此参数的值并更新公司、作业、产品等。在此最简单的示例中,我们只有公司,所以这个参数没有被使用。或者,如果您不想使用附加参数,可以使用不同的 URL 来处理不同的记录类型(例如,'/Company/UpdateField'、'Product/UpdateField'、'Job/UpdateField' 等)。以下图形显示了发送到服务器端的 AJAX 调用的跟踪:

MVC3-Inline-Edit-JQuery/JEditable-XHR2.png

应在服务器端添加一个控制器,其中包含在发送 _/Company/UpdateField_ 请求时将调用的操作方法。控制器和操作方法的示例如下所示:

public class CompanyController : Controller
{
    public string UpdateField(string id, string value, int CompanyId, string RecordType)
    {
        return value;
    }
}

此操作方法接受字段的 ID、新值、公司 ID 以及我们正在编辑的记录的类型。用于在数据库中更新公司字段值的具体代码被省略,因为它是应用程序特定的,与插件本身没有直接关系。

Jeditable 插件的配置

可以通过在插件初始化调用中设置不同的选项来轻松更改默认功能。选项作为 Jeditable 调用中的第二个参数进行设置。在本节中,将展示可以应用的各种选项。

自定义提交选项

默认情况下,单击元素将启动 Jeditable 插件,按 **Enter** 键将被视为接受更改。失去元素焦点(blur)或按 **ESC** 键将被视为取消操作。您可以更改这些选项,并为接受和取消操作添加单独的按钮,这些按钮将插入在文本输入框旁边。为了配置 submitcancel 按钮,您需要在初始化中设置这些参数:

$(".editable-field").editable("/Company/UpdateField",
{
    cancel    : 'Cancel',
    submit    : 'OK'
});

如果未设置 cancel 和 submit 参数,则不会生成这些按钮。

更改编辑器类型

文本框是默认编辑器,但是您可以使用文本区域或下拉列表作为替代编辑器。要使用文本区域而不是文本输入,只需更改 type 参数的值,如下例所示:

$(".textarea").editable("/Company/UpdateField",
{
     type      : 'textarea',
     rows      : 4,
     columns   : 10,
     cancel    : 'Cancel',
     submit    : 'OK',
});

请注意,当您使用文本区域输入时,您应该添加一个 **Submit** 按钮,因为在文本区域中,**Enter** 键会添加新行,因此不能用于提交值。配置为文本区域的编辑器的外观如下所示:

MVC3-Inline-Edit-JQuery/JEditable-textarea.png

另一种编辑器类型是 select 列表,您可以在其中定义一组可供选择的选项。以下列表显示了一个示例:

$(".select").editable("/Company/UpdateField",
{
    type      : 'select',
    data      :  "{'Belgrade':'Belgrade','Paris':'Paris',
                  'London':'London', 'selected':'Belgrade'}"
});

在此示例中,生成了一个包含三个值的 select 列表。请注意,最后一个参数告诉 Jeditable 插件哪个值应该被选中。而不是在 data 参数中硬编码值,您可以从服务器端 URL 加载选项:

$(".remote-select").editable("/Company/UpdateField",
{
     type      : 'select',
     loadurl   : '/Company/Options',
     loadtype  : 'GET',
     loaddata  : {type: "1"};
});

当用户单击元素时,将使用 GET 协议向服务器端发送一个 _/Company/Options?type=1_ 请求。返回的值将用作下拉列表中的选项。以下图形显示了下拉列表编辑器:

MVC3-Inline-Edit-JQuery/JEditable-select.png

文本框、文本区域和下拉列表是标准编辑器,但还有其他自定义类型,如 checkboxdatepicker、文件上传、时间编辑器等。其中一些在 Jeditable 演示页面 上显示。

如果您找不到所需的编辑器类型,您可以创建自己的编辑器 - 有关更多详细信息,请参阅本教程

配置提交的数据

默认情况下,Jeditable 插件将元素的 ID 和输入元素中输入的 value 发送到服务器端 URL。但是,您可以自定义这些设置,如下例所示:

$("#txtTitle").editable("/Company/UpdateField",
{
    id    : 'COMPANY_FIELD',
    name  : 'FIELD_VALUE',
    method: 'POST',
    submitdata : {type: "company"}
});

其他选项包括:

  • id:包含内容 ID 的已提交参数的名称。默认为 id
  • name:包含已编辑内容的已提交参数的名称。默认为 value
  • method:提交已编辑内容时使用的方法。默认为 POST。您最有可能想使用 POSTPUT
  • submitdata:提交内容时的额外参数。可以是哈希或返回哈希的函数。您在上面的示例中已经看到了如何使用此函数来从隐藏字段添加公司 ID 参数。

当 Jeditable 将请求提交到服务器端时,POST 请求将如下所示:/Company/UpdateField?COMPANY_FIELD=Name&FIELD_VALUE=TEST&type=company

如您所见,idvalue 参数具有不同的名称,值被编码,并且一个名为 type 的新参数被添加到请求中。

配置显示/行为

可编辑插件的激活方式可以在配置中设置。这是使用 eventonblur 参数配置的:

$("#txtTitle").editable("/Company/UpdateField",
{
     event    : 'click',
     onblur   : 'submit'
});

event 参数是一个 jQuery 事件,它会将内容转换为可编辑输入(例如,“click”、“dblclick”或“mouseover”)。onblur 参数可以具有以下值之一:“cancel”、“submit”、“ignore”,或者可以设置为一个函数。此参数将定义插件在输入失去焦点时执行的操作。

您可以更改 Jeditable 的显示方式。您可以设置样式或将 CSS 类关联到放置内联编辑器的表单。如果您将值设置为 'inherit',则类或样式将从周围元素继承到表单中。此外,您还可以定义编辑器的宽度和高度。以下列表显示了一个示例:

$("#txtTitle").editable("/Company/UpdateField",
{
     cssclass    : 'inherit',
     style       : 'display:inline',
     height      : '20px',
     width       : '100px'
});

在此配置中,CSS 类将从周围元素继承,表单将以行内方式显示,并且文本框的尺寸为 20x100px。

您还可以定义如果当前文本不存在时显示什么文本,用作工具提示文本的内容,以及在服务器保存已编辑值时显示什么文本/HTML:

$("#txtTitle").editable("/Company/UpdateField",
{
     placeholder : 'N/A',
     tooltip     : 'Click to edit',
     indicator   : 'Saving...',
     select      : true
     data: function(value, settings) {
              return encode(value);
     },             
});

在此示例中,如果元素没有内容,将显示 'N/A'(默认值为 'Click to edit'),工具提示将是 'Click to edit'。当插件等待服务器响应时,将显示文本 'Saving...'。如果您愿意,可以将 HTML 放在文本而不是纯文本中。一旦用户编辑了文本,它将自动高亮显示,因为 select 属性设置为 true。

Data 参数代表将在编辑器中显示的数据。在前面带有 select 编辑器类型的示例中,数据元素中放置了将放入 select 列表中的选项列表。如果您将函数作为 data 参数,将在 Jeditable 从元素获取当前文本之前调用该函数,然后将该文本传递给函数,并且返回的值将设置为编辑器元素的内容。它可以是字符串或返回 string 的函数。当您需要修改文本(例如,将其编码)后再进行编辑时,这会很有用,如示例所示。

事件处理

Jeditable 插件可以处理许多事件:

  • callback - function(value, settings) { ... } 在表单提交后调用。value 包含已提交的表单内容。settings 包含所有插件设置。在函数内部,this 指的是原始元素。
  • onsubmit - function(settings, original) { ... } 在提交前调用。settings 包含所有插件设置。original 是元素的原始内容。在函数内部,this 指的是原始元素。
  • onreset - function(settings, original) { ... } 在重置前调用。 settings 包含所有插件设置。original 是元素的原始内容。在函数内部,this 指的是原始元素。
  • onerror - function(settings, original, xhr) { ... } 在发生错误时调用。settings 包含所有插件设置。original 是元素的原始内容。在函数内部,this 指的是原始元素。

与其他插件集成

Jeditable 插件的优点在于它可以应用于任何其他插件之上。例如,您可以在表格单元格中应用内联单元格编辑,编辑树视图或菜单中的节点,编辑选项卡的内容等。您只需要做的是将 Jeditable 插件应用于应编辑的元素。在以下示例中,您可能会找到 Jeditable 插件与选项卡和表的两种用法。

与 JQuery UI Tabs 集成

JQuery UI tabs 是 JQuery UI 库的一部分,它使您能够轻松创建选项卡式界面。您可以在 JQuery UI Tabs 页面 上找到各种使用案例。以下图形显示了一个选项卡式界面的示例:

图片中的每个选项卡都采用 <a href="#tab-1">Nunc tincidunt</a><a href="#tab-2">Proin dolor</a><a href="#tab-3">Aenean lacinia</a> 的格式,其中 tab-1tab-2tab-3 是选项卡内容的 ID。您可以使用以下代码将可编辑插件应用于选项卡链接:

$("#tabs").tabs();
$("a[href='#tabs-1']").editable("/Settings/UpdateTabLabel",
				{  event: "dblclick",
				   submitdata: { id: "tab-1" } 
                                });

可编辑插件应用于指向第一个选项卡的链接(通过 href 属性)。当用户双击选项卡链接并编辑选项卡标签时,JEditable 插件会将新值和 ID “tab-1”一起发布到 _/Settings/UpdateTabLabel_ 页面。下图显示了如何编辑第一个选项卡:

类似的脚本可用于使其他选项卡可编辑。

与 DataTables 集成

JQuery DataTabes 插件为表格添加了分页、过滤和排序功能。一旦应用了 DataTables 插件,您就可以将可编辑插件应用于单元格。在下图中,您可以看到 Jeditable 插件如何应用于表格单元格:

在此示例中,jQuery DataTables 插件已应用于表格,然后 JEditable 已应用于特定单元格。应用 Jeditable 插件到表格单元格的脚本很简单:

$("table#mycompanies td").editable("/Company/UpdateTableCell");

只要每个单元格都有自己的 ID,JEditable 插件就会正常工作。更好的解决方案是避免在每个单元格中使用 ID,而只发送行和列的 ID 以及值。在这种情况下,您可以查看 DataTables 站点上的 已准备好的用于将可编辑插件应用于 DataTable 的解决方案 或结合了 DataTables 和 JEditable 插件功能的 DataTable Editable 插件。您可以在 ASP.NET MVC 可编辑表格[^] 文章中找到有关创建内联可编辑单元格的更多详细信息。

结论

在本文中,展示了在 MVC3 中实现内联编辑器的基本概念。我还展示了各种配置选项。如果您对 Jeditable 插件有任何疑问,或者需要有关其使用方法的更多信息,请查看 Jeditable 网站,您将在其中找到完整的文档和实时示例。

附加的是带有 Web Developer 2010 项目的源代码,其中实现了一个包含编辑器的简单页面。

历史

  • 2011年10月17日:初始版本
© . All rights reserved.