Web DevCenter    
 Published on Web DevCenter (http://www.oreillynet.com/javascript/)
 See this if you're having trouble printing code examples


Essential JavaScript

Forms Extension Framework Documentation

03/16/2001

Also in Essential JavaScript:

Extending Dreamweaver: Let Dreamweaver Create Your Menus

Extending Dreamweaver with its JavaScript API

Accessing Dreamweaver's JavaScript API

Creating Themes with CSS and JavaScript

Parsing and DOM-Tree Building With JavaScript


Visit the JavaScript Library for sample scripts such the ForX entry that accompanies this article. More scripts will be added with upcoming columns.

In my previous column, I explained that I'll use form processing as a platform for introducing a few new JavaScript concepts. So in that spirit, this week I'm going to provide you with the nuts and bolts of the Forms Extension Framework, which I'll be referring to as ForX.

This is not a regular column in the sense that I'll focus on how to perform a specific task using JavaScript -- those columns are to follow in the future. This is, instead, a reference document designed to help you understand the templates I've included and, ultimately, to help you write your own ForX scripts.

Along those lines, I have a few suggestions. First, if you haven't read my two previous articles, Yajc -- Yet Another JavaScript Column and Working With Forms: An Introduction, do so now. Then you might want to look at my first library example, Forms Extension Framework (ForX). After that, breeze through this document once to become familiar with its content. Finally, I would then save this article and refer to it as you are playing with one of the ForX examples.

If you follow my suggested path, I think that you'll find yourself coming up to speed quickly with this exciting method of JavaScript form processing. Now, on to the ForX elements themselves.

Overview of the Forms Extension Framework

ForX is a set of attributes designed to extend existing form functionality with desirable features such as validation, content types, and groups. ForX is based on two principles:

With ForX, you can specify the elements that must be completed before a form can be submitted. To define these requirements, you use forx:required and forx:ctype, which can, in addition to existing attributes, be applied to the following elements (list items are linked to appropriate section of the HTML 4.01 reference):

A "group" makes it easier to handle elements that are not associated by default, such as radio buttons. With a conditional requirement you can have a group that's dependent on another element's value or on a literal value.

A form implementing ForX attributes must have a unique forx:id and the forx:enabled attribute set to true to be handled by the engine. To start the engine, you also have to attach the document's onload handler to the forxInit() function of the library -- after the library files have been included, of course.

To make sure a user completed the form correctly, you can use an option to enable a warning after the user tried to send a valid form (which doesn't necessarily mean that the data entered is correct). This element is shown only once (if the form remains valid after reviewing). This behavior is managed by forx:review, which must be set to true to switch the warning on. The warning element is an empty element (DIV) that's identified by its ID, forx:review, and class, forx.

Required elements and non-valid elements are marked with a special element, which is defined in the same way as the warning element above. You are generally free to fill the template elements with any content you want; you only need to have the correct ID and class.

The template file contains everything you need to get started. (Use right-click to save, or view source -- the unaltered template file will just view as a blank page!) After that, you should examine the example page for some working demos.

Namespace

ForX uses its own namespace to avoid conflicts with other elements. The prefix for the namespace is defined as forx, but it can't be altered due to missing DOM Level 2 support in IE. See implementation details on that. This means that every ForX attribute looks like this:

forx:required="true"

Every element that is referenced by another ForX element needs to have its own unique forx:id.

Validation

Requirements definition

To mark any element as being "required" for the form to process, the forx:required attribute has to be set to true. In addition to an unconditional requirement, you can define a simple if-then condition, which will be evaluated before the element is marked as being required. A condition of this type should have the following format:

if element operator value|element

where element is some element of the same form. All elements referenced need a forx:id attribute value.

The operator can be != (not equal) or == (equal).

You can use a literal value, or the name of another element on the same form, on the right side of the condition. A literal value is indicated by single or double quotation marks.

Checkboxes and radio buttons can use the keyword CHECKED instead of using the element's value on the right side. To make an element required only when some other element is checked, you write:

forx:required="if pay_card=='CHECKED'"

An element is required only when the condition evaluates true. If a required element has a content type or a regular expression also defined, the element is checked in regard to the content type or regular expression. If the variables don't match, the element is marked as being invalid.

All required elements need to be specifically marked as defined in the template. A template needs to have class forx and ID forx:marker to be recognized by the engine. This is how a template should look:

<div id="forx:marker" style="display:inline" class="forx"><b style="color:red">*</b></div>

As long as you meet these requirements, you are free to use whatever you want as your marker. The engine copies this template to all elements and group containers that are required, but not valid.

Content types

Elements that allow the user to enter any type of text should be checked to contain a special class of content. For this purpose, ForX defines a set of predefined content types. The content type for an element is defined within the forx:ctype attribute.

Predefined content types:

If no content type is specified for a required element, it's assumed to have the any content type.

Regular expressions

In those cases where a predefined set of content types is not good enough, a regular expression is the only solution. To use a regular expression, it has to be put into the forx:ctype attribute, where it differs from the defined content types by a leading and trailing slash. The syntax is the same as in JavaScript.

Grouping

Groups are probably one of the most desirable features. Just imagine the following situation: You need a form for an online store that allows customers to pay via invoice or credit card. For the latter, you need additional data such as the number and expiration date for the card.

Previously, "in the old days," you'd write a custom function that forked after it detected the customer's selected payment method. With ForX, you can easily group required elements and make them dependent on other elements.

To create such a group you need two things: a container element and a set of member elements.

The container element is needed to place the marker element into, which reminds the user to fill out required fields. If a group is not valid, the marker template is copied and shown in the group container element. The container element is identified by the forx:group attribute value -- the name of the group is stored here.

The container element also holds the forx:required attribute; the behavior is the same as with standard elements.

To highlight all members of a group, you can set the group container's forx:highlight attribute to true. A group implementing this feature shows all members with a red background for a few seconds and switches back.

To define the number of elements that must be valid to make the entire group valid, you use the forx:grouprequires attribute of the group container. You have three options: all elements, any element, or the exact number of elements must be valid. For example:

forx:grouprequires="all"
forx:grouprequires="any"
forx:grouprequires="3"

To add elements to a group you use the forx:member attribute. This value must correspond to a group defined by a container element. After adding an element to a group, the requirements are determined using the group container's attributes. You can define content types for all group members, however.

It's not possible to retrieve the value of a group or to nest groups.

See the example pages for working demos.

Claus Augusti is O'Reilly Network's JavaScript editor.


Read more Essential JavaScript columns.

Return to the JavaScript and CSS DevCenter.

Copyright © 2009 O'Reilly Media, Inc.