3

我有以下 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>

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

有没有办法在 jQuery 中做到这一点?以这种方式创建名称可以更轻松地使用 PHP 处理 POST 数据,因此如果可能,我不想更改命名方案。

4

3 回答 3

13

您可以在每次克隆/删除后实施类似的方法来重命名元素:

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/

于 2012-09-11T13:17:17.630 回答
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>

更正!

刚刚意识到依赖 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 解决方案仍然很有用......

于 2012-09-11T13:06:59.087 回答
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));
于 2012-09-11T13:14:57.283 回答