Forms

Dojo has a number of facilities for dealing with HTML forms:

  • Form Bind - sets things up so that whenever the user hits the submit button, rather than submitting the form in the usual way, and refreshing the entire page, the contents are sent over xmlhttp (or any transport), and then the results are passed to the given callback.
  • dojo.validate.check - validates a form based on a given profile

  • form widgets - there are many form widgets that will validate/correct user input, and also make it easier to input data by (for example) providing a graphical datepicker rather than requiring users to enter a date as a series of number

Button

(dojo 0.9/dijit Release Only)

The Dojo button is a better looking HTML Button. You can display text and an icon, and specify the rollover and disabled background images

Examples


<div dojoType="dijit.form.Button">
   <img src="images/flatScreen.gif" width="32" height="32">
   <span style="font-size:xx-large">big</span>
</div>

Like HTML buttons, the dojo button sizes to fit its content. Usually, you will provide an onclick="..." attribute to specify what happens when the button is pressed.


This needs to be rewritten for 0.9

Using Your Own Backgrounds

By default, dojo uses a blue gradient background. But you can provide your own. You will need to create three .gif images: one for the left, one for the right, and one for the center. The filenames must end with l, r, or c, respectively. You can specify image sets for four different conditions:

  • activeImg - the mouse pointer is over the button
  • inactiveImg - the mouse pointer is not over the button
  • pressedImg - the button is being pressed
  • disabledImg - the button cannot be pressed

For example, you can use these files:

  • /images/buttons/disabled-l.gif
  • /images/buttons/disabled-r.gif
  • /images/buttons/disabled-c.gif

as the disabled image of your button like this:

<button dojoType="Button" disabledImg="/images/buttons/disabled" >
   Quit
</button>

API Reference: dojo.widget.Button

See Also: DropDownButton, comboButton

comboButton

Used in HTML Element:button

A combination Button and DropDownButton. Use this for a button that has a common action (e.g. "Make Regular Dinner") and less common related actions (e.g. "Make Romantic Dinner" and "Make TV Dinner")

Example

<button dojoType="comboButton" menuId='saveMenu'>
   <img src="images/editIcon.gif" width="32" height="32">
   Save
</button>

<div dojoType="PopupMenu2" id="editMenu" toggle="wipe">
	<div dojoType="MenuItem2" iconSrc="images/save.gif" caption="Save" accelKey="Ctrl+S" onclick="mySave();" />
	<div dojoType="MenuItem2" iconSrc="images/saveAs.gif" caption="Save As...." accelKey="Ctrl+A" onclick="mySaveAs();" />
</div>

You can also specify your own background images, as in Button.

API Reference: dojo.widget.ComboButton

See Also: Button, DropDownButton, PopupMenu2, MenuItem2

Editor2 (RichText) Widget

Introduction

Editor2 Widget in dojo provides a WYSIWYG editor for HTML content. The core is compact and lightweight, while a plugin framework ensures that any functionality can be achieved by plugins.

Basic html editing capacity is implemented in the core, which is the RichText widget. Currently keyboard shortcuts are also hardcoded in this widget (TODO: generalize this, or use KeyRouter instead?).

Editor2 is a subclass of RichText Widget which adds a toolbar (Editor2Toolbar Widget) to the top of the editing area.

Basic Principles of Editor2

In order to have an extensible structure, the new Editor2 introduced several new concepts.

Command (dojo.widget.Editor2Command)

The first and most fundamental one is call Command, which executes a specific function on the editing area. It also provides the API to retrieve the current state of the command. The base class for Command is dojo.widget.Editor2Command (defined in Editor2.js).

Each command should have a unique name and each command is a singleton object per page: no matter how many Editor2 instances there are in one page, they share the same command objects.

Toolbar Item (dojo.widget.Editor2ToolbarButton)

The toolbar (defined in Editor2Toolbar.js) for the editor2 contains serveral toolbar items. The basic class for toolbar item is dojo.widget.Editor2ToolbarButton (defined in Editor2Toolbar.js), which essentially is a simplified version of dojo widget.

Toolbar item can be of any type, besides buttons, you can have more complex items, such as a dojo combobox like item with a dropdown (see dojo.widget.Editor2ToolbarFormatBlockSelect in Editor2Toolbar.js).

Available Plugins

All the builtin plugins are located under src/widget/Editor2Plugin directory. Those files ending with Dialog are the actual popups. The table below lists all the other plugins:



