cloneNode() - Cloning Existing Form Objects
- Retaining Values and Object States
for IE5.5+, N7+, and Mozilla 1.1
! SOLUTION ALERT !
Dave Chisholm has developed a great script that lets cloned form objects retain all the attributes and event handlers of the originals. You can see the form in action at http://www.receptiveearth.comYou may have noticed this in the section on assigning unique names: if you fill out a row of form elements before you clone it, the clones don't always keep the value of the original. The table directly below shows the results for cloned elements in different browsers.
| WIN | MAC | ||||||
| Retains Value or State | Mozilla 1.1 | N7 | N6 | IE5.5+ | Opera 6.05 | N6 | IE5+ |
| Text Input | N | N | N | Y | n/a | N | n/a |
| Select | N | N | N | N | n/a | N | n/a |
| Radio | N | N | N | N | n/a | N | n/a |
| Checkboxes | N | N | N | N | n/a | N | n/a |
| Textarea | N | N | N | Y | n/a | N | n/a |
| Button | Y | Y | N | Y | n/a | N | n/a |
In order to keep the values and states of the original elements, we need to add additional code to our addRow() function. We start out by cloning the row and adding the clone to the table. Next we need to determine the values of the original elements and then assign them to the new ones.
The example below is slightly different from ones we've used before. In previous examples we cloned only the first row. In this example we start out with 3 rows in the table and you have the option of cloning any row.
<script> // -- we already have rows 0,1, and 2 so new rows start at 3 var nameNum = 3; function addRow(node) { var t = document.getElementById('test2'); var tb = t.getElementsByTagName('tbody')[0]; var tr = node.parentNode.parentNode; // -- use this line if you want to be able to choose which rows to clone var myClone = tr.cloneNode(true); // -- use the next 2 lines if you only want to copy the first row //var tr = tb.childNodes[0]; //var myClone = tr.cloneNode(true); // -- add the new row to the table before setting the values tb.appendChild(myClone); var newInpt = myClone.getElementsByTagName('input'); var newSel = myClone.getElementsByTagName('select'); var newTa = myClone.getElementsByTagName('textarea'); for (i=0; i < newInpt.length; i++){ var newName = newInpt[i].name.substring(0,newInpt[i].name.search(/\d/)) + nameNum; newInpt[i].setAttribute('name',newName); if (newInpt[i].type == 'text' || newInpt[i].type == 'button') newInpt[i].setAttribute('value',tr.getElementsByTagName('input')[i].value); if (newInpt[i].type == 'checkbox' || newInpt[i].type == 'radio') { if (tr.getElementsByTagName('input')[i].checked == true) newInpt[i].setAttribute('checked',true); } } for (i=0; i < newTa.length; i++){ var newName = newTa[i].name.substring(0,newTa[i].name.search(/\d/)) + nameNum; newTa[i].setAttribute('name',newName); newTa[i].setAttribute('value',tr.getElementsByTagName('textarea')[i].value); // -- this next line is for N7 + Mozilla newTa[i].defaultValue = tr.getElementsByTagName('textarea')[i].value; } for (i=0; i < newSel.length; i++){ var newName = newSel[i].name.substring(0,newSel[i].name.search(/\d/)) + nameNum; newSel[i].setAttribute('name',newName); var oIndx = tr.getElementsByTagName('select')[i].selectedIndex; if (oIndx != -1){ newSel[i].selectedIndex = oIndx // -- this next line is for N7 + Mozilla newSel[i].getElementsByTagName('option')[oIndx].setAttribute('selected',true); } } nameNum++; } </script>
| WIN | MAC | ||||||
| Retains Value or State | Mozilla 1.1 | N7 | N6 | IE5.5+ | Opera 6.05 | N6 | IE5+ |
| Text Input | Y | Y | Y | Y | n/a | Y | n/a |
| Select | Y* | Y* | Y | Y | n/a | Y | n/a |
| Radio | Y* | Y* | N | B | n/a | N | n/a |
| Checkboxes | Y | Y | N | Y | n/a | N | n/a |
| Textarea | Y* | Y* | Y | Y | n/a | Y | n/a |
| Button | Y | Y | B | Y | n/a | B | n/a |
| Button Behaviour | Y | Y | N | Y | n/a | N | n/a |
| B = buggy, * - notes | |||||||
Bugs:
| N6 - | Buttons keep their names but seem to loose part of their values. Same problems with radios and checkboxes as before. |
| Win IE 5.5+ - | The cloned radio buttons take the checked state; the original row looses it. It's the same problem we saw in "Assigning Unique names". |
| N7 & Mozilla - | Radio buttons - setting the checked state when cloning an original row works; it does not work when cloning a clone (same problem as IE 5.5+ bug). Selects and Textareas - extra code needed for this to work. See the script above. |
PXL8 2003