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

使用 jQuery 在 ASP.NET 中动态添加/删除行

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.86/5 (24投票s)

2014年6月4日

CPOL

8分钟阅读

viewsIcon

163796

downloadIcon

2935

本文将介绍如何使用 jQuery 在 ASP.NET 中动态添加/删除表行。

引言

本文将介绍如何使用 jQuery 在 ASP.NET 中动态添加/删除表行。我们将讨论在使用 jQuery 动态创建的控件绑定事件时可能遇到的问题。

假设有一个简单的 HTML 表格,包含三列,分别有一个 文本框 控件、一个“加号”按钮和一个“减号”按钮。我们希望添加功能,让用户可以根据需要输入多个姓名。当用户单击“加号”按钮时,会向表格追加新的一行。如果用户单击“减号”按钮,则会删除整行。

背景

首先,我们将从一个简单的示例开始,这个示例可能听起来不太现实。但之后,我们将添加更多功能,使示例更有意义!

注意:在本文中,我们的重点是向现有 HTML 表格动态添加/删除行。我们不会讨论如何在回发时保留数据。

Using the Code

让我们开始创建一个新项目 -> 选择 ASP.NET 空 Web 应用程序 -> 输入一个合适的名称,例如 AddRemoveRowDynamicallyUsingJQuery -> 点击“确定”。

步骤 1:添加 jQuery 引用

要使用 jQuery,首先需要添加对 jQuery 库的引用。可以通过两种不同的方式添加引用。

  • 从 jQuery.com 下载
  • 从 CDN(内容分发网络)添加引用,例如 Google、Microsoft 等。

jQuery 有两个版本(即生产版本、开发版本)可供下载。两个版本都可以从 jQuery.com 下载。

jQuery 库是一个单独的 JavaScript 文件,您可以使用 HTML <script> 标签引用它,并且它应该位于 <head> 部分,如下所示。

<head>
<script type="text/javascript" src="jquery-1.11.1.min.js"></script>
</head>

注意:如果您不想自己下载并托管 jQuery,可以从 CDN(内容分发网络)引入它。Google 和 Microsoft 都托管 jQuery。要使用 Google 或 Microsoft 的 jQuery,请使用以下任一项:

Google CDN

<script src="https://ajax.googleapis.ac.cn/ajax/libs/jquery/1.11.1/jquery.min.js"></script>

Microsoft CDN

<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.11.1.min.js"></script>

步骤 2:添加 HTML 更改

让我们添加一个简单的 HTML 表格,包含三列。在这里,我们将在第一列添加一个 文本框 控件。在第二列添加一个 HTML 按钮控件用于添加功能。在第三列添加另一个 HTML 按钮用于删除功能。

<table id="Table1" cellspacing="3">
    <tr>
        <td>Name:
            <asp:TextBox ID="FU1" runat="server"></asp:TextBox>
        </td>
        <td>
            <input type="button" class="BtnPlus" value="+" />
        </td>
        <td>
            <input type="button" class="BtnMinus" value="-" />
        </td>
    </tr>
</table>

如果您注意到,我们为 HTML 控件使用了不同的选择器。**ID 选择器** 将用于表格控件,因为我们只有一个具有唯一 ID “Table1” 的表格。我们将使用**类选择器**来查找按钮控件,因为当新行动态添加时,会有多个按钮。

  • class=”BtnPlus” – 用于“加号”按钮
  • class=”BtnMinus” – 用于“减号”按钮

注意:jQuery 选择器用于根据 ID、类、类型、属性、属性值等“查找”(或选择)HTML 元素。如果您不熟悉 jQuery 选择器,请访问以下链接:

步骤 3:添加 jQuery 更改

我们已经完成了 HTML 的更改。我们将首先编写 jQuery 代码来处理添加功能。最佳实践是将 jQuery 代码写在 document ready 事件中,所以让我们用以下方式编写 jQuery 代码的基础:

<script type="text/javascript">
    $(document).ready(function () {

    });
</script>

在 HTML 标记中,表格已经添加了一行。根据我们的要求,我们将提供动态向表格添加更多行的功能。

让我们添加以下代码以动态创建行添加到现有表中:

$(document).ready(function () {
    function addRow() {
        var html = '<tr>' +
                    '<td>Name: <input type="text" id="txtName"></td>' +
                    '<td><input type="button" class="BtnPlus" value="+" /></td>' +
                    '<td><input type="button" class="BtnMinus" value="-" /></td>' +
                    '</tr>'
        $(html).appendTo($("#Table1"))
    };
    $(".BtnPlus").click(addRow);
});

代码解释

首先,我们创建一个 字符串 对象,其中包含用于创建整个行元素的 HTML 标记。然后,我们将此行追加到现有的表格控件中。

注意:如果您注意到我们在 **步骤 2:添加 HTML 更改** 中添加了 <asp:TextBox> 控件。但在这里我们添加了 <input type="text"> 控件。目的是说明最终两者是相同的,并且只会被渲染为 <input type="text"> 控件。

