IE6 & IE7 quirks with cloneNode() and form elements

Categories: JavaScript, jQuery

I've been working on some code for a contracting client which involves a really cool drag-n-drop interface for building forms on-the-fly. While working on the project, I ran into an issue in IE6 when dragging a <div /> element that form fields and there values had been changed by the user, the values were not properly reflected when I'd copy the node using the cloneNode() DOM method.

It turns out IE 6/7 doesn't properly clone some form elements when you use the cloneNode(true) and the form element is a checkbox, radio or select element. My suspicion is this is because MSIE stores the element in a non-XHTML way (if you do an innerHTML on the source element you'll see that checkbox elements have a "CHECKED" attribute with no value.)

I was able to work around the issue by doing the following:

var clonedEl = elm.cloneNode(true);
/*
* if this is MSIE 6/7, then we need to copy the innerHTML to
* fix a bug related to some form field elements
*/
if( !!document.all ) clonedEl.innerHTML = elm.innerHTML;

The project I'm working on is actually using the jQuery Interface v1.2 library. To fix the problem I actually had to modify the source code in the Draggables to find instances of the cloneNode(true) method and apply the fix.

NOTE:
The actual fix I used in jQuery varies slightly, as I used available jQuery methods to detect IE6. In jQuery you can do:
var clonedEl = elm.cloneNode(true);
/*
* if this is MSIE 6/7, then we need to copy the innerHTML to
* fix a bug related to some form field elements
*/
if( jQuery.browser.msie && (jQuery.browser.version <= 7) )
   clonedEl.innerHTML = elm.innerHTML;

This quite frankly feels like an issue I've run into before, but just forgot the solution. Hopefully blogging about it well help me if I ever run into the problem again.

UPDATE:

I've added an example page that shows this problem off in action: http://www.pengoworks.com/workshop/bugs/cloneNode_issue.htm

Comments

VulgarisOverIP's Gravatar Thank you so much, you've stopped the hours of torture.
Santiago's Gravatar Thanks man, this was a big help for me.
Erik's Gravatar Thanks for this post. I just ran into this problem, but I wanted to note that this solution does not quite work in Firefox. It seems that once you copy the innerHTML to the cloned element, Firefox loses the attributes (what IE was doing before we copied innerHTML). So to get around this I resorted to sniffing for IE before copying the innerHTML. Am I missing something here? Does anyone know if Prototype or jQuery have a cross-platform method for this built in? For instance, try using your example form in Firefox (2.0 here) -- the first clone method works fine, but the second one ('w/fix') doesn't copy the attributes.
Dan G. Switzer, II's Gravatar @Erik:

If you read the blog entry, you'll see that I only apply that to IE6. The test page was purely to illustrate the problem that IE has. You should only apply the fix to IE6.

I believe jQuery might have since worked in a fix for this, but I haven't looked at the clone() in a while.

Add Comment



If you subscribe, any new posts to this thread will be sent to your email address.