Skip to main content

Bug Tracker

Side navigation

#8500 closed bug (fixed)

Opened March 11, 2011 07:20AM UTC

Closed April 17, 2011 01:39AM UTC

Last modified May 31, 2011 05:51PM UTC

radios and checkboxes revert to default (HTML) state when wrapped in IE

Reported by: gnarf Owned by: gnarf
Priority: low Milestone: 1.6
Component: manipulation Version: 1.5.2
Keywords: Cc:
Blocked by: Blocking:
Description

http://jsfiddle.net/eGgvw/6/

calling .wrap() on something that contains a radio or checkbox will cause it to revert to the state in the HTML that created it.

Attachments (0)
Change History (17)

Changed March 11, 2011 07:53AM UTC by gnarf comment:1

_comment0: I apologize for duping http://bugs.jquery.com/ticket/769 but to hopefully redeem myself I will correct with a punchable plugin for those that need this in IE6: http://jsfiddle.net/eGgvw/10/ \ \ {{{ \ (function($) { \ var _append = $.fn.append; \ \ $.fn.append = function(args) { \ var inps = $(), ret; \ if ( args && args.jquery ) { \ inps = $( args ).find( 'input:checked' ); \ } \ ret = _append.apply(this, arguments); \ if ( args && args.jquery ) { \ $( args ).find( 'input:checked' ).not(inps).removeAttr('checked'); \ } \ inps.attr('checked', 'checked'); \ return ret; \ }; \ })(jQuery); \ \ }}} \ 1299830543617585
_comment1: I apologize for duping http://bugs.jquery.com/ticket/769 but to hopefully redeem myself I will correct with a punchable plugin for those that need this in IE6: http://jsfiddle.net/eGgvw/11/ \ \ {{{ \ (function($) { \ var _append = $.fn.append; \ \ $.fn.append = function( arg ) { \ var inps = $(), ret; \ if ( arg && arg.jquery ) { \ inps = arg.find( 'input:checked' ); \ } \ ret = _append.apply( this, arguments ); \ if ( arg && arg.jquery ) { \ arg.find( 'input:checked' ) \ .not( inps ) \ .removeAttr( 'checked' ); \ } \ inps.attr( 'checked', 'checked' ); \ return ret; \ }; \ })(jQuery); \ }}} \ 1299832378068573
_comment2: I apologize for duping http://bugs.jquery.com/ticket/769 but to hopefully redeem myself I will correct with a punchable plugin for those that need this in IE6: http://jsfiddle.net/eGgvw/11/ \ \ {{{ \ (function($) { \ var _append = $.fn.append; \ \ $.fn.append = function( arg ) { \ var inps = $(), ret; \ if ( arg && arg.jquery ) { \ inps = arg.find( 'input' ).andSelf().filter( 'input:checked' ); \ } \ ret = _append.apply( this, arguments ); \ if ( arg && arg.jquery ) { \ arg.find( 'input' ).andSelf() \ .filter( 'input:checked' ) \ .not( inps ) \ .removeAttr( 'checked' ); \ } \ inps.attr( 'checked', 'checked' ); \ return ret; \ }; \ })(jQuery); \ }}} \ 1299833553908191
_comment3: I apologize for duping http://bugs.jquery.com/ticket/769 but to hopefully redeem myself I will correct with a punchable plugin for those that need this in IE6: http://jsfiddle.net/eGgvw/13/ \ \ {{{ \ (function($) { \ var _append = $.fn.append; \ \ function getChecked(el) { \ if (el && el.jquery) { \ return el.length == 1 && el[0].nodeName == "INPUT" && el[0].checked ? el : el.find('input:checked'); \ } \ return $(); \ } \ \ $.fn.append = function(arg) { \ var chk = getChecked(arg), \ ret = _append.apply(this, arguments); \ getChecked(arg).removeAttr('checked'); \ chk.attr('checked','checked'); \ return ret; \ }; \ })(jQuery);}}} \ 1299833633606794
_comment4: I apologize for duping http://bugs.jquery.com/ticket/769 but to hopefully redeem myself I will correct with a punchable plugin for those that need this in IE6: http://jsfiddle.net/eGgvw/13/ \ \ {{{ \ (function($) { \ var _append = $.fn.append; \ \ function getChecked(el) { \ if (el && el.jquery) { \ return el.length == 1 && el[0].nodeName == "INPUT" && el[0].checked ? el : el.find('input:checked'); \ } \ return $(); \ } \ \ $.fn.append = function(arg) { \ var chk = getChecked(arg), \ ret = _append.apply(this, arguments); \ getChecked(arg).removeAttr('checked'); \ chk.attr('checked','checked'); \ return ret; \ }; \ })(jQuery); \ }}} \ 1299833719674322

I apologize for duping http://bugs.jquery.com/ticket/769 but to hopefully redeem myself I will correct with a punchable plugin for those that need this in IE6: http://jsfiddle.net/eGgvw/13/