NameDescriptionFeatures
ContextMenuCommandToolbarItem
ContextMenuContext Menu Core, with menu items for builtin commandsCut/Copy/Paste, Link/Unlink, Image properties--
FindReplaceImplement find and replace functionalities-Find/ReplaceFind/Replace
TableOperationSupport for table related operationInsert/Delete TableInsert/Delete TableInsert Table
AlwaysShowToolbarEnsure the toolbar is visible when scrolling the page---
ToolbarDndSupportToolbar Set/Item drag and drop support---
SimpleSignalCommandsAdd simple signals to Editor2, such as save() and createLink()---

Misc

SetupCopyPasteForFirefox - Copy, Cut and Paste are disabled by default in Mozilla/Firefox, this tip is how to enable it for your trusted websites.

Form Widgets

There are many widgets used for forms:

  • Button - just like HTML's button, except with a few advanced features
  • Checkbox - like HTML's checkbox but in soria (blue) theme
  • ComboBox - like a text input field, but w/suggested values
  • DropDownDatePicker - for specifying a date by selecting a cell of a calendar
  • DropDownTimePicker - for specifying a time (scheduled for 0.4 release)
  • Editor2 (RichText) - like HTML's textarea, but allows editing of rich text

  • HslColorPicker - pick a color
  • Select - just like HTML [select] element, except w/autocompletion, and loading of possible values from a remote data source
  • Slider - graphical slider control used to specify a number within a range
  • Spinner - numeric input field that can be adjusted up/down by pressing arrow keys
  • dojo.widget.*Validate - a bunch of widgets that check the user's input and correct it or print an error message if it doesn't conform to a certain format

The main principle of these widgets is that:

  • each widget corresponds to a native HTML element.
  • each widget (w/the exception of Button) represents a single input value
  • each widget has a (possibly hidden) <input> element, to which it serializes its input value, so that form submission (either normal submission or via FormBind) works as expected

All these widgets should have these attributes just like native HTML input elements. You can set them during widget construction, but after that they are read only:

  • disabled
  • tabIndex
  • name
  • value

And they also share some common methods:

  • disable()/enable()
  • onValueChanged() - called with the new value of the widget whenever it's changed
  • setValue() (note: you can get the value by accessing accessing value; exception: Editor)

