【问题标题】:"Add another item" form functionality“添加另一个项目”表单功能
【发布时间】:2011-01-05 07:03:27
【问题描述】:

我有一个表单,可以让用户输入他们的职业历史 - 这是一个非常简单的表单,只有 3 个字段 - 类型(下拉)、详细信息(文本字段)和年份(下拉)。

基本上我想包含一些动态功能,用户可以在同一页面上输入多个项目,然后一次性提交所有项目。我在 Google 上搜索并找到了一些示例,但它们都是基于表格的 - 我的标记基于 DIV 标签:

<div class="form-fields">

<div class="row">
    <label for="type">Type</label>
    <select id="type" name="type">
      <option value="Work">Work</option>
    </select>
</div>

<div class="row">
    <label for="details">Details</label>
    <input id="details" type="text" name="details" />
</div>

<div class="row">
    <label for="year">Year</label>
    <select id="year" name="year">
      <option value="2010">2010</option>
    </select>
</div>

</div>

所以基本上需要复制具有“行”类的 3 个 DIV 标签,或者为了简化事情 - 可以复制 div“表单字段”。我也知道输入名称必须转换为数组格式。

此外,每个项目都需要一个“删除”按钮。底部会有一个主提交按钮,用于提交所有数据。

有人对此有一个优雅的解决方案吗?

【问题讨论】:

    标签: jquery


    【解决方案1】:

    一种方法是:

    $('<span class="add">+</span>').appendTo('.form-fields:last');
    $('.add').live('click',
                   function(){
                       $('.form-fields:first')
                           .clone()
                           .insertAfter('.form-fields:last');
                       $('.add').remove();
                       $('<span class="add">+</span>')
                           .appendTo('.form-fields:last');
                   });
    

    JS Fiddle demo

    不过,它并不是特别漂亮;还没有考虑到对唯一 ids 的需求。

    【讨论】:

    • 这个非常好 - 我看到一些演示使用了克隆功能,我认为这是解决问题的方法。但是是的,它需要唯一的 ID 和数组格式输入名称 :)
    【解决方案2】:

    HTML:

    <div class="form-fields">
      <div class="row">
        <label>Type
          <select name="type[0]">
            <option value="Work">Work</option>
          </select>
        </label>
      </div>
      <div class="row">
        <label>Details
          <input type="text" name="details[0]" />
        </label>
      </div>
      <div class="row">
        <label>Year
          <select id="year" name="year[0]">
            <option value="2010">2010</option>
          </select>
        </label>
      </div>
    </div>
    

    JS:

    var counter = 0, formFieldsString = '<div class="form-fields"...';
    
    function addNew()
    {
      $(formFieldString.replace('[0]', '['+(++counter)+']')).appendTo('#form-fields-parent');
    }
    

    【讨论】:

    • 这个看起来很有趣。我刚刚尝试过,但它对我不起作用 - 您的 JS 代码中的字段名称是否不正确?
    • 请注意,我稍微更改了布局以删除 ids 并使用数组语法作为字段名称。
    • var formFieldsString 和 appendTo 函数呢?
    • formFieldsString 是我懒得再次从上面输入整个 HTML 字符串。 Append to 只是将它添加到指定的选择器中。我写了一个描述性选择器,这样你就可以明白了。
    【解决方案3】:

    我现在经常这样做。以下是我使用的大型元素的简要说明:

    1. 使用最新版 JQuery 自带的模板。
    2. 从服务器来回传递一个包含所有必要数据的 JSON 对象。

      var data = { items: [ { id: 1234, work: "work", details: "details", year: "2010" } ] };

    3. 创建一个可以为特定属性创建唯一 ID 的 javascript 函数。

      function GetFieldId(type, id, prop) { return [type, id, prop].join("_"); }

    4. 在模板中,使用上述函数为用户可以交互的每个元素添加 id。创建对象上实际上不存在的“属性”对于按钮和类似元素非常有效。

    5. 使用 JQuery 委托,为任何带有 id 的输入创建一个“更改”处理程序。

    6. 在更改处理程序中,将 id 拉开,找到合适的对象,然后开始工作。

    7. 要添加项目,请创建一个新对象,将其放入相应的 JSON 数组中,渲染模板,然后将其放入页面上的正确位置。

    8. 要删除对象,请向对象添加“IsDeleted”属性,然后删除 HTML 元素。

    9. 保存涉及将此 JSON 对象推送到服务器上,服务器将对其进行分析并采取适当的措施。

    【讨论】:

      【解决方案4】:

      我使用 jQuery 和 ASP.NET 的组合来做这样的事情。

      首先,我在 ASP.NET (*.ascx) 中编写了一个包含“行”的部分页面。在您的情况下,由于这三个项目放在一起,所有这些项目都可以被视为一行。 (您可以使用 CSS 样式使它们看起来像是属于一起的。)我还在行的末尾放置了一个图像(一个加号),这样,如果用户单击该加号,我可以添加一个新行(稍后会详细介绍)。

      无论如何,我将部分行添加到页面以开始使用。 (我使用强类型页面,这样我就可以遍历模型并将单个行传递到我的部分页面。)我将所有这些显示在一个表格中。 (在我的例子中,它由表格数据表示,但不一定是。)

      关于加号,当用户点击它时,我根据部分页面添加一个新行。大致如下:

      personAdd($('#addPerson'), '#personInformation');
      
      function personAdd(personDiv, tableName) {
          personDiv.live('click', function () {
              $.ajax({
                  url: this.href,
                  cache: false,
                  success: function (html) { $(tableName + ' > tbody:last').append(html); }
              });
      
              $(this).replaceWith('<img alt="Delete Person" class="deleteImg" src="/Content/Images/remove_delete_cancel_clear.png" />');
      
              return false;
          });
      }
      

      这会添加一个新行,并将前一行更改为“删除图像”(红色 X),以便可以删除之前的行。我用这个 jQuery 处理那一点:

      // Allow rows to be deleted.
      $('.deleteImg').live('click', function () {
          $(this).closest('tr').remove();
      });
      

      由于所有内容都是强类型的,所以当我继续提交表单时,它工作得很好。我希望这对您有所帮助并帮助您入门,或者可能对其他人有所帮助。如果您有任何问题,请告诉我。

      【讨论】:

        猜你喜欢
        • 2011-06-21
        • 2018-04-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多