Samuel Sjöberg's weblog

Skip to navigation

vForm 2.0

vForm 2.0 can be divided into three parts: the XML rules, the javascript on the client and the PHP classes on the server side.

The vForm DTD

The vForm DTD is located at samuelsjoberg.com/vform.dtd. The definition is as follows:

<!ELEMENT vform (field+)>
<!ATTLIST vform name CDATA #IMPLIED>

<!ELEMENT field (rules, message)>
<!ATTLIST field name CDATA #REQUIRED>
<!ATTLIST field optional (true|false) "false">
<!ATTLIST field xml (true|false) "false">

<!ELEMENT rules (rule*)>
<!ELEMENT rule (#PCDATA)>
<!ATTLIST rule name CDATA #REQUIRED>

<!ELEMENT message (#PCDATA)>

Below is an example of a rule denfinition.


<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE vform PUBLIC "VFORM 2.0 DTD"
      "http://samuelsjoberg.com/vform.dtd">
<vform name="myform">
   <field name="url">
      <rules>
         <rule name="url"/>
         <rule name="expression">#</rule>
      </rules>
      <message>Enter a valid URL. Must contain an
         anchor (#).</message>
   </field>
   <field name="text" xml="true">
      <rules/>
      <message>At least write something.</message>
   </field>
</vform>

Reading the definition, one can see that vForm can act upon a specific form, defined by name, or on all forms on the page. If the name attribute is omitted, all forms on the page are assumed to be validated.

Each form field that should be validated must have a corresponding field group in the definition. The name of the field is used as identifiers. If the optional attribute is set to true, the field should be optional to fill in. However, it is up to each validation rule to check if the flag is set. The field tag also has an xml tag which can be used to preserve XML. If optional and xml is omitted, they are assumed to be false.

Each field contains a block of rules. This block can contain zero or multiple validation rules. If no rules are specified and optional is set to false the field will only ask for some kind of non-whitespace input.

The name of the rule corresponds to the name of the function to invoke at validation. So, if a new, custom validation rule should be used, simply create it and then add it to the rules block.

If PCDATA is specified for a rule it is passed as arguments at validation. For example, the expression rule takes a regular expression as argument.

Client side - Javascript

Below is an overview of the core javascript classes.

vForm Javascript core classes

vForm 2.0 is totally rewritten and has a more flexible design compared to its singleton predecessor. The validation is now delegated to vForm.Rules which in turn invokes the rules specified in the XML.

Validation rules are added as prototypes to the vForm.Rule class. This makes it possible to add validation rules without tainting the global namespace. Being prototypes, this also means that the validation functions can access the attributes of vForm.Rule directly. Consider for example the alpha rule that checks if the optional flag is set before validating.

vForm.Rule.prototype.alpha = function(element) {
   if (element.value.trim().isEmpty() && this.optional) {
      return true;
   }
   return /(D)+$/.test(element.value)
}

Errors are stored in the vForm.ErrorList class. It is responsible for keeping only one rule for each field (i.e., no duplicate error message) and to arrange and display them according to the vForm properties.

vForm.Map is a utility class not much different from a hash map. Values can be stored and retrieved based on a key. They can also be exported as an array to enable easy iteration.

vForm JS interface

The functions of most interest is the public functions to validate, refresh and reset forms.

vForm.validate() triggers immediate validation of the form(s) associated with the vform object.

vForm.refresh() should be used to reinitialize the form(s). This is necessary if changes has been made to the form, for exampe by an AJAX call. The method free all event handlers and reassign them again.

vForm.reset() can be called to reset any error messages and error classes that has been set. It is called automatically when the form's reset method is invoced.

vForm properties

vForm can be created with two arguments. The first should be the URL to the XML rules. The second is optional and is the properties for the vform object.

If properties are passed, the replace the default properties that looks like follows. Make sure to set all properties if not using the defaults.

var properties = {
   validateOnBlur : true,
   listErrors : true,
   errorMessageId : 'errorMessage',
   focusClassName : 'focus',
   invalidClassName : 'invalid',
   validClassName : 'valid',
   skip : new Array('submit', 'button',
            'reset', 'hidden', 'image')
}

Mechanisms for setting only some of the properties might be added in the future. It might for example be interesting to change the errorMessageId, but keep other settings as default.

Cross-browser compability

vForm 2.0 is known to work in the following browsers:

vForm on the server side is of course browser-independent.

Server side - PHP

The illustration below gives an overview of the core PHP classes.

vForm PHP core classes

The PHP solution follows the same basic design as the javascript solution, but differs in some aspects due to differences in the languages and in the way validation should be done. On the server, we have a given input that will not change until we reload the page, compared to the interactive client side where input change over time.

Just like on the client side, validation is delegated to vFormRules. However, in lack of prototypes, the bundled validation methods are found in the static vFormBase class. New validation rules can be added either to this class or in the global scope. The script first looks in the vFormBase class and then in the global namespace. Note that there is no problem to have some validation only on the server, or vice versa.

Each validation method have three arguments: the value of the field, the argument (might be empty) and a reference to the vFormRule that invoked the method. The alpha rule looks like this in PHP.

function alpha($value, $argument, $rule) {
   if (empty($value) && $rule->isOptional()) {
      return true;
   }
   return preg_match('/^(D)+$/', $value);
}

The $value is passed by reference to allow the validation methods to change the value. This is for example done by the url method that adds http:// if it is not present.

vForm PHP interface

vForm.isValid($array) is used to check if the content of the associative array is valid. The array is passed by reference and the content can be changed by validation functions.

vForm.getHtmlErrors() returns the error messages in an unordered HTML list.

vForm.getErrors() returns the errors in an associative array with the field name as key and the message as value.

vForm::stripArray($array) is a static utility function that performs stripslashes on all values in the passed array. The array can be multi-dimensional and is passed by reference.

Bundled validation rules

This is the predefined, bundled validation rules that comes with vForm 2.0.

required
Check that a non-whitespace input is present. Called automatically if the optional flag is not set.
url
The value must be formatted as a valid URL. http:// is added to the beginning of the value if it is not present.
email
The value must be formatted as a valid email address.
alpha
The value may not contain numeric characters.
numeric
The value can only contain numeric characters. Whitespace is not allowed.
max
Specify a maximum number of allowed choices in a group of elements. Pass the number as an argument.
min
Specify a minimum number of allowed choices in a group of elements. Pass the number as an argument.
expression
Check the value against a regular expression. The regular expression is passed as argument.
equals
Check if the values in two fields are equal. Pass the name of another field as argument.

Demonstration

I have set up a demonstration page where you try out vForm 2.0. Try to disable javascript to see how the server side validation kicks in.

Download

vForm 2.0 is released under the Creative Commons Deed. Feel free to use it in any way you can. If you find any problems, don't hesitate to tell me.

Download vForm 2.0.2

You will also need copy of Prototype in order to use vForm on the client.