This SSCCE says it all:
<!doctype html> <html lang="en"> <head> <title>Test</title> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script type="text/javascript"> $(document).ready(function() { $('#add').click(function() { var ul = $('#ul'); var liclone = ul.find('li:last').clone(true); var input = liclone.find('input'); input.attr('name', input.attr('name').replace(/(foo\[)(\d+)(\])/, function(f, p1, p2, p3) { return p1 + (parseInt(p2) + 1) + p3; })); liclone.appendTo(ul); $('#showsource').text(ul.html()); }); }); </script> </head> <body> <ul id="ul"> <li><input type="text" name="foo[0]"></li> </ul> <button id="add">Add</button> <pre id="showsource"></pre> </body> </html>
Copy'n'paste'n'run it, click the Add
button several times. On every click you should see the HTML code of the <ul>
to show up in the <pre id="showsource">
and the expected code should roughly be:
<li><input name="foo[0]" type="text"></li> <li><input name="foo[1]" type="text"></li> <li><input name="foo[2]" type="text"></li> <li><input name="foo[3]" type="text"></li>
This works as expected in FF, Chrome, Safari, Opera and IE8.
However, IE6/7 fails in changing the name
attribute and produces like:
<li><input name="foo[0]" type="text"> <li><input name="foo[0]" type="text"> <li><input name="foo[0]" type="text"> <li><input name="foo[0]" type="text"></li>
I googled a bit and found this very similar problem, he fixed it and posted a code snippet how it should have look like. Unfortunately this is exactly what I already have done, so I suspect that he was only testing in IE8, not in IE6/7. Other than that particular topic Google didn't reveal much.
Any insights? Or do I really have to grab back to document.createElement
?
Note: I know that I can use just the same name for each input element and retrieve them as an array, but the above is just a basic example, in real I really need to have the name attribute changed, because it not only contains the index, but also other information such as parentindex, ordering, etc. It's been used to add/rearrange/remove (sub)menu items.
Edit: this is related to this bug, The jQuery (I'm using 1.3.2) does thus not seem to create inputs that way? The following does just work:
$('#add').click(function() { var ul = $('#ul'); var liclone = ul.find('li:last').clone(true); var oldinput = liclone.find('input'); var name = oldinput.attr('name').replace(/(foo\[)(\d+)(\])/, function(f, p1, p2, p3) { return p1 + (parseInt(p2) + 1) + p3; }); var newinput = $('<input name="' + name + '">'); oldinput.replaceWith(newinput); liclone.appendTo(ul); $('#showsource').text(ul.html()); });
But I can't imagine that I am the only one who encountered this problem with jQuery. Even a simple $('<input>').attr('name', 'foo')
doesn't work in IE6/7. Isn't jQuery as being a crossbrowser library supposed to cover this particular issue under the hoods?
Here is a function that will set the name of an element in all browsers, even IE6 and IE7. It is adapted from the code at http://matts411.com/post/setting_the_name_attribute_in_ie_dom.
function setElementName(elems, name) { if ($.browser.msie === true){ $(elems).each(function() { this.mergeAttributes(document.createElement("<input name='" + name + "'/>"), false); }); } else { $(elems).attr('name', name); } }
I found that using replaceElement and outerHTML was not reliable across different versions of IE. But the mergeAttributes trick above works perfectly!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With