The Dijit library provides an extremely powerful, flexible set of Dojo-based widgets with which you may easily enhance the look and functionality of your web application. These widgets include drop down / popup menus, dialogs, page layouts, trees, progress bars, and form elements. When looking at these elements, it’s easy to see that Dijit enhances their presentation but this post will focus on enhancing functionality; specifically, enhancing a basic form with usability improvements and validation.
Quick Dijit Implementation Review
The first step in introducing Dijit to any page is including Dojo:
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/dojo.xd.js.uncompressed.js" djConfig="isDebug:true,parseOnLoad:true"></script>
The next step is requesting the Dijit theme stylesheet:
<style type="text/css">
@import "http://ajax.googleapis.com/ajax/libs/dojo/1.5/dojo/resources/dojo.css";
@import dojox/"http://ajax.googleapis.com/ajax/libs/dojo/1.5/dijit/themes/claro/claro.css";
</style>
The last step is adding the theme name as a class for the BODY
element:
<body class="claro">
Enhancing Basic Form Elements
Note: this tutorial will use the declarative method of widget creation. You may create any Dijit widget programatically using dojo.behavior
as described in Dive Into Dijit.
The first step in enhancing our static form is enhancing the form elements themselves. Dijit provides a corresponding widget (sometimes two or three) for the different types of form elements. Using the declarative method of Dijit widget creation and the dojoType
attribute, we’ll quickly widget-ize every piece of our static form:
<form action="process.php" method="get">
<!-- text inputs: dijit.form.TextBox -->
<strong>First Name: </strong>
<input type="text" name="firstName" placeholder="Your Name" id="firstName" dojoType="dijit.form.TextBox" />
<strong>Website: </strong>
<input type="text" name="website" placeholder="Your Website" id="website" dojoType="dijit.form.TextBox" />
<!-- radio buttons: dijit.form.FilteringSelect -->
<strong>Favorite Color: </strong>
<select name="color" id="color" dojoType="dijit.form.FilteringSelect">
<option value="">Select a Color</option>
<option value="Red">Red</option>
<option value="Green">Green</option>
<option value="Blue">Blue</option>
</select>
<!-- radio buttons: dijit.form.CheckBox -->
<strong>Send Emails? </strong>
<input type="checkbox" id="checkbox" checked="checked" dojoType="dijit.form.CheckBox" />
<!-- radio buttons: dijit.form.RadioButton -->
<strong>Email Format: </strong>
<input type="radio" id="radio1" name="format" checked="checked" dojoType="dijit.form.RadioButton" />
<label for="radio1">HTML</label>
<input type="radio" id="radio2" name="format" dojoType="dijit.form.RadioButton" />
<label for="radio2">Text</label>
<!-- submit button: dijit.form.Button -->
<input type="submit" value="Submit Form" label="Submit Form" id="submitButton" dojoType="dijit.form.Button" />
</form>
Boom: our static, boring form elements have been themed and extended with extra functionality. A few notes with regard to widgets we created above:
- The
FilteringSelect
widget duplicates the functionality of a nativeSELECT
element by:- Setting an initial value based on one of its options having a selected attribute.
- Enforcing a fixed set of possible results based upon the values and text of each
OPTION
element. - Providing keyboard accessibility
-
The
FilteringSelect
widget adds the following functionality to the basicSELECT
element:- You may type values into the
FilteringSelect
; autocomplete is employed. - If an invalid value is provided, an error message is provided to the user.
- You get more control over the display when the widget is disabled.
- You may type values into the
- Dojo 1.5 introduces strategies for employing placeholder text within
INPUT
elements to save you time in adding focus/blur events to accomplish the same functionality.
Now that the basic form has been widget-ized and themed, we can add basic validation functionality.
Form Validation with Dojo
As with just about every client-side problem, Dojo’s got a great solution for form validation. Luckily there are only a few key components required for basic form validation.
dijit.form.ValidationTextBox
A precursor to the overall validation of a form is deciding which elements are required. Say we want to require the first
field; the dojoType
of that will will change from dijit.form.TextBox
to dijit.form.ValidationTextBox
:
<input dojoType="dijit.form.ValidationTextBox" required="true" placeholder="Your Name" missingMessage="Ooops! You forgot your first name!" name="firstName" id="firstName" type="text" />
Since required="true"
has been added to the widget, an error icon and tooltip (with error message) will display if the user fails to place text into the box. A custom error message can be placed within the missingMessage
attribute, otherwise a generic message will display.
What if the field requires special validation of the pattern of input? That’s where the regExp
attribute comes in:
<input dojoType="dijit.form.ValidationTextBox" required="true" regExp="(https?|ftp)://[A-Za-z0-9-_]+\.[A-Za-z0-9-_%&\?\/\.=]+" name="website" placeholder="Your Website" id="website" type="text" />
Not only is the website
field now required but the value of the field must pass the regular expression test provided by the regExp
attribute.
Validation Utilities with dojox.validate
The dojox.validate
library includes numerous utility functions and regular expressions for validating form element values. These utility functions can validate email addresses, URLs, phone numbers, zip codes, and much more. An example usage of dojox.validate
with a ValidationTextBox
would look like:
<script type="text/javascript">
dojo.require("dojox.validate");
dojo.require("dojox.validate.web");
</script>
<strong>Email:</strong>
<input type="text" required="true" name="email" id="email" dojoType="dijit.form.ValidationTextBox" validator="dojox.validate.isEmailAddress" />
The validator
attribute is a link to the validation function for emails. dojox.validate
is especially helpful if you don’t feel comfortable with regular expressions. There are also locale-specific packages within dojox.validate
. The API docs provide a complete listing of dojox.validate
helpers.
dijit.form.Form with the onSubmit Event
Now that our required fields are in place, we’ll enhance the wrapping form
element with a dijit.form.Form dojoType
:
<form dojoType="dijit.form.Form" action="process.php" method="get">
<script type="dojo/method" event="onSubmit">
<!--
if (this.validate()) {
alert('Form is valid, submitting!');
} else {
alert('Form contains invalid. Please complete all required fields.');
return false;
}
return true;
-->
</script>
<!-- form fields here -->
</form>
Accompanying the dijit.form.Form
is a special script
element. Within this Dojo-specific script is a this.validate()
test, acting on the dijit.form.Form
instance, which validates the entire form based on require="true"
inputs. You could also add your own custom validation within the code block as well.
The dijit.form Collection
I’ve only touched the most-used Dijit widgets within my example above. There are several more outstanding form widgets within Dijit; let’s take a look at a few other helpful widgets!
DateTextBox
Asking the user to format a date properly can be a nightmare, especially if other form fields within the page rely on the contents of a given date field. Dijit provides a dijit.form.DateTextBox
class which displays a user-friendly calendar widget for users to select a date on.
<!-- when the user focuses on this element, the calendar appears -->
<input dojoType="dijit.form.DateTextBox" required="true" invalidMessage="Please provide a valid date." type="text" name="date" id="date" />
CurrencyTextBox
The dijit.form.CurrencyTextBox
class helps the user to properly format and validate currency per a given locale.
<!-- {fractional:true} means you must provide cents -->
<input dojoType="dijit.form.CurrencyTextBox" required="true" constraints="{fractional:true}" currency="USD" invalidMessage="Please provide both dollars and cents." type="text" name="weekly_wages" id="weekly_wages" value="2000" />
Textarea
The dojox.form.Textarea
class enhances a given TEXTAREA
element so that the element grows in height as the user types.
<textarea dojoType="dijit.form.Textarea" name="comments"></textarea>
Enhancing Basic Dijit Widgets with DojoX Alternatives
As nice as many of the Dijit widgets are, DojoX hosts numerous enhanced widgets that solve problems that many basic widgets cannot. The following are a few notable DojoX form widgets.
BusyButton
dijit.form.Button
works great but what if I want to disable the button (to avoid double submissions) and provide a feedback message (i.e. “Sending form….”) when clicked? We could use dojox.form.BusyButton
to do just that:
<!-- assuming dojox.form.BusyButton has been required... -->
<button dojoType="dojox.form.BusyButton" busyLabel="Sending Data...">
Send Data
</button>
CheckedMultiSelect
What if our SELECT element allows for multiple selections? That’s the perfect opportunity to use the dojox.form.CheckedMultiSelect
widget:
<!-- assuming dojox.form.CheckedMultiSelect has been required... -->
<select multiple="true" name="rockers" dojoType="dojox.form.CheckedMultiSelect">
<option value="Oasis">Oasis</option>
<option value="Rod Stewart" selected="selected">Rod Stewart</option>
<option value="Coldplay" selected="selected">Coldplay</option>
<option value="Kings of Leon">Kings of Leon</option>
</select>
PasswordValidator
What if our website features a form that allows updating/changing of passwords? The dojox.form.PasswordValidator
provides all the functionality you need to quickly implement that system:
<!-- assuming dojox.form.PasswordValidator has been required... -->
<!-- pwValidate is the name of your function that verifies the current password is correct -->
<div dojoType="dojox.form.PasswordValidator" name="pwValidate">
<!-- pwType=old is where the user must place their current password -->
<input type="password" pwType="old" />
<!-- pwType=new is where the proposed new password must be placed -->
<input type="password" pwType="new" />
<!-- pwType=new is where the user verifies their new pass -->
<input type="password" pwType="verify" />
</div>
Reminder: JavaScript validation is not a substitute for server-side validation; JavaScript simply enhances the user experience by providing instant feedback to the user.
FileUploader
File uploading without enhancement is probably the worst form control available. The dojox.form.FileUploader
provides a great solution for making the process more streamlined:
<!-- assuming dojox.form.FileUploader has been required... -->
<div class="uploadBtn" dojoType="dojox.form.FileUploader" hoverClass="uploadHover" pressClas="uploadPress" activeClass="uploadBtn" disabledClass="uploadDisable" uploadUrl="/upload-files.php">Select Files</div>
The dojox.form Collection
The dojox.form namespace hosts a huge host of widget enhancements, including:
- BusyButton – button with special disable/busy label states
- CheckedMultiSelect – turns your SELECT element with the “multiple” attribute into a series of checkboxes for usability
- DropDownStack – disable/enable form elements based upon a selection
- RangeSlider – allows values to be chosen via a sliding scale
- Rating – easily creates UI for ratings (star ratings)
- …and much more!™
Great Dijit & Dojox Resources
- View Working Example
- Dijit Theme Tester
- Dive Into Dijit
- DojoX Form Reference Guide
- Dijit Form Reference Guide
- dojox.validate Reference
The Dijit library is much more than just gloss on your elements — it’s a hugely functional set of classes to make life easier for both you, the developer, and your users.