jQuery UI button tweaks

I recently completed a project which included a complicated web application. jQuery UI looked really nice, so I went with it. I don’t regret that decision, but one thing was especially annoying: the buttons are unpolished to the point of being almost broken. They just don’t behave at all like desktop GUI buttons. I guess I could post this stuff over at jQuery UI, but I feel like these are all things you would notice within five minutes of playing around with the buttons, so they must have been deliberate design decisions (although I can’t fathom why). I used jQuery 1.6.2 and jQuery UI 1.8.14, so perhaps one or more of the issues are already fixed.

1. Firefox F5 refresh bug

Firefox has a bug which can cause jQueryUI buttons to sometimes retain their disabled state through a page refresh. This can happen on a normal refresh (hitting F5) but a complete refresh (hitting Ctrl-R) always completely resets the state. To fix it I added a line to the top of a $(function){}) block that is the first thing to execute on page load:

$("button").removeAttr('disabled').button();

2. Normal buttons

Themes define several colors for buttons, which are used for normal, mouseover, and mousedown states. But when you click a button, sometimes the button remembers the mouseover state even after you mouse away–so normal buttons (not checkboxes) seem to behave like checkboxes. My fix is to call an additional function from every button’s onclick event:

function resetButton(obj)
{
   $(obj).removeClass("ui-state-focus ui-state-hover");
}

...

$("#a_button").button();

...

<button id="a_button" onclick="resetButton(this); doSomething();">Click Me</button>

3. Checkboxes

Checkboxes can get into a funky state where the button highlight is opposite what you would expect given the “checked” status of the input. It’s easy to reproduce: just double-click the checkbox. They also suffer from the mouseover issues that normal buttons have:

function resetCheckBox(obj)
{
   if($("#" + $(obj).attr("for")).attr("checked") == "checked")
   {
      $(obj).addClass("ui-state-active");
   }
   else
   {
      $(obj).removeClass("ui-state-active");
   }
   resetButton(obj);
}

...

<input type="checkbox" id="checkbox1" onclick="doSomething();"/>
<label id="checkbox1_label" for="checkbox1" ondblclick="resetCheckBox(this);"></label>

4. Radio buttons

Radios are even buggier. I can’t remember all the debugging steps it took me to arrive at this function; as you can see, I’m reimplementing every part of the radio functionality. It makes me think I must have been doing something wrong, to need to do all this.

function resetRadio(obj)
{
   resetButton(obj); //remove hover classes
   $(obj).parent().children('label').removeClass('ui-state-active');
   $(obj).addClass('ui-state-active');
   $(obj).parent().children("input").removeAttr("checked");
   $("#" + $(obj).attr("for")).attr("checked", "checked");
}

...

<form>
   <div id="radio1">
      <input type="radio" name="radio1" id="radio1_opt1" checked="true" />
      <label for="radio1_opt1" onclick="resetRadio(this); doSomething();">Option 1</label>
      <input type="radio" name="radio1" id="radio1_opt2"/>
      <label for="radio1_opt2" onclick="resetRadio(this); doSomething();">Option 2</label>
   </div>
</form>

In sum, jQuery UI buttons: kinda buggy.

This entry was posted in hacks. Bookmark the permalink.

One Response to jQuery UI button tweaks

  1. Patrick Walsh says:

    Great post! We’re now at jQuery UI 1.10.4 and all of these issues are still present. Googling the F5 issue brought me here. Thanks for all the great workarounds. I’m still debating whether or not I should even push forward with the UI buttons. So buggy!

Leave a Reply

Your email address will not be published.