Re-numbering text input array indices with jQuery

匿名 (未验证) 提交于 2019-12-03 08:54:24

问题:

I have the following block of HTML which is used to collect information about an item from the user as part of a form:

<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>

I can clone this element (if the user wants to add another item) and place it after the last instance of div.clone_block in the DOM and everything works fine, and I can also delete elements. However, I end up with multiple instances of text inputs with the same name, which means only the last one shows up in a POST request (the previous ones are overwritten). What I want to do is re-number all the items so that the first is item[0], the second is item[1] etc.

Is there a way to do this in jQuery? Creating the names in this way makes it easier to process the POST data with PHP, so I don't want to change the naming scheme if possible.

回答1:

You can implement something like this to rename the elements after each clone/removal:

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);            });     }); }

Demo: http://jsfiddle.net/Wzzf2/1/



回答2:

If you are using PHP as your sever-side language you can do this:

<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 will automatically handle creating the right offset indexes when it receives the data.

To answer your question however, once you have cloned your block you just need to navigate its structure and change the name attributes with an incremented number. Or better still navigate all the inputs and re-index them whenever an add or delete button is used... this will allow for deletions.

/// 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);   }); });

The above will work (and has been tested) with the following markup, you should see the indexes get re-ordered:

<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>

Correction!

Just realised a bug with relying on PHP to generate the indexes... it will work if your indexes are the last part of the array structure:

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

But if you are using (like you are):

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

You will end up the following PHP side:

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

Rather than:

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

Which is probably more what you want. So for your example ignore the PHP route that I mention and use the jQuery snippet instead. The PHP solution is still useful if you only have one input per row however...



回答3:

If you want to do something else using the index while copying it would be a bit more complicated:

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));


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!