(function($) {
    var _append = $.fn.append;

    function getChecked( el ) {
        if ( el && el.jquery ) {
            return el.length == 1 && el[0].nodeName == "INPUT" && el[0].checked ? 
                el : 
                el.find('input:checked');
        }
        return $();
    }

    $.fn.append = function( arg ) {
        var chk = getChecked( arg ),
            ret = _append.apply( this, arguments );
        getChecked( arg ).removeAttr( 'checked' );
        chk.attr( 'checked', 'checked' );
        return ret;
    };
})(jQuery);

Changed March 11, 2011 09:36AM UTC by gnarf comment:2

_comment0: So far the closest to a feature detect I've gotten is this: \ \ {{{ \ var div = document.createElement(div), \ input; \ \ div.innerHTML = "<input type='checkbox' />"; \ input = div.getElementsByTagName( "input" )[ 0 ]; \ \ // IE6 actually sets checked to true here, and if it doesn't work, the \ // appendChild doesn't clear the checked state - it should be fairly safe \ input.click(); \ jQuery.support.noAppendChecked = input.checked && !div.appendChild(input).checked; \ }}}1299836268909073

So far the closest to a feature detect I've gotten is this:

var div = document.createElement(div),
	input;

div.innerHTML = "<input type='checkbox' />";
input = div.getElementsByTagName( "input" )[ 0 ];

// IE6 actually sets checked to true here, and if it doesn't work, the
// appendChild doesn't clear the checked state - it should be fairly safe
input.click();
// interestingly - if you set input.checked = true it will work - odd eh?
// and maybe we should call this "appendResetsChecked"
jQuery.support.noAppendChecked = input.checked && !div.appendChild(input).checked;

Changed March 11, 2011 10:12AM UTC by gnarf comment:3

http://jsperf.com/append-checked -- Might not be the right way to test the effects, but they don't seem that drastically bad here...

Changed March 11, 2011 02:33PM UTC by scottgonzalez comment:4

Changed March 11, 2011 03:12PM UTC by dmethvin comment:5

See also #1736, where someone was asking for the ability to preserve arbitrary expando properties. I think it's better to just deal with the critical ones like checked as you've done here.

But... doesn't this problem iron itself out if the attr rewrite sets the checked attribute when someone uses $(":checkbox").attr("checked", true); ? That way when the element is cloned and/or serialized it will reflect the current check state.

Of course, if someone uses $(":text").attr("value", "abc"); that would also change the serialized state of the element. I think that $(":text").val("abc"); should only set the dynamic state (value property) and leave the value attribute unmolested.

Changed March 11, 2011 04:22PM UTC by dmethvin comment:6

Nope, setting the checked attribute doesn't seem to be enough for IE6:

http://jsfiddle.net/AhhJh/

Changed March 11, 2011 05:49PM UTC by gnarf comment:7

Replying to [comment:5 dmethvin]:

See also #1736, where someone was asking for the ability to preserve arbitrary expando properties. I think it's better to just deal with the critical ones like checked as you've done here.

Agreed

But... doesn't this problem iron itself out if the attr rewrite sets the checked attribute when someone uses $(":checkbox").attr("checked", true); ? That way when the element is cloned and/or serialized it will reflect the current check state.

Yeah, but thats not going to catch the actual user clicking on a radio to change it, unless you are suggesting they add a handler to every checkbox to set the attr to what it is, which could be a valid solution too...

Of course, if someone uses $(":text").attr("value", "abc"); that would also change the serialized state of the element. I think that $(":text").val("abc"); should only set the dynamic state (value property) and leave the value attribute unmolested.

Changed March 14, 2011 03:12PM UTC by rwaldron comment:8

component: unfiledattributes
owner: → gnarf
priority: undecidedlow
status: newassigned

Changed April 15, 2011 03:46AM UTC by timmywil comment:9

The test case seems to work fine now: http://jsfiddle.net/timmywil/eGgvw/21/

Changed April 15, 2011 04:42AM UTC by timmywil comment:10

#8060 is a duplicate of this ticket.

Changed April 15, 2011 04:44AM UTC by timmywil comment:11

component: attributesmanipulation
version: 1.5.11.5.2

I didn't see the real problem before. This is a manip bug (IE6/7 can't handle keeping checked on appendChild).

Gnarf's duck punch above works to fix #8060. Patch incoming. http://jsfiddle.net/timmywil/MwtCW/8/

Changed April 15, 2011 05:39AM UTC by gnarf comment:12

_comment0: https://github.com/jquery/jquery/pull/3281303024312773297

Changed April 17, 2011 01:39AM UTC by timmywil comment:13

resolution: → duplicate
status: assignedclosed

Changed April 17, 2011 01:39AM UTC by timmywil comment:14

Duplicate of #8060.

Changed April 22, 2011 01:56AM UTC by timmywil comment:15

resolution: duplicatefixed

Landing pull request 332. Appending disconnected radio or checkbox inputs and keeping checked setting Fixes #8060, #8500.

More Details:

Changeset: d274b7b9f7727e8bccd6906d954e4dc790404d23

Changed April 22, 2011 01:57AM UTC by john comment:16

milestone: 1.next1.6

Changed May 31, 2011 05:51PM UTC by timmywil comment:17

#9470 is a duplicate of this ticket.