1

I'm using this piece of jQuery to add radio button behavior to checkboxes, i.e. allowing only one from each group to be checked.

$("input:checkbox").click(function()
{
    $("input:checkbox:checked[name='" + this.name + "']")
        .not(this).removeAttr("checked");
});

It works great, or at least I thought so until I discovered that in Opera I can still check multiple checkboxes from the same group if I'm insistent. By rapidly toggling between some checkboxes (clicking like a maniac) I eventually end up with two (or more) checked.

Normally thinking of JavaScript as single-threaded I was kind of surprised by this. However, I know JavaScript is not always as single-threaded as it seems (see this answer) and I assume that's somehow causing this behavior. How can it otherwise happen?

If my assumption is right, can anyone explain what happens? In the answer I link to you can read:

Similarly calling click() on an element that provides it calls the onclick handler immediately in all browsers (at least this is consistent!).

That seems relevant, except that this only happens with Opera (I've tried with IE(8), FF, Chrome and Safari).

Any input is much appreciated!

Community
  • 1
  • 1
lindsten
  • 88
  • 1
  • 6
  • 5
    why not use radio buttons, why ruin a checkbox and make it a radio, when you can just use radio? – Naftali May 03 '11 at 14:12
  • I'm fairly new to javascript development, but couldn't this be one of those "closure issues"? What happens if you try (...).click((function() { return new function() { $("input:checkbox:checked[name='" + this.name + "']").not(this).removeAttr("checked"); } })()); – diogoriba May 03 '11 at 14:50
  • @Neal: I expected that question and I know it sounds like a bad thing, but I've got my reasons. Besides, *why* is really irrelevant. – lindsten May 04 '11 at 09:15

1 Answers1

1

If you click really fast here, http://jsfiddle.net/RxbW6/1/

You will see that when 2 checkboxes end up being checked at the same time (by spamming them) the click event does not fire for the second checkbox. So it's not a threading issue with the 2 click events interfering, rather opera does not seem to be firing the onclick event at all.

I would recommend just using a radio group instead and styling it, this case is what it is here for.

However,

$("input:checkbox").mouseup(function()
{
    $("input:checkbox:checked[name='" + this.name + "']")
        .not(this).removeAttr("checked");
});

Will fix your issue. [Edit] mouseup will probably be better so you can mousedown and then move off and keep the previous check.

Andrew
  • 13,757
  • 13
  • 66
  • 84
  • Interesting, so Opera checks the checkbox but doesn't fire the onclick event.. that must be a bug in Opera, wouldn't you say? Btw, with *click* I can still mousedown and move off without loosing the current check. – lindsten May 04 '11 at 09:24
  • I did some more testing and I noticed that if I mousedown on a checkbox, move off it and then back on and finally mouseup, Opera fires neither the click nor the change event (despite the checked state being toggled). Try it [here](http://jsfiddle.net/bLB5j/). The other browsers (IE, FF, Chrome & Safari) seem to be consistent and always fire both click and change whenever the checked state is changed. Can this be what happens when I spam the checkboxes with clicks? – lindsten May 04 '11 at 10:11
  • @lindsten I think that is probably what is happening, you should file a bug report with opera. I won't speculate as to what exactly is going wrong, but the two definitely seem related. – Andrew May 04 '11 at 14:52