views:

745

answers:

4

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"&gt;&lt;/script&gt;
        <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?

+1  A: 

not an answer, is an analysis to the question asked:

<!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"&gt;&lt;/script&gt;
        <script type="text/javascript">
            $(document).ready(function() {
                $('#add').click(function() {
                    var ul = $('#ul');

                    var liclone1 = ul.find('li:last').clone(true);
                    var liclone2 = ul.find('li:last')[0].cloneNode(true);
                    var liclone3 = $( ul.find('li:last')[0].cloneNode(true) );
                    var liclone4 = $( '<li><input type="text" name="foo[88]"></li>' );

                    var linew    = document.createElement("li"); 
                    linew.innerHTML = '<input type="text" name="foo[99]">';

                    $('#showsource').text("");
                    $('#showsource').text($('#showsource').text() + $(liclone1)[0].outerHTML);
                    $('#showsource').text($('#showsource').text() + $(liclone2)[0].outerHTML);
                    $('#showsource').text($('#showsource').text() + $(liclone3)[0].outerHTML);
                    $('#showsource').text($('#showsource').text() + $(liclone4)[0].outerHTML);
                    $('#showsource').text($('#showsource').text() + $(linew)[0].outerHTML);
                    $('#showsource').text($('#showsource').text() + $(ul)[0].outerHTML);
                    $('#showsource').text($('#showsource').text() + $(ul)[0].innerHTML);

                });
            });
        </script>
    </head>
    <body>
        <ul id="ul">
            <li><input type="text" name="foo[0]"></li>
            <li><input type="text" name="foo[1]"></li>
        </ul>
        <button id="add">Add</button>
        <pre id="showsource"></pre>
    </body>
</html>

Result:

<LI><INPUT name=foo[1]> 
<LI><INPUT name=foo[1]> 
<LI><INPUT name=foo[1]> 
<LI><INPUT name=foo[88]></LI>
<LI><INPUT name=foo[99]></LI>
<UL id=ul><LI><INPUT name=foo[0]> 

<LI><INPUT name=foo[1]> </LI></UL><LI><INPUT name=foo[0]> 
<LI><INPUT name=foo[1]> </LI>

so I can analyze it, the only way is to make a new li with createElement or create the object with $(...)

andres descalzo
+1  A: 

I wonder if you are running into this bug in IE (even with jQuery)?

Essentially in IE you can't change the name attribute of elements (regular or cloned) (and then re-access them via javascript by name) although you can submit them (e.g. input elements) and have them successfully submit.

scunliffe
Thanks for the link (+1). You're right that they get submitted, but my first SSCCE would send the parameters as `foo[0]`, `foo[1]`, `foo[1]`, `foo[1]`,... Thus, only one of `0` and multiple of `1` (for clones of clones). I can however rewrite the code so that it only clones the original, but I also **need** to be able to re-access them after adding, because they may be involved in other jQuery actions afterwards (like rearranging and sorting).
BalusC
+1  A: 

This post is also about this subject which gave me an insight into this problem.

http://stackoverflow.com/questions/2105815/weird-behaviour-of-iframe-name-attribute-set-by-jquery-in-ie

XGreen