views:

358

answers:

3

If I have a set of radio buttons, all styled with jQuery UI's .button().

I want to change their checked state, but when I do so programatically on the container's change event with

$("#myradio [value=1]").attr("checked", false);
$("#myradio [value=2]").attr("checked", true);

The values are changed correctly, but the UI styling still shows the unchecked radio button with the checked style and the checked one still looks unchecked.

I looked through the jQuery UI documentation on the button() method for radio buttons, but there is nothing about how to change the state and update the UI styling.

Any ideas? I feel like I am missing something here.

Edit:

The nutshell of the problem is that calling the "$("selector").button("disable");" code does not change the button's active state - the underlying radio button is correctly checked, but the UI active state does not change, so I get a greyed out button that looks like it's still checked, and the real selected button appears unchecked.

Solution

$("selector").button("enable").button("refresh");
A: 

The below is all very interesting, but A) jQuery handles it, and B) It didn't solve the OP's problem. :-) So I posted another answer that I think actually addresses the problem. I'm leaving this in case someone finds the information useful.


If you use the attribute, basically having the attribute there at all means checked (usually you use the value "checked", e.g., .attr("checked", "checked")), and removing the attribute entirely (.removeAttr("checked")) means unchecked. This is a DOM/HTML thing, not a jQuery thing. However, see Tgr's note below and my tests confirming it, jQuery itself apparently handles this for you.

FWIW, it may be easier to use the reflected DOM property checked rather than the attribute:

$("#myradio [value=1]")[0].checked = false;
$("#myradio [value=2]")[0].checked = true;

(The above assumes exactly one match for the jQuery selector. Adjust if there's the possibility of zero matches, or more than one match.)

Worth a shot, anyway, in case that resolves the problem.

T.J. Crowder
Calling `attr` with false should remove the attribute (and it does in vanilla jQuery 1.4 so maybe this is some side effect of jQuery UI).
Tgr
@Tgr: Thanks, good to know. No offense, but I verified it: http://jsbin.com/usujo3 And it even seems to work back with jQuery 1.3.2: http://jsbin.com/usujo3/2 Tested on Chrome for Linux, IE8, and IE6. Works a treat, you're right.
T.J. Crowder
Changes the underlying radio button's state, but still not the UI styling...
Antony Carthy
+1  A: 

Looking at the code, you need to toggle the ui-state-active class, but the simplest way is probably just $('someradiobutton').trigger('click') (or if you don't want your custom event handlers to run, $('someradiobutton').trigger('click.button')).

Tgr
Changes the underlying radio button's state, but still not the UI styling...
Antony Carthy
+1  A: 

You need to call the refresh method after changing the underlying state:

Refreshes the visual state of the button. Useful for updating button state after the native element's checked or disabled state is changed programatically.

Working example: http://jsbin.com/udowo3

function setRadio(id) {
    var radio = $('#' + id);
    radio[0].checked = true;
    radio.button("refresh");
}

That uses IDs for the radios, but it doesn't matter as long as you get a jQuery instance containing the relevant input[type=radio] element.

T.J. Crowder
Worked - thank you! Why do I need to do this? Is this a bug or bad behaviour in jQuery UI?
Antony Carthy
@Antony: Well, there's no reliable, cross-browser event thrown when the state of the `checked` or `disabled` properties is changed. What surprises me is that they're not using CSS to have the browser handle the change automatically, but I expect they have a reason (IE6 support, perhaps -- IE6 doesn't do state selectors on anything but links). The other surprise was that they don't provide a method that you can use to change the `checked` state and update the UI all at once. Still, easy enough once you know. :-)
T.J. Crowder
Precisely! thank you T.J.
Antony Carthy