Skip to main content

Bug Tracker

Side navigation

#1294 closed bug (wontfix)

Opened June 13, 2007 11:12PM UTC

Closed September 18, 2007 02:42PM UTC

Last modified March 15, 2012 01:03AM UTC

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:
Blocked by: Blocking:
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');

});

Attachments (0)
Change History (7)

Changed July 12, 2007 08:42PM UTC by mrtwice99 comment:1

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

Changed July 20, 2007 09:19PM UTC by brandon comment:2

owner: → brandon

Changed July 21, 2007 02:46AM UTC by brandon comment:3

milestone: 1.1.31.1.4
version: 1.1.21.1.3

Changed July 21, 2007 03:16AM UTC by brandon comment:4

resolution: → fixed
status: newclosed

Fixed in Rev [2438].

Changed July 21, 2007 05:07AM UTC by brandon comment:5

Actually this bug also exists in the other browsers when the selected attribute isn't set. It also applied to checkboxes which Rev [2439] fixes. Except #769 causes IE6 to loose the checkbox state.

Changed August 24, 2007 11:18AM UTC by rformato comment:6

resolution: fixed
status: closedreopened

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

Changed September 18, 2007 02:42PM UTC by brandon comment:7

resolution: → wontfix
status: reopenedclosed

The fix for this is to expensive for the core and has been removed in 1.2. The workaround is simple. Just copy the selectedIndex from the original.