Bug Tracker

Modify

Ticket #3827 (closed bug: fixed)

Opened 5 years ago

Last modified 16 months ago

Checkbox state inconsistent in click event handler

Reported by: skorpan Owned by: dmethvin
Priority: high Milestone: 1.9
Component: event Version: 1.2.6
Keywords: 1.9-discuss Cc:
Blocking: Blocked by:

Description

I'm not sure whether this is intended behavior or simply impossible to hack in pure JavaScript, but here goes nothing...

There is a significant difference between actually clicking an element and the triggering of the click event handlers bound to that element by JQuery. Attached to this ticket is a test script and its HTML to reproduce this "bug". What happens is:

  1. I click the checkbox and see "State: ON" in the Firebug console. I click it a few times to verify that the correct state is always reported.
  1. I click the button which in turn programmatically triggers the click event bound to the checkbox. Now the INCORRECT state is reported every time. This is probably due to the bound event handler being triggered before any internal behavior.

Attachments

test.html Download (537 bytes) - added by skorpan 5 years ago.
test.js Download (224 bytes) - added by skorpan 5 years ago.
test-3827.html Download (1.6 KB) - added by dmethvin 5 years ago.
event handling with jQuery trigger() and DOM events

Change History

Changed 5 years ago by skorpan

Changed 5 years ago by skorpan

comment:1 Changed 5 years ago by dmethvin

Can you explain what behavior you expected? Does it differ from raw Javascript behavior in some undesirable way? In general, all the handlers have to run before the browser's default action is taken. That's because the event handler can return false or e.preventDefault() to stop the default action.

comment:2 Changed 5 years ago by dmethvin

I did some further work on this, and I agree with your analysis. Test case attached, checked in FF3 and IE8B2. The difference is because .trigger("click") calls the handler before the checkbox native click() method. A click on the checkbox calls the checkbox native click() method; that method causes the onclick event to fire and jQuery calls the handler.

See this thread for more discussion:

 http://groups.google.com/group/jquery-dev/browse_frm/thread/39c3dabc8ac3569a

Changed 5 years ago by dmethvin

event handling with jQuery trigger() and DOM events

comment:3 Changed 5 years ago by brandon

  • Owner brandon deleted

comment:4 Changed 4 years ago by dmethvin

Closed duplicate #5727 with another test case.

More info:

 http://www.w3.org/TR/DOM-Level-2-HTML/html.html#ID-6043025

Note: During the handling of a click event on an input element with a type attribute that has the value "radio" or "checkbox", some implementations may change the value of this property before the event is being dispatched in the document. If the default action of the event is canceled, the value of the property may be changed back to its original value. This means that the value of this property during the handling of click events is implementation dependent.

It seems like most modern browsers change the checkbox state before calling the event handler, then revert it if the default action is cancelled.

comment:5 Changed 4 years ago by dmethvin

  • Summary changed from Click event triggered "too late" to Checkbox state inconsistent in click event handler

Closed duplicate #6775.

comment:6 Changed 3 years ago by dmethvin

  • Status changed from new to closed
  • Resolution set to wontfix

This behavior has been consistent since jQuery's first version, so there's no way we could change it without breaking significant existing code.

comment:7 Changed 3 years ago by dmethvin

#5951 is a duplicate of this ticket.

comment:8 Changed 3 years ago by David Sanders

If you compare jQuery's behaviour with raw JavaScript the results are opposite.

The best policy here is to fix this in the next major version of jQuery and tell people there's a BC break otherwise everyone will have to put up with annoying workarounds until the end of time.

comment:9 Changed 3 years ago by anonymous

Hey,

I was having the same issue, and found a great answer on Stack Overflow here:  http://stackoverflow.com/questions/3478267/jquery-strange-behaviour-on-click-from-a-click

Basically, instead of just calling the click() method of the checkbox, you set the attribute "checked" to true or false, which checks or unchecks the box, and then manually call the event handler by using triggerHandler("click"). Here's the code that I used:

Check the box: $(this).find("input.city_selector_chk").attr('checked', 'true'); $(this).find("input.city_selector_chk").triggerHandler("click");

Uncheck the box: $(this).find("input.city_selector_chk").attr('checked', ); $(this).find("input.city_selector_chk").triggerHandler("click");

Hope this helps! Paul

comment:10 Changed 3 years ago by jitter

#8374 is a duplicate of this ticket.

comment:11 Changed 3 years ago by dmethvin

#8636 is a duplicate of this ticket.

comment:12 Changed 3 years ago by anonymous

