使用jQuery重新编号文本输入数组索引

时间:2012-09-11 13:00:09

标签: jquery forms

我有以下HTML块,用于从用户收集有关项目的信息作为表单的一部分:

<div class="clone_block">
  Name: <input type="text" name="items[0][name]" /><br />
  Amount: <input type="text" name="items[0][amount]" /><br />
  <button class="delete">Delete</button>
</div>

我可以克隆这个元素(如果用户想要添加另一个项目)并将它放在DOM中div.clone_block的最后一个实例之后,一切正常,我也可以删除元素。但是,我最终得到了具有相同名称的多个文本输入实例,这意味着只有最后一个显示在POST请求中(之前的请求被覆盖)。我想要做的是重新编号所有项目,使第一项为item[0],第二项为item[1]等。

有没有办法在jQuery中执行此操作?以这种方式创建名称可以更容易地使用PHP处理POST数据,因此我不希望在可能的情况下更改命名方案。

3 个答案:

答案 0 :(得分:12)

您可以实现类似这样的操作,以便在每次克隆/删除后重命名元素:

function renumber_blocks() {
    $(".clone_block").each(function(index) {
        var prefix = "items[" + index + "]";
        $(this).find("input").each(function() {
           this.name = this.name.replace(/items\[\d+\]/, prefix);   
        });
    });
}

演示:http://jsfiddle.net/Wzzf2/1/

答案 1 :(得分:6)

如果您使用PHP作为服务器端语言,则可以执行以下操作:

<div class="clone_block">
  Name: <input type="text" name="items[][name]" /><br />
  Amount: <input type="text" name="items[][amount]" /><br />
  <button class="delete">Delete</button>
</div>

PHP会在收到数据时自动处理创建正确的偏移索引。

然而,要回答您的问题,一旦克隆了块,您只需要导航其结构并使用递增的数字更改名称属性。或者更好的是仍然导航所有输入并在使用添加或删除按钮时重新索引它们...这将允许删除。

/// find each row with inputs
$('div.form_row').each(function(rowIndex){
  /// find each input with a name attribute inside each row
  $(this).find('input[name]').each(function(){
    var name;
    name = $(this).attr('name');
    name = name.replace(/\[[0-9]+\]/g, '['+rowIndex+']');
    $(this).attr('name',name);
  });
});

以上将使用以下标记(已经过测试),您应该会看到索引被重新排序:

<div class="form_row"><input name="something[0][abc]"></div>
<div class="form_row"><input name="something[2][abc]"></div>
<div class="form_row"><input name="something[3][abc]"></div>

校正<!/ EM>

刚刚实现了依赖PHP生成索引的错误......如果你的索引是数组结构的最后一部分,它将会起作用:

something[abc][]
something[def][]

但如果你正在使用(就像你一样):

something[][abc]
something[][def]

您将结束以下PHP方面:

array (
   '0' => array( 'abc' => 'value' ),
   '1' => array( 'def' => 'value' ),
)

而不是:

array (
   '0' => array( 
     'abc' => 'value',
     'def' => 'value',
   ),
);

这可能更符合您的要求。因此,对于您的示例,请忽略我提到的PHP路由并使用jQuery代码段。如果每行只有一个输入,那么PHP解决方案仍然有用......

答案 2 :(得分:3)

如果您想在复制时使用索引执行其他操作,则会更复杂一些:

var name = $('input').attr('name'),
    newId = parseInt(name.match(/\d+/)[1])++;

// clone the input and use newId for something else

$('input.new').attr('name', name.replace(/\d+/, newId));