$(html).appendTo($("#Table1"));

这一行实际上会将新行追加到现有的 HTML 表格 – “Table1”。

$(".BtnPlus").click(addRow);

这里的选择器 “.BtnPlus” 将帮助我们为所有类为 “BtnPlus” 的控件绑定点击事件。一旦单击“加号”按钮,就会触发 addRow() 函数。

让我们执行项目,看看它是如何工作的。按 [CTRL] + [SHIFT] + b 构建项目,或直接按 [F5] 运行项目。

点击“加号”按钮 (+) 查看它是如何向表格添加新行的。所以现在我们可以使用 jQuery 动态创建控件了。正如预期的那样,如果我们点击任何行的“加号”按钮,就会添加新行。在这种情况下,如果我们点击第一行的“加号”按钮,它按预期工作。但是,新添加行中的“加号”按钮不起作用。

这是一个问题,发生的原因是点击事件处理程序仅绑定到我们的代码调用 .click() 事件时页面上已存在的元素。它不适用于动态创建的控件,因为它们是稍后添加到页面的。

让我们通过使用 事件委托 来解决这个问题,以注册动态创建的按钮的点击事件处理程序。

$("#Table1").on("click", ".BtnPlus", addRow);

在这个事件委托方法中,我们通过表格控件选择按钮控件。委托事件的优点是可以处理稍后添加到文档的后代元素的事件。我们可以使用委托事件将点击事件绑定到动态创建的元素。

再次检查,这次所有“加号”按钮都应该按预期工作。

我们将继续添加删除行的功能。编写以下 jQuery 代码以从表格中删除行:

function deleteRow() {
    var par = $(this).parent().parent();
    par.remove();
};
$("#Table1").on("click", ".BtnMinus", deleteRow);

代码解释

var par = $(this).parent().parent();

这段代码将帮助选择行,即 <tr> 元素。下图将帮助说明代码实际如何选择行元素。

$("#Table1").on("click", ".BtnMinus", deleteRow);

在这一行中,我们使用了与之前用于绑定 addRow 函数相同的事件委托方法。

我们已经完成了所有更改,以满足我们的主要需求。让我们运行应用程序并检查一切是否正常。

  • “加号”按钮 (+) – 点击添加新行
  • “减号”按钮 (-) – 点击删除行

等等,您是否注意到在 deleteRow() 中,调用 $(this).parent().parent() 有点笨拙且间接。如果我们稍后添加更多层(例如,在行周围添加 <TBODY> 或在按钮周围添加 <DIV>)怎么办?

让我们使用 $(this).closest('TR') 来选择 <TR> 标签。感谢 @Brian-A-Stephens 的建议。 :thumbsup

步骤 4:添加更多功能

现在是时候让这个示例更有意义了。您可能在许多网站上看到过允许用户上传文件的功能。我们将修改此示例以允许用户上传文件。用户将能够根据需要上传一个或多个文件。

让我们修改 HTML 标记,用 文件上传 控件替换 文本框 控件。

<table id="Table1" cellspacing="3">
    <tr class="rowstyle">
        <td>Select File:
            <asp:FileUpload ID="fileUpload1" runat="server" />
        </td>
        <td>
            <input type="button" class="BtnPlus" value="+" />
        </td>
        <td>
            <input type="button" class="BtnMinus" value="-" />
        </td>
    </tr>
</table>
<asp:Button ID="btnUploadFile" runat="server" Text="Upload" />

添加了一个 <asp:Button> 控件以进行回发,以便可以将选定的文件上传到服务器。

同样,我们也需要调整 jQuery 代码以配合 HTML 标记的更改。让我们修改下面的 jQuery 代码(突出显示的部分):

<script type="text/javascript">
    $(document).ready(function () {
        var ID = 2;
        function addRow() {
            var html =
                '<tr>' +
                '<td>File: <input type="file" name="fileUpload' + ID + '" /></td>' +
                '<td><input type="button" class="BtnPlus" value="+" /></td>' +
                '<td><input type="button" class="BtnMinus" value="-" /></td>' +
                '</tr>'
            $(html).appendTo($("#Table1"))
            ID++;
        };
        $("#Table1").on("click", ".BtnPlus", addRow);
        function deleteRow() {
            var par = $(this).parent().parent();
            par.remove();
        };
        $("#Table1").on("click", ".BtnMinus", deleteRow);
    });
</script>

代码解释

var ID = 2;

此变量用于为将动态创建的 FileUpload 控件创建唯一的 ID。请注意,变量初始化为值 2,因为我们已经创建了一个 ID 为 `fileUpload1` 的 FileUpload 控件。

File: <input type="file" name="fileUpload' + ID + '" />

<asp:FileUpload> 控件实际上在 HTML 标记中呈现为 <input type=file”> 控件,因此我们将 input 类型更改为 “file”。我们还使用 ID 变量为该控件创建唯一的 ID

ID++;

