Ticket #1294 (closed bug: wontfix)
selectedIndex lost after clone() in Internet Explorer
| Reported by: | jesse | Owned by: | brandon |
|---|---|---|---|
| Priority: | major | Milestone: | 1.1.4 |
| Component: | core | Version: | 1.1.3 |
| Keywords: | Cc: | ||
| Blocking: | Blocked by: |
Description
It seems that after a jQuery clone(), the value of select boxes are lost in IE (but not Firefox). Try this out:
<div>
<select>
<option value="0">one</option> <option value="1" selected='selected'>two</option>
</select>
</div>
$(function(){
$('div').clone(true).appendTo('body');
});
The first option will be selected in the cloned select.
Doing something like this fixes the problem (as long as there is only one select box), though I suspect there needs to be a better fix in jQuery explicitly:
$(function(){
var old = $('div'); var clone = old.clone(true); var select_val = $('select', old).val(); $('select', clone).val(select_val); clone.appendTo('body');
});
Change History
comment:3 Changed 6 years ago by brandon
- Version changed from 1.1.2 to 1.1.3
- Milestone changed from 1.1.3 to 1.1.4
comment:4 Changed 6 years ago by brandon
- Status changed from new to closed
- Resolution set to fixed
Fixed in Rev [2438].
comment:6 Changed 6 years ago by rformato
- Status changed from closed to reopened
- Resolution fixed deleted
The bug is fixed but at a very high performance cost.
I wrote this new version:
clone: function(deep) {
deep = deep != undefined ? deep : true;
var $this;
if (jQuery.browser.msie) {
$this = this.add(this.find("*"));
// Need to remove events on the element and its descendants
$this.each(function() {
this._$events = {};
for (var type in this.$events)
this._$events[type] = jQuery.extend({},this.$events[type]);
}).unbind();
}
// Do the clone
var copy = false, r = this.pushStack( jQuery.map( this, function(a){
if (!copy && deep && ( a.hasChildNodes() || jQuery.nodeName(a,"select") || jQuery.nodeName(a,"input") ) ) copy = true;
return a.cloneNode( deep );
}) );
if (jQuery.browser.msie) {
$this.each(function() {
// Add the events back to the original and its descendants
var events = this._$events;
for (var type in events)
for (var handler in events[type])
jQuery.event.add(this, type, events[type][handler], events[type][handler].data);
this._$events = null;
});
}
// copy form values over
if (copy) {
if (!jQuery.browser.msie)
$this = this.add(this.find("*"));
var origInputs = $this.filter('select,input[@type=checkbox]');
if (origInputs.length) {
var inputs = r.add(r.find('*')).filter('select,input[@type=checkbox]');
origInputs.each(function(i) {
if (this.selectedIndex)
inputs[i].selectedIndex = this.selectedIndex;
if (this.checked)
inputs[i].checked = true;
});
}
}
// Return the cloned set
return r;
},
It is still slower but much better when you clone a single element that is not a select or a checkbox.
If using clone(false) there's a very small performance hit, but i've read it is deprecated now
Please follow the bug reporting guidlines and use jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

I have also seen this bug and would greatly appreciate a fix.