The need arose at my client recently to add a checkbox to an existing JSP. The checkbox had to be defaulted to checked. Actually I had asked whether the checkbox should be defaulted to checked. This was a proud moment for me. It is not often that I have been codesented with such an easy request, with good requirements around it. A checkbox is a single line of HTML code:

input type="checkbox" name="vehicle" value="Bike" />

and to default the box to checked it can look something like this:

input type="checkbox" name="vehicle" value="true" checked="true"/>

This creates the checkbox and the attributes give it a name for reference elsewhere in the code and tell it what value to pass when checked. So easy!

Well as it turns out we use a lot of Spring "stuff" at the client; the Webflow framework and the general Spring framework. The Spring framework includes some nice JSP tag libraries that allow all kinds of extra attributes, but the bonus is your model can be a boolean field and by setting it as a boolean you don't even need to add the value attribute to the Spring checkbox, it will either be true or false. So as you can see there is this level of abstraction and features that really make it seem attractive.

So while an HTML checkbox certainly has it's place when it comes to simplicity, the Spring checkbox is where we can "kick it up a notch". Below is one way how you would setup a checkbox Spring style (Disclaimer: the example below has been simplified to protect the innocent).

MyModel.java :

private boolean checkbox = Boolean.TRUE; //default to checked
 
public boolean ischeckbox() {
 return disableNotification;
}
 
public void setcheckbox(boolean checkbox) {
 this.checkbox = checkbox;
}

MyJSP.jsp:

form:form id="myAction" modelAttribute="MyModel" action="${submit}" method="post">
 form:label path="checkbox" for="checkbox1" cssClass="inline">Please check my boxform:label>
 form:checkbox path="checkbox" id="myCheckbox"/>
form>

The TLD for the "form" tag is here

The model is straight forward. We have a primative boolean variable with getters and setters. The JSP has one extra line that allows us to put text to describe the checkbox but anyone that has glanced at HTML before should be able to understand what's going on here. Instead of the html "input" tag we are using the Spring "form" tag and specifying a checkbox with . The path attribute on checkbox binds the checkbox to the boolean variable in the model. The model is defined in the parent node as modelAttribute.

So it appears we have certainly done a lot more coding for a Spring checkbox but we almost have a nice MVC model (Controller not shown for simplicity) and we can do all kinds of fancy things that is just not in the scope for this blog post.

We can do everything it seems except, wait, where is the option to default the checkbox to checked? Ah HA! Perhaps it's built in when we set the boolean(primative) value to true in the model? Nope. There is no attribute supported by the TLD to say checked="true". Even defaulting the boolean(primative) to true does nothing but default the variable to true.

You can add a "value" attribute and set it that way!? Nope, that is simply telling the code what the value will be WHEN you check the box. Setting the value attribute to "true" does help reinforce the boolean(primative) aspect of the checkbox in Spring but you're not going to see if checked.

Maybe if we do a before the that will do some kind of MVC magic and the box will be checked? Nope, that is basically the same as saying "private boolean checkbox = Boolean.TRUE". (Style note: some people codefer not to use Boolean.TRUE but just true. Really just a personal codeference as boolean isn't going to change anytime soon; but it may!).

Maybe if you employ some masterful EL into the tag, something like value="${myModel.checkbox}", but again value is what is going to be set when the box is checked, not default it in the JSP to being shown as checked.

In my Google quest I've even seen suggestions that involve overriding the parent classes base instantiation to forceably and explicity set that boolean value to true so it shows checked. Still not quite sure how that even works but there is enough witch-doctory in that "solution" to ward me anyway from it.

Having exhusted other opinions we are left with either ditch the entire "checkbox"> and go with an ExtJs checkbox, or jquery/javascript. In regards to time and my experience with ExtJs I decided not to go that route, but that would have been simple enough. Instead I went with the even simplier route; jQuery, the write less, do more javascript library of your dreams!

Here is the script:

$(document).ready(function() {
 $('#myCheckbox').attr('checked', true);
});

What does it look like the code is doing here? It's creating an attribute called checked that equals true! Look familiar? Yeah it's the same as the HTML version: checked="true". When it comes down to it our Spring abstraction eventually becomes HTML and the script steps in to place the attribute in there to default to checked. My friends we have just hacked the Spring framework in order to default a checkbox to being checked.

This apparently final solution is not too terrible but we really should have trusted Spring a little more or at least realized an option to default the checkbox to checked would have been a no brainer to add and therefore looked a little harder in the Spring documentation to ensure we didn't miss anything. Because......

This link points us to the answer we have been searching for. Under the heading of "13.9.4. The checkbox tag", among the first example, rather than just being stated as one might codefer for a reference resource is a rather unassuming line that states: "When the bound value is of type java.lang.Boolean, the input(checkbox) is marked as 'checked'....."

Look closely and you will see Boolean instead of boolean. That's right, it has to be a Boolean wrapper class in order to make use of the toString() method that Spring uses to bind values. So simply changing the primitive boolean variable in your model to a Boolean wrapper and setting it to TRUE you have defaulted the checkbox to checked.

This underscores the importance of spending time to read the manual before doing the requiste Google/co-worker search for knowledge and is just plain common sense. Granted reading the manual may have taken the same amount of time but the stress and misdirection makes for a much unhappier developer and reading the manual gives you more knowledge than just what pertains to your current problem saving time down the road.