Thursday, June 28, 2012

Checkboxes and radiobuttons

Tired of native checkboxes and radiobuttons which look different in browsers and have inconsistent appearance?
If you don't know a way to change the look and feel of native checkboxes and radiobuttons with pure css (I don't know too except tricks with javascript or crazy css hacks like this) I'll show you how to get radiobuttons and checkboxes like on the image below.

When I was implementing a skin for our project I have asked our designer to make images of these components and got this nice sketch.

I've never done css skinning of these components before and thought it's a trifling matter. But it turned out that a browser is not engaged in rendering of these controls but operating system in case of windows or graphical toolkit in linux (in case if browser is Firefox, IE or WebKit based Konqueror. Chrome renders them itself, but there are no even non-standard properties to use them to change the appearance). So I've started to investigate a ways to achieve the task. I've found out three ways to do this: to use third party libraries like openfaces, to write my own custom component (I've even started to do this, created tag library, part of server-side renderer and stopped doing this when was writing javascript peers), to use css hacks or tricks with substitution of dom inputs by custom images. And one day I've have remember that commandToolbarButton has property "type" (button, check and radio). I've applied some css changes to button and got what I was looking for. If it looks like a duck, swims like a duck, and quacks like a duck, then it probably is a duck.

Get down to business. Create an application with one project with a sctructure like on the image below.

Set the code of trinidad-skins.xml to this:


and trinidad-config.xml:

In the components.css add this lines:

That's it. Now we can test our buttons. Add commandToolbarButtons to the fragment, assign them styleClasses "check" and "radio" and run the application.


There two issues with the components: a disabled component cannot be checked (selected) and in IE the pseudo class "active" is ignored. First problem can be solved by adding a custom styleClass with correct background. The second by ignoring the IE. =)
Getting and setting values of the attribute bindings or bean properties some differs of the usual way. But it is not difficult. There are two ways to do this:
  • write ActionListener for components (it's practical in case of using radiobuttons to use one ActionListener);
  • use af:setActionProperty component with (from="new value" and to="attr binding or bean property" in case of radiobutton, or from="!(new value)" and to="attr binding or bean property" for checkbox);
Here is example code of  page with these two described methods (I did not implemented this for checkbox because it's too trivial, but if you want me to show you a working example then write a comment):


and Managed Bean code:

Don't forget to declare it in the taskflow.
You can download application here. Enjoy with the new skinned buttons. =)

1 comment: