Bug Tracker

Opened 12 years ago

Closed 12 years ago

Last modified 9 years ago

#9166 closed bug (duplicate)

Prop not setting property if it had previously been removed, and Chrome inconsistency

Reported by: jamietre Owned by:
Priority: low Milestone: 1.next
Component: attributes Version: 1.6
Keywords: Cc:
Blocked by: Blocking:



After this script runs the test field is not actually disabled (following setting "disabled" property to "true", then "false", then "true" again.) Yet the reported values in the log indicate that jQuery thinks the property is there. Inspecting the HTML shows that it does not exist in the DOM. This behavior is consistent across all browsers.

Additionally, the results returned by testing "prop" value are incorrect in Chrome.

Initially, Chrome correctly reports "false" for prop on a missing property. However, after adding then removing "disabled" Chrome reports "undefined" whereas IE and FF correctly report "false".

Change History (9)

comment:1 Changed 12 years ago by Rick Waldron

Component: unfiledattributes
Priority: undecidedlow
Resolution: duplicate
Status: newclosed

comment:2 Changed 12 years ago by Rick Waldron

Duplicate of #9140.

comment:3 Changed 12 years ago by timmywil

docs updated to make it clear that .removeProp() should not be used on native properties.

comment:4 Changed 12 years ago by jamietre

Shouldn't methods behave consistently across browsers even if doing things that one "shouldn't" do with them? I would think that if one shouldn't do this then jQuery should either not let you do it, or act as if you used 'prop("native",false)'.

comment:5 Changed 12 years ago by timmywil

.removeProp() was only added so that you can remove user-defined properties that were added with .prop(). However, you'll generally want to use .data() instead anyway. It is a simple, powerful, and dangerous function, but I think we just need clear documentation or we'll be playing the guessing game too much on what the user wants.

comment:6 Changed 12 years ago by jamietre

OK - I was only using it because behavior is inconsistent when using "attr" to set/unset "disabled" per your previous comment (basically was following the example from your original jsfiddle).

There are so many different ways one could try to do this:

attr("disabled",true); attr("disabled","disabled"); attr("disabled",false); attr("disabled,""); removeAttr("disabled"); prop("disabled",true); prop("disabled",false); removeProp("disabled)");

At this point it appears that the only "right" way to do it is

prop("disabled",true); prop("disabled",false):

This is a pretty confusing array of options with many wrong answers (but not just wrong answers - answer that *appear* to work because they do in some browsers) for a very simple need. Given that if you google "how I set something disabled with jQuery" you get every answer EXCEPT prop (which has only been around since 1.6.0), this is going to trip people up for a long time to come.

Maybe it's time for disable() and enable() to become native functions :)

comment:7 Changed 12 years ago by timmywil

Yea, we agree it's confusing. disable and enable might be good ideas for 1.7. However, we are reverting attr in 1.6.1 to work the way it used to for boolean attributes to reduce the confusion. You should still use prop for changing these values as that is what attr will be doing internally in 1.6.1.

I don't want to go changing removeProp when it was just introduced though. The documentation for it makes the dangers clear now.

Last edited 12 years ago by timmywil (previous) (diff)

comment:8 Changed 12 years ago by jamietre

Thanks for the discussion. I'll proceed with prop("disabled",true|false) and am glad to have a deeper understanding of the issue.

comment:9 Changed 9 years ago by anonymous

This bug still exist I'm using version 1.7.1 and the following code doesn't change the HTML DOM but only visually !

var checkboxes = $('input[type="checkbox"]');
var state = $(checkboxes).first().is(':checked');				
	checkboxes.each(function() {
		$(this).prop('checked', !state);		

I've fixed this code by adding this line just below .prop() call:

$(this).attr('checked', $(this).is(':checked'));

.attr() changes the DOM.

Note: See TracTickets for help on using tickets.