(note: some widgets don't conform but we plan to convert them soon)

Author: Bill

ComboBox Widget

The ComboBox widget is a text input box that supplies a list of possible preexisting values for the user to choose from. It can query the server for an updated list of values as the user types, allowing it to offer a large list of values without requiring the entire list to be downloaded to the browser.



To demonstrate the power of this widget, let's dive right in and make an autocompleting combo box that queries the server for the list of matches for what the user has typed so far. We'll declare the widget using HTML:

<select dojoType="ComboBox"
    autoComplete="true"
    dataUrl="/suggest.php?match=%{searchString}"
    maxListLength="15"
    mode="remote"
    name="myComboBox">
There are a few attributes of note here.

  • autoComplete should be set to "true" if you want the widget to fill in the rest of the input box with the contents of the first item in the suggestion list. For example, if the user has entered "Ala" and the first suggestion on the list is "Alabama", the widget will put "bama" after the letters the user has typed (selected, so the user can simply continue typing to replace them with something else.)
  • dataUrl is the location of a URL which will be queried each time the user types something into the box. It will be discussed in more detail below.
  • maxListLength is the number of suggestions that will be visible to the user at one time. If the server supplies more suggestions than this, the user will have to scroll the list of suggestions to see them.
  • mode is one of "local" (the default; the dataUrl is fetched once at load time), "remote" (the dataUrl is fetched on each keypress, and is expected to return a JSON object; see below) or "html" (the dataUrl is fetched on each keypress, and is expected to return HTML.)
When the page containing that widget is loaded, it gets rendered as a text entry box with a little dropdown list button on the right side, not as a normal HTML <select>.

When you enter text into the box, Dojo tries to find matches for the text you've just entered. For example, suppose you type "a". Because the widget's mode is set to "remote", it will fetch the dataUrl and substitute your input for the magic %{searchString} token. (That token is only valid when mode is set to "remote" or "html".) In this case, it will fetch /suggest.php?match=a from the server. You don't have to use PHP on the server side, of course; it's simply used as an example here. The point is that the widget will replace the magic token in dataUrl with the user's input and fetch the resulting URL from the server.

What should the server return? In the "remote" mode, the widget expects a JSON array of entries, each entry of which contains a displayable option name and a value. For example, the server might return something like

[

[ "Alabama", "AL" ],

[ "Alaska", "AK" ],

[ "Arkansas", "AR" ]

]

Many server-side programming languages have existing libraries to output native objects in JSON form. In this case, for simplicity's sake, we'll do it by hand. Here's what an extremely simple, inefficient suggest.php might look like.

<?php

$states = array( "Alabama" => "AL",

"Alaska" => "AK",

...

);



$userInput = $_GET['match'];

$result = "[";



foreach ($states as $state => $abbreviation) {

if (strpos($state, $userInput) === 0) {

$result = $result . '[ "' . $state . '", "' .

$abbreviation . '"],';

}

}



$result = $result . ']';

print $result;

?>



FormBind

FormBind allows you to quickly setup your “Web 1.0″ form for asynchronous submission. Basically it sets things up so that whenever the user hits the submit button, rather than submitting the form in the usual way, and refreshing the entire page, the contents are sent over xmlhttp (or any transport), and then the results are passed to the given callback.

How do you do it? Easy:

function magicForm() {

var x = new dojo.io.FormBind({

// reference your form

formNode: document.forms[1],



load: function(load, data, e) {

// what to do when the form finishes

// for example, populate a DIV:

dojo.byId('myDiv').innerHTML = data;

}

});

}



dojo.addOnLoad(magicForm);

Note the unfortunate naming between dojo.io.bind() and dojo.io.FormBind.

dojo.io.bind() is a function that immediately sends the given info to the specified URL. (It would probably better be called something like dojo.io.send() but it isn't.)

dojo.io.FormBind(), on the other hand, doesn't send anything to the server. It just hooks up events so that when the user presses the submit button then the data is sent via dojo.io.bind(). Also note that you call "new" to make it work.

Note also that although dojo.io.bind() also takes a formNode argument, it's tricky to use and you are better off using FormBind. That's because for forms containing the Editor/Editor2 widgets, they need to serialize their data back to the [textarea] before the form is submitted, and that only happens when the form's onSumbit handler is called. Just calling dojo.io.bind() and specifying a formNode won't do that. However, with FormBind (and with an actual [input type="submit] button in in the form), everything works perfectly.

You can play with the demo to see it in action.

Validation

There are three methods which you can use to validate your form data on the client side before it is sent to the server - with each having their own benefits and drawbacks. Often, the most effective validation is performed using a combination of these methods.

It is important to understand that whilst client side validation is effective, it should not be considered a replacement of server side validation techniques. In order to provide an enjoyable and secure user experience it is essential that a combination of both methods is used.

Manual processing of input fields

The dojo.validate.* module provides a number of functions for validating user input. Currently, these functions are broken into the following groups:
  • common
  • datetime
  • de
  • jp
  • us
  • web

Common dojo.validate functions

dojo.validate.isText

This function takes two arguments - a value, and an optional flags object. Depending on the properties of the flags object (length, minlength, or maxlength), the value can be tested for exact length, a minimum length, or a maximum length.

dojo.validate.isInteger


This function takes two arguments - a value, and an optional flags object. Depending on the properties of the flags object (signed or separator), the value can be tested for the presence of a sign (+ or -) character at it's beginning, or whether it has separators. Whilst there is no default separator, single characters (such as ',') or arrays listing multiple separators can be specified.



dojo.validate.isRealNumber


dojo.validate.isCurrency



dojo.validate.isInRange


dojo.validate.isNumberFormat


TODO: summary of each function group and functions within each group

Using dojo.validate.check on a form

The second method of validation is known as dojo.validate.check. This function let's you setup a table of rules for checking a form's input elements.

TODO: more info on this

Validation widgets

There are several widgets in the dojo.widget.validate module that will either correct user input (converting lowercase to uppercase, etc.), or print errors when the input doesn't match a certain pattern. A few of the widgets are:

  • dojo.widget.validate.IntegerTextbox - allow only integer input
  • dojo.widget.validate.UsZipTextbox - entering a US zip code
  • dojo.widget.validate.UsPhoneNumberTextbox - entering a US phone number
Unfortunately currently the validation widgets, although they do display an error message alongside illegal values, do not actually prevent the form from submitting. This needs to be addressed at some point. You need to do some javascript coding yourself to make this happen.

Graphical widgets

The alternative to validating user input is to provide such an interface that the user can't enter a bogus value to begin with. For example, the DatePicker widget won't let the user input an invalid date.