Playing with form validation in Spry
As much as I love working with Spry, I haven't spent a lot of time playing with the widgets or effects. Outside of the tabs - I just wasn't that interested. During my Spry presentation to the OC CFUG this week, I decided it was time to take a look at the form validation widgets that ship with Spry. This morning I looked specifically at the checkbox widget.
Widgets in Spry all follow a basic setup - whether you are using UI-ish widgets like tabs, or validation widgets like the checkbox. You begin with your content, and then "enable" the widget with a line of JavaScript. This works due to the loading of a JavaScript library and a CSS file as well.
Let's take a look at a simple example. The following is a very basic HTML form:
<form>
<b>Please select your favorite monsters</b>:<br />
<input type="checkbox" name="monsters" value="blast-ended skrewt">Blast-Ended Skrewt<br />
<input type="checkbox" name="monsters" value="augurey">Augurey<br />
<input type="checkbox" name="monsters" value="ashwinder">Ashwinder<br />
<input type="checkbox" name="monsters" value="acromantula">Acromantula<br />
<input type="checkbox" name="monsters" value="doxy">Doxy<br />
<input type="checkbox" name="monsters" value="nogtail">Nogtail<br />
<input type="submit">
</form>
The form has one set of six checkboxes. Now let's enable basic validation using Spry. The first thing I need to do is load the resources Spry needs:
<script src="/spryjs/SpryValidationCheckbox.js" type="text/javascript"></script>
<link href="/sprycss/SpryValidationCheckbox.css" rel="stylesheet" type="text/css" />
Now I need to help Spry know what checkboxes are going to be validated. To do that - I'm going to wrap the checkboxes in a span:
<span id="mycheckboxes">
<input type="checkbox" name="monsters" value="blast-ended skrewt">Blast-Ended Skrewt<br />
<input type="checkbox" name="monsters" value="augurey">Augurey<br />
<input type="checkbox" name="monsters" value="ashwinder">Ashwinder<br />
<input type="checkbox" name="monsters" value="acromantula">Acromantula<br />
<input type="checkbox" name="monsters" value="doxy">Doxy<br />
<input type="checkbox" name="monsters" value="nogtail">Nogtail<br />
</span>
Then I simply enable the validation with a line of JavaScript:
<script type="text/javascript">
var sprycb = new Spry.Widget.ValidationCheckbox("mycheckboxes");
</script>
So we aren't quite done yet. How do we handle errors? Typically you use a message of some sort. What I need to do is create a message inside a specifically named CSS class. Here is an example:
<span class="checkboxRequiredMsg">Please make a selection.<br /></span>
The class I used above is recognized by Spry. So when loaded - the message is automatically hidden. And that's it. When I try to submit the form now, Spry will check my checkboxes, and if one isn't selected, it will take that previously hidden message and reveal it. Here is the complete source of the new version:
<html>
<head>
<script src="/spryjs/SpryValidationCheckbox.js" type="text/javascript"></script>
<link href="/sprycss/SpryValidationCheckbox.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form>
<b>Please select your favorite monsters</b>:<br />
<span id="mycheckboxes">
<input type="checkbox" name="monsters" value="blast-ended skrewt">Blast-Ended Skrewt<br />
<input type="checkbox" name="monsters" value="augurey">Augurey<br />
<input type="checkbox" name="monsters" value="ashwinder">Ashwinder<br />
<input type="checkbox" name="monsters" value="acromantula">Acromantula<br />
<input type="checkbox" name="monsters" value="doxy">Doxy<br />
<input type="checkbox" name="monsters" value="nogtail">Nogtail<br />
<span class="checkboxRequiredMsg">Please make a selection.<br /></span>
</span>
<input type="submit">
</form>
<script type="text/javascript">
var sprycb = new Spry.Widget.ValidationCheckbox("mycheckboxes");
</script>
</body>
</html>
And you can test this here. In case you are curious - yes - you can modify the look and feel of the error. You can also modify when the validation occurs. By default it is on submit, but you can also run it on blur or change. Check the docs for more information.
While this is nice and all - so far it isn't too terribly exciting. But the checkbox validation also has another cool feature. You can specify a minimum and maximum number of required checkboxes. All you need to do is specify the option when enabling the validation:
<script type="text/javascript">
var sprycb = new Spry.Widget.ValidationCheckbox("mycheckboxes",{minSelections:2});
</script>
This example specifies that a minimum of two checkboxes must be selected. As I said above, I can also do a maximum as well. In order to handle this validation, you need to add a new error message. Once again there is a specially named CSS class you can use:
<span class="checkboxMinSelectionsMsg">Please pick at least two selections.<br /></span>
Here is a complete example:
<html>
<head>
<script src="/spryjs/SpryValidationCheckbox.js" type="text/javascript"></script>
<link href="/sprycss/SpryValidationCheckbox.css" rel="stylesheet" type="text/css" />
</head>
<body>
<form>
<b>Please select your favorite monsters (pick 2 minimum)</b>:<br />
<span id="mycheckboxes">
<input type="checkbox" name="monsters" value="blast-ended skrewt">Blast-Ended Skrewt<br />
<input type="checkbox" name="monsters" value="augurey">Augurey<br />
<input type="checkbox" name="monsters" value="ashwinder">Ashwinder<br />
<input type="checkbox" name="monsters" value="acromantula">Acromantula<br />
<input type="checkbox" name="monsters" value="doxy">Doxy<br />
<input type="checkbox" name="monsters" value="nogtail">Nogtail<br />
<span class="checkboxRequiredMsg">Please make a selection.<br /></span>
<span class="checkboxMinSelectionsMsg">Please pick at least two selections.<br /></span>
</span>
<input type="submit">
</form>
<script type="text/javascript">
var sprycb = new Spry.Widget.ValidationCheckbox("mycheckboxes",{minSelections:2});
</script>
</body>
</html>
And the online demo may be found here.
So now that I've finally played with it a bit - I like it. Especially the min/max support.
Comments
http://cfspryforms.riaforge.org/
I agree that it can be a pain. However, I think it is becoming increasingly necessary.
For example, I personally give sites very few chances with user interfaces. If I have to correct errors AFTER filling out forms AND submitting them, I lose patience very quickly and am less likely to bother continuing with it.
In the past, people may have been accustomed to this kind of "go-back-and-correct-the-errors" kind of workflow, but with the incredible proliferation of AJAX across the web, newer users are probably endowed with a significantly smaller toleration for such processes, expecting live notifications of potential problems.
This is one of the reasons I love Spry so much. Whether one is looking for pure client-side validation, or a fusion of the two like you have suggested (and which I use for the very example you cited), Spry makes the addition of this second "layer" very intuitive and coding-time-friendly. It is so easy to implement that one can still concentrate on the still extremely important server-side validations without consuming a lot of precious coding time on wrangling with Javascript.
So now we have to go change the code on the client side and then go change the validation on the server side, if we remember. The problem then(when we forget) is that your client side validation checks to see that 2 fields are required and your serverside says that 3 are required, and now your validation doesn't match.
One could argue that testing could and should catch that, but we all know how much people love to test.
In reality I love client side validation, I just want the logic for it on the server.


Obviously, server-side checking is still necessary; however, it is nice to be able to provide a more user-friendly and alert-as-you-go experience for those who aren't trying to break things just for the heck of it. Spry enables the addition of an entire second layer and requires very little time above and beyond what one should already be doing.
Very cool stuff!