views:

48

answers:

0

I'm having trouble with a short script used to clone a group of controls in a form. This script works fine in Firefox and Internet Explorer 8, but doesn't work as I would expect in Internet Explorer 7

The script makes a deep copy of the specified node, renaming every name/identifier that ends with a number, incrementing the numeric part.

I've reduced the script to write the following example based on php

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"&gt;
<html>
<head>
    <script type="text/javascript">

// finds the max index of the element list identified by elementid
function findmaxelementid(elementid)
{
    // limito la lunghezza massima della lista a 10 elementi
    for (var i = 0; i < 9; ++i)
    {
        if (!document.getElementById(elementid + i))
        {
            return i - 1;
        }
    }
    return -1;
}

// removes the index part of the element name
function nameroot(name)
{
    var len = name.length;
    if (name.slice(len - 1, len) >= '0' && name.slice(len - 1, len) <= '9')
    {
        return name.slice(0, len - 1);
    } 
    else
    {
        return null;
    }
}

// recursive function to rename every identifier/name with an index part
function renamenode(node, newid)
{
    if (typeof(node.attributes) != "undefined" && node.attributes)
    {
        for (var i = 0; i < node.attributes.length; ++i)
        {
            var attributeroot = null;
            if (node.attributes[i].value != null)
            {
                attributeroot = nameroot(node.attributes[i].value);
            }
            if (attributeroot != null && (node.attributes[i].name == "name" ||
                                          node.attributes[i].name == "id" ||
                                          node.attributes[i].name == "for"))
            {
                node.attributes[i].value = attributeroot + newid;
            }
        }
    }

    if (typeof(node.childNodes) != "undefined")
    {
        for (var i = 0; i < node.childNodes.length; ++i)
        {
            renamenode(node.childNodes[i], newid);
        }
    }
}


// copy the group of controls identified by elementid, contained in the node 
// specified by containerid
function addelement(elementid, containerid)
{
    var maxid = findmaxelementid(elementid);

    var newid = maxid + 1;
    var container;
    var element = document.getElementById(elementid + maxid);
    var newelement = element.cloneNode(true);

    renamenode(newelement, newid);

    if (container = document.getElementById(containerid))
    {
        container.appendChild(document.createElement('br') );
        container.appendChild(newelement);
    }
    return null;
}

    </script>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
    <body>
        <?php echo "<pre>\n"; print_r($_POST); echo"</pre>\n"; ?>
            <form method="post" id="myid">
                <fieldset name="fieldseta">
                <legend>My list</legend>
                <div id="mylist">
                    <div id="myelement0">
                        <label for="Amount0">Amount</label>
                        <input id="Amount0" name="Amount0" type="text" value="0">
                    </div>
                </div>
                <input type="button" value="Add element" 
                            onclick="return addelement('myelement', 'mylist')">
                </fieldset>
                <input type="submit" value="Submit"/>
            </form>
    </body>
</html>

this example shows a from with a input field named Amount0. Pressing the "Add element" button generates a Amount1 element and so on up to Amount9.

After the submit, the php code dumps the $_POST array.

By pressing the button two times and inserting 0, 1 and 2, this is the result:

Firefox and IE8:

Array
(
    [Amount0] => 0
    [Amount1] => 1
    [Amount2] => 2
)

IE7

Array
(
    [Amount0] => 0
    [Amount2] => 1
    [Amount1] => 2
)

The scripts renames the new element, therefore this looks to me like a bug that was fixed in IE8

Since I'm new to javascript programming, I wonder if this is a known issue of cloneNode or of the attributes collection and if there is a workaround that works on both IE7 and IE8