I don't understand why this is a won't fix. Manual triggering of event is basically broken with this bug!

comment:13 Changed 3 years ago by euan.ritchie@…

Having recently discovered this issue I note that there is different behaviour between different versions of jQuery;

Given a input:checkbox that has both an inline onclick handler and a jQuery bound click handler the value of checked differs according both to how the click is triggered and what version of jQuery is in use.

Actually clicking on the element in the browser changes the checked value before the events are handled.

With jQuery 1.6.2 using $(element).trigger('click') handles the events before the checked value changes.

In jQuery 1.3.2 the behaviour is slightly different as one handler is called before the checked state changes and the other after.

So at least now the behaviour is consistent across handlers and predictable, though I think ought still be fixed. If not in a minor version change then certainly by jQuery 2.0

comment:14 Changed 2 years ago by dmethvin

#10166 is a duplicate of this ticket.

comment:15 Changed 2 years ago by dmethvin

#10005 is a duplicate of this ticket.

comment:16 Changed 2 years ago by dmethvin

#9274 is a duplicate of this ticket.

comment:17 Changed 2 years ago by dmethvin

#8885 is a duplicate of this ticket.

comment:18 Changed 2 years ago by dmethvin

#8796 is a duplicate of this ticket.

comment:19 Changed 2 years ago by dmethvin

#10827 is a duplicate of this ticket.

comment:20 Changed 2 years ago by rwaldron

#11602 is a duplicate of this ticket.

comment:21 Changed 2 years ago by anonymous

As a note to anyone else suffering with this bug, you can work around this problem by wrapping your checkbox's click event handler in setTimeout(function(){ ... }, 1);

comment:22 Changed 22 months ago by dmethvin

#11991 is a duplicate of this ticket.

comment:23 Changed 22 months ago by dmethvin

  • Keywords 1.9-discuss added; click, event, trigger, checkbox, button removed

comment:24 Changed 22 months ago by derek.rosenzweig@…

I too am having issues with this. I dynamically add a new checkbox, and using delegated 'click' handler:

$('div.parent').on('click', 'input[type=checkbox].classname', function() {

if ($(this).is(':checked')) { <--- this shows opposite value when doing $(element).trigger('click');

do stuff

}

});

comment:25 Changed 22 months ago by checat

Just 2 cents.

Ideally jQuery click() and DOM click() should work identically for elements which have DOM click().

comment:26 Changed 22 months ago by coreyog@…

There have been 13 duplicate bugs posted in the past 3 years indicating many people find it should not be the way it is. Several fixes ranging from setTimeout(..., 1) to setting the checked attribute and calling the triggerHandler have been proposed but these are work arounds to account for a bug, i.e. people aren't accepting this as expected behavior. Checat makes a valid point for why expectations supports the idea that this is a bug. The cause of the problem has been pointed out by dmethvin and it honestly sounds like an easy fix.

Fixing this bug in a new release would only impact those who have legacy code referencing a constantly changing 'newest release'. Those developers should know that a constantly updated library will occasionally not only have changes, but fixes, that would impact their projects.

comment:27 Changed 22 months ago by dmethvin

Suggestions for a fix are welcome. Please submit a patch.

comment:28 Changed 20 months ago by dmethvin

  • Priority changed from minor to high
  • Milestone changed from 1.3 to 1.9

Okay, let's try one last time, because this one bothers me too. I think this can be fixed with the 1.7 special event hooks if we assume that click is a DOM event and don't let it flow through the normal jQuery.event.trigger path. This may have negative effects for non-DOM usages however, so it's a question of what breaks when we fix this. See also #12379.

comment:29 Changed 19 months ago by gibson042

+1, let's give it our best shot.

comment:30 Changed 18 months ago by dmethvin

  • Status changed from closed to reopened
  • Resolution wontfix deleted

comment:31 Changed 18 months ago by dmethvin

  • Owner set to dmethvin
  • Status changed from reopened to assigned

comment:32 Changed 17 months ago by Dave Methvin

  • Status changed from assigned to closed
  • Resolution set to fixed

Fix #3827. Get the correct checkbox status for a click handler.

Changeset: 1fb2f92c357b985a5ba18d0938edd27b5f64d8c3

comment:33 Changed 16 months ago by dmethvin

#13194 is a duplicate of this ticket.

Please follow the  bug reporting guidlines and use  jsFiddle when providing test cases and demonstrations instead of pasting the code in the ticket.

View

Add a comment

Modify Ticket

Action
as closed
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.