cloneNode() - Cloning Existing Form Objects
- Assigning unique names

- Introduction
- Assigning Unique names
- Assigning Unique ids
- Retaining Values and Object States

for IE5.5+, N7+, and Mozilla 1.1

There are 2 critical aspects to assigning unique names:
1 - the ability of the browser to recognise the new names
2 - the ability of the browser to add the new elements to the form array

Unless the browser can do both of these things, cloning cannot be used with forms.

 

Text inputs

Let's start with the simplest problem - cloning text inputs and giving them unique names. In the example below, there are three text inputs named LAST_NAME_0, FIRST_NAME_0, and NICKNAME_0. The function addRow() clones the row of inputs, renames them by incrementing the number at the end of each field name, sets the values to the new names, and adds the row to the table.

<script>
nameNum = 1; // -- This is the number for the new row names. We start with 1 because we already have row 0

function addRow(){
  // -- get the table id="test1"
 var t = document.getElementById('test1');
  // - get the first tbody tag belonging to var t (this is where our inputs are )
 var tb = t.getElementsByTagName('tbody')[0];
 var tr0 = tb.childNodes[0];

 var myClone = tr0.cloneNode(true);
 // -- get the number of inputs contained in the cloned row
 var newInpt = myClone.getElementsByTagName('input');
 
 // -- for Mac IE 5, the appendChild statement must be here instead of
 // -- the end of the function or the row won't be added
 // -- tb.appendChild(myClone)

for (i=0; i < newInpt.length; i++){
  // -- get only the non-numeric part of the name using a regular expression; 
  // -- concatinate it with nameNum to create the new name
 var newName = newInpt[i].name.substring(0,newInpt[i].name.search(/\d/)) + inNo;
 newInpt[i].setAttribute('name',newName);
 newInpt[i].setAttribute('value',newName);
 }
nameNum++;

tb.appendChild(myClone);
}
</script>

Table id="test1"
Last Name First Name Nickname

Test 1: Count # of form elements (remember, the button counts as 1) using document.form.elements.length;
Test 2: Show names of all form elements using document.formName.elements[i]
Test 3: Show names using getElementsByTagName('input')
Test 4: Choose an element to select:
Test 5: Adds new inputs to request string
Request String:

Here's how different browsers did on the tests:
  WIN MAC
TEST Mozilla 1.1 N7 N6 IE5.5+ Opera 6.05 N6 IE5+
function addRow() YY Y Y N Y B
Test 1 YY N Y n/a N B
Test 2 Y Y N Y n/a N N
Test 3 Y Y Y Y n/a Y Y
Test 4 YY Y N n/a Y N
Test 5 YY N Y n/a N N
B = buggy


As you can see, even with this basic example, we're already running into problems.
Opera 6 is out of the game.
Mac IE 5 behaves so strangely it should probably be disqualified. The appendChild won't work unless it comes before the loop. Even then, every time you append the new row, the table keeps getting mysteriously wider. And unlike the Win version, Test 5 doesn't work.
N6 can't recognise the new objects as part of the forms[i].elements array and fails to add them to the request string on submit. Oddly, N6 passes Test 4 which uses document.formName.elementName.select(). IE 5.5+, which passes Test 2, fails Test 4. (!???!) Go figure.

 

 

All form objects

Using function addRow() as a starting point, we'll create a new function that can handle all form objects. The new function will be addRow2().

<script>
nameNum = 1;

function addRow2(){
 var t = document.getElementById('test2');
 var tb = t.getElementsByTagName('tbody')[0];
 var tr0 = tb.childNodes[0];

 var myClone = tr0.cloneNode(true);
 var newInpt = myClone.getElementsByTagName('input');
 var newSel = newRow.getElementsByTagName('select');
 var newTa = newRow.getElementsByTagName('textarea');
 
 // -- for Mac IE 5, the appendChild statement must be here instead of
 // -- the end of the function or the row won't be added
 // -- tb.appendChild(myClone)

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

nameNum++;
tb.appendChild(myClone);
}
</script>
Table id="test2"
Name State Sex Options Comment  
M
F
Soup
Salad

Test 1: Count # of form elements (remember, the button counts as 1) using document.form.elements.length;
Test 2: Show names of all form elements using document.form.elements[i]
Test 3: Show names using getElementsByTagName('input')
Test 4: Show names using getElementsByTagName('select')
Test 5: Show names using getElementsByTagName('textarea')
Test 6: Choose an element to focus on:
Test 7: Adds new inputs to request string - remember to fill out the form first
Request String:
Here's how different browsers did on the tests:
  WIN MAC
TEST Mozilla 1.1 N7 N6 IE5.5+ Opera 6.05 N6 IE5+
function addRow() Y Y B Y N B B
Test 1 Y Y N Y n/a N N
Test 2 Y Y N Y n/a N N
Test 3 Y Y Y Y n/a Y Y
Test 4 Y Y Y Y n/a Y Y
Test 5 Y Y Y Y n/a Y Y
Test 6 Y Y B N n/a B N
Test 7 Y Y N Y n/a N N
Radio Buttons function properly Y Y N N n/a N N
Checkboxes function properly Y Y N Y n/a N N
B = buggy


There's a lot of buggy behavior when it comes to cloned radios and checkboxes.

Bugs:

Netscape 6 - Test 6 works for all elements except radios and checkboxes.
Cloned radios and checkboxes cannot be checked.
Also, N6 clearly has a problem cloning buttons. We'll see more of this in "Retaining Values and Object States".
Win IE 5.5+ - You can only check one radio button out of all original and cloned radios. The browser treats them as if they all have the same name, although the other tests indicate otherwise.
Mac IE 5.5+ - Boy is this buggy - and how! Cloned radios, checkboxes, textareas, and buttons display as text inputs even though Tests 3-5 show it recognizes them. Also, same problems as indicated in the first example. Due to these problems, this tutorial will do no further testing with Mac IE5.
Interesting Note - In Test 2, N7 and Mozilla list functionButton before the cloned elements, not as the last item as you would expect.

Assigning Unique ids >>








PXL8 2003