【问题标题】:Clone a <tr> and also increment the name attribute of elements inside <td> by 1克隆一个 <tr> 并将 <td> 中元素的 name 属性增加 1
【发布时间】:2012-11-08 09:07:08
【问题描述】:

我必须在表单中实现“添加新行”功能。表单的结构类似于:

<table>
<tr>
     <td><input type="text" name="v1[label]" /></td>
     <td><input type="text" name="v1[observation]" /></td>
     <td><input type="text" name="v1[remarks]" /></td>
</tr>
<tr>
     <td><input type="text" name="v2[label]" /></td>
     <td><input type="text" name="v2[observation]" /></td>
     <td><input type="text" name="v2[remarks]" /></td>
</tr>
<tr>
    <td colspan="3">
       <input type="button" id="addrow" value="Add One More Row">&nbsp;
       <input type="submit" name="proceed" value="Submit" />
    </td> 
</tr>
</table>

正如所见,每一行,v[] 的数量都会增加。 v1、v2..等等

我在寻找什么

当点击“Add One More Row”按钮时,应该会发生以下情况

  • 在最后一行(带有 按钮)
  • name 属性值加 1(即 v2[label] 变为 v3[label], v2[observation] 变成 v3[observation] 等等)在那个 行

我尝试了什么

我最接近的是使用jQuery'sclone()。这确实完美地添加了行。但是我发现每次单击按钮时很难找到一种方法将 name 属性的值增加 1。

jQUERY 当前正在使用

$('input:button[id="addrow"]').click(function(){

   var secondlast = $('table tr:last').prev('tr');
   secondlast.clone().insertBefore(secondlast);

});

如果我单击该按钮两次,我会添加以下 HTML

<tr>
     <td><input type="text" name="v2[label]" /></td>
     <td><input type="text" name="v2[observation]" /></td>
     <td><input type="text" name="v2[remarks]" /></td>
</tr>

<tr>
     <td><input type="text" name="v2[label]" /></td>
     <td><input type="text" name="v2[observation]" /></td>
     <td><input type="text" name="v2[remarks]" /></td>
</tr>

所以添加了一行,但 name 属性仍然是 v2,而第三和第四行应该是 v3 和 v4。我知道clone() 无法做到这一点,这就是我寻找替代方案的原因。

【问题讨论】:

  • 您是否尝试过在插入之前处理克隆?例如,secondlast.clone().each('input') 之类的东西,解析名称并替换数字?
  • 嗯..这是有道理的。我会试试看我能不能做到这一点
  • @Eregrith 我对逻辑非常清楚,但发现很难将其转换为编程语法:(
  • 您可以操作属性并根据事件点有多少表行来增加它。

标签: javascript jquery


【解决方案1】:
$('input:button[id="addrow"]').click(function(){
    var secondlast = $('table tr:last').prev('tr');
    var newClone = secondlast.clone();
    // find all the inputs within your new clone and for each one of those
    newClone.find('input').each(function() {
        var currentNameAttr = $(this).attr('name'); // get the current name attribute
        // construct a new name attribute using regular expressions
        // the match is divided into three groups (indicated by parentheses)
        // p1 will be 'v', p2 will be the number, p3 will be the remainder of the string
        var newNameAttr = currentNameAttr.replace(/^(v)(\d+)(.*)$/, function(match, p1, p2, p3) {
            return p1+(parseInt(p2)+1)+p3;
        });
        $(this).attr('name', newNameAttr);   // set the incremented name attribute 
    });
    // insert after is I assume what you want
    newClone.insertAfter(secondlast);
});

编辑

// you could also simply increment any digit you find as Batman indicated
var newNameAttr = currentNameAttr.replace(/\d+/, function(match) {
    return (parseInt(match)+1);
});

【讨论】:

  • 这按预期工作。给我一点时间来玩弄它。我还必须用选择框测试它
  • 是的。按预期完美运行。我刚刚用newClone.find('input, select').each(function() 替换了newClone.find('input').each(function()。 +1 并接受作为答案。还要感谢您的代码提供的 cmets xD
  • +1 表示解决方案的优雅。但是,请确认一个重大警告:Changing name attr of cloned input element in jQuery doesn’t work in IE6/7?
  • @chridam 谢谢,不知道IE6/7没有让你动态更新name属性。
  • @cbayram 不用担心。我想如果($.browser.msie === true) 成为一个真正的问题,OP 可以添加mergeAttributes 修复
【解决方案2】:

如果您需要将这些输入中的数据发送到服务器,则很难确定您必须采取多少 v*... 相反,我建议您使用 [] 在数组中添加行。

你的 HTML 应该是这样的:

<table>
<tr>
     <td><input type="text" name="v[label][]" /></td>
     <td><input type="text" name="v[observation][]" /></td>
     <td><input type="text" name="v[remarks][]" /></td>
</tr>
<tr>
     <td><input type="text" name="v[label][]" /></td>
     <td><input type="text" name="v[observation][]" /></td>
     <td><input type="text" name="v[remarks][]" /></td>
</tr>
<tr>
    <td colspan="3">
       <input type="button" id="addrow" value="Add One More Row">&nbsp;
       <input type="submit" name="proceed" value="Submit" />
    </td> 
</tr>
</table>

post 变量将是唯一的:v,并且很容易循环通过它来获取数据,这是一个 PHP 示例。

foreach($_POST['v']['label'] as $k=>$v){
    $_POST['v']['label'][$k]; // label
    $_POST['v']['observation'][$k]; // label
    $_POST['v']['remarks'][$k]; // label
}

这允许无限数量的输入,无需处理和重新格式化每个克隆的名称,并且更易于使用。

【讨论】:

  • 实际上我想每次将值增加 1 的原因是因为我希望以您列出的类似方式处理表单。如果没有任何问题,我会保留这个作为最后一个选项
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-12
  • 1970-01-01
  • 2019-06-13
  • 2021-12-01
  • 1970-01-01
  • 2017-12-01
相关资源
最近更新 更多