Log in

Previous Entry | Next Entry

Interesting IE bug.

I've found an interesting little bug in Internet Explorer, by interesting I of course mean totally bloody annoying. I shall walk you through the situation. You have an existing input element you'd like to make a copy of with a new name. EG:

<input id="target" name="target_input" value="value">

So you grab it, clone it, rename the clone and append it like so:

var base = document.getElementById( 'target' );
var newNode = base.cloneNode( true );
newNode.name = 'new_input';
newNode.id= 'new_target';
base.parentNode.appendChild( newNode );

Woot! You now have two input tags. Here's where it gets interesting. what would you expect the following code to do?

var list = document.getElementsByName( 'target_input' );
for ( var i = 0; i < list.length; i++ )
   list[i].value = list[i].name;

If you answer was set the first input field to have a value of 'target_input' and the second would keep it's value of 'value' then well done, have a banana. If your answer was set the first input field to have a value of 'target_value' and the second would keep it's value of 'new_input' then I guess you work for Microsoft.

Yup. document.getElementsByName( 'target_input' ); returns our new element in IE despite it knowing that the name has been changed. Interestingly document.getElementsByName( 'new_input' ); returns a single element list with just our new element in it. Yup, IE seems to have gone a tad nutty. The moral of this story seems to be avoid cloneNode with form elements and IE. Joy.


( 9 comments — Leave a comment )
Dec. 18th, 2007 03:33 pm (UTC)
strange that because it seems to work for me:

however - firefox *doesn't* do what i'd expect your code to do... it sets the value of the first element correctly, but leaves the second one blank.

two differences in my code:
- the input tag is well-formed
- i'm setting the value of the new element to a blank string

(internet explorer 6, firefox

Edited at 2007-12-18 03:34 pm (UTC)
Dec. 18th, 2007 03:38 pm (UTC)
actually, i'm wrong - firefox is doing what i expect. what does appear to be wrong, is that internet explorer is returning the new element is in the list as well as the old one.

is name and id definately writable (i haven't done any ecmascript for a while now) ?

Edited at 2007-12-18 03:38 pm (UTC)
Dec. 18th, 2007 03:41 pm (UTC)
Yup. Like I say if you call document.getElementsByName( 'new_input' ); you get the new element returned.
Dec. 18th, 2007 03:43 pm (UTC)
Side note. If you keep adding new inputs using cloneNode they ALL get picked up by the getElementsByName.
Dec. 18th, 2007 03:47 pm (UTC)
that's a pain in the bum. you'll have to write your own getElementsByName method for internet explorer for occasions like this.

i bet the m$ implementation of node has a seperate private field for "name" which is what they use when you call getElementsByName rather than the public field which would have been sensible/correct/etc. is there any way to introspect that?
Dec. 18th, 2007 03:49 pm (UTC)
Probably but I prefer to just chalk it up as (another) IE foible and work out how to work round it.
Dec. 18th, 2007 03:55 pm (UTC)
i've added a note to the msdn website to let other people know! ;)
Dec. 18th, 2007 03:58 pm (UTC)
See that's the smart thing to do. Note the mention there that it also (incorrectly) returns items the the ID requested.

Plus of course document.getElementById() in IE will return the first item in the document with the id or name attribute specified....

I love IE so much.
Dec. 18th, 2007 03:39 pm (UTC)
Why shouldn't it leave the second one blank? It's not got a name of 'target_input' so won't be selected. This is what I would expect to happen.

Once you've cloned you node and renamed it there should only be one node named 'target_input' so only that one should have the value changed.

IE 7 which I just tested you code with does both... what does IE 6 do?
( 9 comments — Leave a comment )