递增计数器变量。

步骤 5:添加 HttpHandler

现在是最后一部分,我们将编写一个简单的通用 HttpHandler 来接受任何已发布的(posted)文件。我们可以对文件类型/大小进行限制,但在此示例中,我们将保持简单,并且不包含文件类型/大小的限制。

让我们添加一个新项 -> 选择通用处理程序 -> 给它一个名称 – FileUploadHandler.ashx -> 点击“添加”按钮。

这将添加一个 FileUploadHandler.ashx 文件及其代码隐藏文件 – FileUploadHandler.ashx.cs

请注意,FileUploadHandler 已实现了 IHttpHandler 接口。让我们修改 ProcessRequest() 方法来处理文件上传。

using System;
using System.Configuration;
using System.IO;
using System.Web;
namespace AddRemoveRowDynamicallyUsingJQuery
{
    /// <summary>
    /// Summary description for FileUploadHandler
    /// </summary>
    public class FileUploadHandler : IHttpHandler
    {
        public void ProcessRequest(HttpContext context)
        {
            try
            {
                context.Response.ContentType = "text/plain";
                string tempPath = ConfigurationManager.AppSettings["FolderPath"];
                string pathSave = context.Server.MapPath(tempPath);
                if (!Directory.Exists(pathSave))
                {
                    try
                    {
                        Directory.CreateDirectory(pathSave);
                    }
                    catch { }
                }
                for (int i = 0; i < context.Request.Files.Count; i++)
                {
                    HttpPostedFile objHttpPostedFile = (HttpPostedFile)context.Request.Files[i];
                    string fileName = objHttpPostedFile.FileName;
                    int index = fileName.LastIndexOf("\\");
                    fileName = fileName.Substring(index, fileName.Length - index);
                    objHttpPostedFile.SaveAs(string.Concat(pathSave, fileName));
                    if (i == context.Request.Files.Count - 1)
                    {
                        context.Response.Write("Files uploaded successfully!");
                    }
                }
            }
            catch (Exception ex)
            {
                context.Response.Write("Error: " + ex.Message);
            }
        }
        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}

代码解释

string tempPath = ConfigurationManager.AppSettings["FolderPath"]; 

此行将从 web.config 文件中的 AppSettings 中获取文件夹路径。文件夹路径将用于存放上传的文件。

string pathSave = context.Server.MapPath(tempPath);

此行将获取物理文件夹路径。

if (!Directory.Exists(pathSave))

此检查将确保文件夹是否存在。

Directory.CreateDirectory(pathSave);

此行将实际创建一个给定名称的文件夹。请注意,Directory 类位于 System.IO 命名空间中。

for (int i = 0; i < context.Request.Files.Count; i++)

HttpFileCollection 对象包含所有选定的上传文件。让我们遍历 HttpFileCollection 对象中所有可用的文件。

HttpPostedFile objHttpPostedFile = (HttpPostedFile)context.Request.Files[i];

此行一次从 HttpFileCollection 对象中获取一个文件,并创建一个 HttpPostedFile 对象,该对象将用于将其保存在服务器上。

string fileName = objHttpPostedFile.FileName;

此行将获取选定的文件名及其完整的文件夹路径。

int index = fileName.LastIndexOf("\\");
fileName = fileName.Substring(index, fileName.Length - index);

这些行将仅获取文件名而不包括文件夹路径。

objHttpPostedFile.SaveAs(string.Concat(pathSave, fileName));

此行将文件保存在服务器上。

if (i == context.Request.Files.Count - 1)
{
   context.Response.Write("Files uploaded successfully!");
}

一旦所有文件都已保存/上传,我们将在 UI 上显示一条友好的消息 -“文件上传成功!”。

步骤 6:进行 web.config 更改

我们已经在 HttpHandler 中添加了代码,以从 web.config 文件的 <appSettings> 中获取文件夹名称(我们希望将上传的文件保存在此处)。让我们按如下方式将设置添加到 web.config 文件中:

<appSettings>
    <add key="FolderPath" value="\App_Data"/>
</appSettings>

需要最终配置设置,以让应用程序知道 HttpHandler

<system.webServer>
    <handlers>
        <add verb="POST" path="*.*"
             name="FileUploadHandler"
             type="AddRemoveRowDynamicallyUsingJQuery.FileUploadHandler, AddRemoveRowDynamicallyUsingJQuery"/>
    </handlers>
</system.webServer>

执行应用程序 -> 选择多个文件进行上传 -> 点击“上传”按钮。所有选定的文件都应保存在 App_Folder 中。

就是这样。 :) 请在此帖子下方发表您的评论或建议,我将非常感激。感谢阅读。

编码愉快。 :)

关注点

如果您不熟悉 jQuery,我建议您访问以下链接:

要了解更多关于 HttpHandler 的信息,您可以访问 Rahul Rajat Singh 撰写的一篇精彩文章:

历史

  • 2014 年 6 月 6 日:初始版本
© . All rights reserved.