PEAR HTML_QuickForm
Getting Started Guide

Contents

  1. Introduction
  2. Getting started
  3. Practical Examples
  4. Rules and Filters
  5. Defaults, Constants and processing
  6. Miscellaneous
  7. Reference: elements

A note from the author

I hope you find this guide, or tutorial, call it what you will, useful, and I also hope it saves you some time. If you do find it useful, I would be grateful if you could make a donation using the button below (and if it wasn't useful, mail me and tell me why not).

I receive a great deal of mail as a result of this article, much of it asking me to solve various PEAR/HTML_QuickForm/Smarty problems. Please bear in mind that the money that puts food on my family's table comes from the consultancy work that I do, so here's the deal. If you would like some help with a the points discussed in this article, mail me and tell me what that help is worth to you. Quote any amount you like, and if I'm able to help you out you can make a PayPal donation by way of thanks. Fair enough?

Thank you
Keith Edmunds

1. Introduction

What this is and what it isn't

This page is a simple introduction to one part of PEAR, HTML_QuickForm. It is by no means exhaustive; in fact, it covers a very small fraction of the total functionality of HTML_QuickForm. It is also not definitive: that role is taken by the source code itself, which is of course always right. However, for the newcomer to PEAR or HTML_QuickForm, the following should be a useful foundation to build upon.

Pre-requisites

It is assumed that you have installed both PHP and PEAR, and that you are familiar with PHP and HTML. Help with PEAR can be found at the PEAR website; help with PHP can be found at the PHP website. It is also assumed that your PHP scripts are correctly interpreted by your web server. The following script should display a host of information about the environment your web server runs in:

  <?php
      phpinfo();
  ?>

If, instead, you simply see the code above displayed in your browser window then you need to resolve this problem before proceeding. There are many tutorials setting up PHP on the Internet, and a simple search should find a suitable one.

Finally, it is a good idea to ensure that your PEAR installation is up to date. This can be done with the following command:

  # Optionally check for upgrades first
  pear list-upgrades
  # Upgrade PEAR
  pear upgrade-all

2. Getting started

Your first form

We will start by creating a very simple form. Copy the following code to a file, give it a .php extension, and display it in your browser:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  <html>
  <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Testing PEAR HTML_QuickForm</title>
  </head>
  <body>
  <?php
      require_once "HTML/QuickForm.php";

      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('header', 'MyHeader', 'Testing QuickForm');
      $form->display();
  ?>
  </body>
  </html>

Loading this file in your browser will simply show the words "Testing QuickForm" in black on a grey background. Not particularly exciting, but this does show that PEAR and QuickForm are installed correctly and working.

Let's consider the lines individually. The line:

require_once "HTML/QuickForm.php";

loads the class definitions for QuickForm. Next we instantiate an HTML_QuickForm object:

$form = new HTML_QuickForm('frmTest', 'get');

This says that the name of the form is frmTest, and the method used to pass the form variables back to the PHP script will be GET. Of course, in this particular example there are no variables to pass back. By default, the form's action - the URI that will be called when the form is submitted - is the same URI that displayed the form in the first place. This may seem strange at first, but it is actually very useful, as we shall see.

The line

  $form->addElement('header', 'MyHeader', 'Testing QuickForm');

creates an element on the form. An element is any item which appears on the form. It may be a text box, a select item, plain text, etc. In this case it is a header, a psuedo-element included in QuickForm simply to improve presentation. This element has the name MyHeader and the text value Testing QuickForm.

Finally, the line

$form->display();

makes it all happen. This displays the form and allows the user to interact with it. Of course, in this example there isn't anything the user can do, so let's create a more complex example.

3. Practical Examples

A real form

Our examples in future will only show the code between the <?php> tags. Consider the following example:

  <?php
      require_once "HTML/QuickForm.php";

      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('header', 'MyHeader', 'Testing QuickForm');
      $form->addElement('text', 'MyTextBox', 'What is your name?');
      $form->addElement('reset', 'btnClear', 'Clear');
      $form->addElement('submit', 'btnSubmit', 'Submit');
      $form->display();
  ?>

We've added three new elements: a text box complete with a label, a reset button, and a submit button. The user can type into the text box; the reset button works, but the submit button does not appear to do anything. We'll fix that in a moment, and later we will show the full syntax for each element that can be added.

Some theory

HTML_QuickForm introduces the concept of freezing elements of the form. Once an element is frozen it cannot be edited by the user. HTML_QuickForm enforces this by changing how the element is rendered: for example, in the case of a textbox the contents will be rendered simply as text, giving the user no opportunity to edit the text value.

HTML_QuickForm also introduces the concept of validating a form. A form is considered to be validated when the URI called to display it has one or more parameters (either GET or POST according the to the method used by the form), and all rules (which we will come on to shortly) have been satisfied.

Let's see these two concepts in action:

  <?php
      require_once "HTML/QuickForm.php";

      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('header', 'MyHeader', 'Testing QuickForm');
      $form->addElement('text', 'MyTextBox', 'What is your name?');
      $form->addElement('reset', 'btnClear', 'Clear');
      $form->addElement('submit', 'btnSubmit', 'Submit');
      if ($form->validate()) {
          # If the form validates then freeze the data
          $form->freeze();
      }
      $form->display();
  ?>

Now, immediately before the form is displayed we attempt to validate it. Remember, for the validation to succeed we need to call it with one or more GET parameters, but when we first call it there are no GET parameters so the validation returns FALSE and the form is not frozen. Finally, the form is displayed.

Now, however, the submit button does do something. The action parameter of the form is, by default, the URI that displayed the form in the first place, but we will now have a GET parameter appended as ?MyTextBox=myname&btnSubmit=Submit. This means that the validation will succeed (as there are, at this stage, no validation criteria to satisfy), and thus the form elements are frozen immediately prior to the form being re-displayed. Try it: you'll see that after you have entered a name and clicked on "Submit" the form is repainted, but the textbox has gone and is replaced simply by the text you typed in.

4. Rules and Filters

Checking input

HTML_QuickForm offers the facility to validate user input. By default, fields which are "required" are flagged as such to the user, and in the event that "required" input is missing a customisable error message is displayed. Consider the following:

  <?php
      require_once "HTML/QuickForm.php";

      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('header', 'MyHeader', 'Testing QuickForm');
      $form->addElement('text', 'MyTextBox', 'What is your name?');
      $form->addElement('reset', 'btnClear', 'Clear');
      $form->addElement('submit', 'btnSubmit', 'Submit');

      $form->addRule('MyTextBox', 'Your name is required', 'required');

      if ($form->validate()) {
          # If the form validates then freeze the data
          $form->freeze();
      }
      $form->display();
  ?>

Note the extra line, $form->addRule. This says that the element "MyTextBox" is required (ie, must not be left blank), and that if it is left blank the error message to the user is "Your name is required".

If you display the form now you will notice that the user is immediately informed that the name field is a required field. If you click on "Submit" while the name field is empty you will see the error message displayed. Filling in the name field and clicking on "Submit" once again validates, freezes and re-displays the form.

Client-side validation

In the above example the validation was carried out by the server when the form was submitted. It is possible to have the form rules validated at the client by using Javascript. A small change to the addRule line is all that is required:

  $form->addRule('MyTextBox', 'Your name is required', 'required', '', 'client');

In this example, if the validation rules are not satisfied a dialog box is displayed informing the user of the error. Arguably this lacks the clarity of the server-side validation, but it has the advantage of not needing to contact the server before informing the user of any input errors.

More validation rules

"Required" is not the only validation rule available. A full list:

Note that some rules (for example, maxlength) take an additional argument:

  $form->addRule('postcode', 'Maximum postcode 8 characters', 'maxlength', 8, 'client');

In addition to the above list, it is possible to add user-defined rules.

Filters

In the previous example the validation rule will be satisfied by any input in the text box, including, for example, a single space. This is because the rule simply ensures that there are one or more characters in the textbox, and a space character satisfies the rule.

In this particular case what we really want is text string minus any leading and trailing spaces. We could write our own regex to do this, and change our rule to be a "regex" rule, but there is an easier way. The PHP built-in function trim does exactly what we want, and we can arrange to have the contents of the textbox run through trim immediately prior to being validated by using the applyFilter method:

  <?php
      require_once "HTML/QuickForm.php";

      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('header', 'MyHeader', 'Testing QuickForm');
      $form->addElement('text', 'MyTextBox', 'What is your name?');
      $form->addElement('reset', 'btnClear', 'Clear');
      $form->addElement('submit', 'btnSubmit', 'Submit');

      $form->addRule('MyTextBox', 'Your name is required', 'required');
      $form->applyFilter('MyTextBox', 'trim');

      if ($form->validate()) {
          # If the form validates then freeze the data
          $form->freeze();
      }
      $form->display();
  ?>

If the user now enters only spaces in the textbox and then clicks Submit, the validation will fail because the spaces will be stripped prior to the rule being checked.

applyFilter takes two arguments. The first is either the name of an element or the string '__ALL__', meaning that this filter applies to all elements on the form. Note that there are two underscores both before and after the word ALL. The second argument is either a function, user-defined or built-in, or an array (the array format is not covered here).

5. Defaults, Constants and processing

Defaults

So far we have had no initial values present in the textbox when the form has been displayed. In this section we will look at how initial values, or default values, can be set for a form element. We'll change the example slightly here and assume that our form is being used to edit some information held in a database. We will use static arrays to represent the data retrieved from the database in order not to complicate the examples with the database code.

In this example we are going to edit a name and/or the salutation of someone in our database. Let's first look at our form without the default values added (we've omitted rules and filters for clarity):

  <?php
      require_once "HTML/QuickForm.php";

      ##########################################################
      # The user information would normally come from a database
      $user = array("firstname"=>"Mickey",
                    "lastname"=>"Mouse",
                    "sal_id"=>4,
                    "user_id"=>7);
      # 'Salutation' comes from a lookup table comprising 
      # sal_id, sal_text
      $salutations = array("0"=>"Mr",
                           "1"=>"Miss", 
                           "2"=>"Mrs", 
                           "3"=>"Dr",
                           "4"=>"Sir");
      # End of "database-retrieved" information
      ##########################################################

      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('header', 'MyHeader', 'Edit username');

      $form->addElement('hidden', 'user_id');
      $form->addElement('select', 'sal_id', 'Address me as:', $salutations);
      $form->addElement('text', 'firstname', 'First name:');
      $form->addElement('text', 'lastname', 'Last name:');

      $form->addElement('reset', 'btnClear', 'Clear');
      $form->addElement('submit', 'btnSubmit', 'Submit');

      if ($form->validate()) {
          // Form is validated, then processes the data
          $form->freeze();
          echo "\n<HR>\n";
      }
      $form->display();
  ?>

After the require_once statement we initialise two arrays, $user and $salutations, that represent data which would normally be retrieved from a database as associative arrays. This form also introduces two new element types, the hidden and the select elements. We have merely created a hidden element called user_id - presumably a database key - but given it no value at this point. We could submit the value as the third parameter, but as we shall see we can set the value automatically. The syntax for the select element is very similar to that used for the textbox we saw earlier, but has a fourth parameter which is an array of values for the select box.

Our default values have been set in the array $user, which would normally be retrieved from a database as mentioned above. The default values for the form elements can be set with an associative array of element-name=>element-value pairs. This is, of course, precisely how an associated array of values from a database would look, so with the addition of one setDefaults line we can set the defaults for every element on our form (only a few lines shown here for clarity):

      // First part of form as previous example
      $form->addElement('reset', 'btnClear', 'Clear');
      $form->addElement('submit', 'btnSubmit', 'Submit');

      if ($form->validate()) {
          // Form is validated, then processes the data
          $form->freeze();
      }
      $form->setDefaults($user);
      $form->display();
  ?>

Now when the form is displayed it shows the defaults set from the $user record.

Constants

Constants can be applied to form elements in a similar way to defaults using setConstants. The difference between defaults and constants is that the former can be changed interactively on the form by the user whereas the latter cannot be changed, either by the user or by a setDefaults call.

Processing

So far all we have done when the user has clicked on "Submit" is redisplay the form in its frozen state. In reality, of course, we would want to process the values submitted. We could put the code for processing the data immediately after the $form->validate() call, but that would result in a lot of code unrelated to the form creation function being part of that function. A tidier way is to use process method, which calls a callback function with the submitted values. An example:

      // First part of form as earlier example
      $form->addElement('reset', 'btnClear', 'Clear');
      $form->addElement('submit', 'btnSubmit', 'Submit');

      if ($form->validate()) {
          // Form is validated, then processes the data
          $form->freeze();
          $form->process('process_data', false);
      }
      else {
          $form->setDefaults($user);
          $form->display();
      }

      function process_data ($values) {
          echo "<pre>";
          foreach ($values as $key=>$value) {
              echo $key."=".$value."<br>";
          }
          echo "</pre>";
      }
  ?>

We have introduced a few changes here. Firstly, by using an else clause after the validation test we ensure that we only display the form while it is unvalidated. Secondly, we have used the process method to call the user-defined function process_data to process the form data after validation. This function is called with a single parameter which consists of an associated array of element-name=>element-value pairs. The second parameter to process is only used when the user has uploaded files using the form; we shall ignore it for now. Finally, the process_data function simply lists out the data passed to it. Notice that the select control returns the selected item's index rather than the text itself, so this function could very easily be adapted to update the database with the new values. Furthermore, the hidden value user_id has been correctly set too.

6. Miscellaneous

Introduction

This chapter has a number of items which don't fit easily into the preceding chapters but which are still useful to know about when working with HTML_QuickForm.

Attributes

As we have seen, the first argument to addElement is the type of element we wish to add to our form. The number, type and meaning of subsequent arguments depend upon the type of element being added, but many elements have an attributes parameter. This allows additional arguments to be placed in the HTML definition of the element, and takes the form of either a string or an array. Two examples should make the use of attributes clearer.

The first example simply displays a textarea with a coloured background. As this example requires some style definitions the whole file is shown here:

  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
  <html>
  <head>
      <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
      <title>Testing PEAR HTML_QuickForm</title>
  <style type="text/css">
     .ok { background: green; }
     .warn { background: yellow; }
     .error { background: red; }
  </style>
  </head>
  <body>
  <?php
      require_once "HTML/QuickForm.php";
      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('textarea', 'MyTextArea', 'Details:', "class=warn");
      $form->addElement('submit', 'btnSubmit', 'Submit');

      if ($form->validate()) {
          $form->freeze();
      }
      $form->display();
  ?>
  </body>
  </html>

The first three arguments to addElement are similar to those we have seen before: the type of element, the name of the element, and the caption. The fourth parameter is attributes, and in this case we have simply passed one attribute as a string, setting the class to "warn" which, in turn, sets the background of the text area to yellow.

In the second example we change not only the class of the textarea, but also its height and width. In this example, because we want to pass multiple values as attributes we use an associative array:

  // First part of form as previous example
  <?php
      require_once "HTML/QuickForm.php";
      $form = new HTML_QuickForm('frmTest', 'get');
      $attrs = array("class"=>"error",
                     "rows"=>"10",
                     "cols"=>"50");
      $form->addElement('textarea', 'MyTextArea', 'Details:', $attrs);

      if ($form->validate()) {
          // Form is validated, then processes the data
          $form->freeze();
      }
      $form->display();
  ?>

Further use of attributes

One other use of attributes is to pass Javascript code. The following (somewhat contrived) example causes the form to react immediately to a change in a select box without the user having to click on a submit button (this assumes that the user's browser supports Javascript):

  <?php
      require_once "HTML/QuickForm.php";

      define ("OK", 0);
      define ("WARNING", 1);
      define ("ERROR", 2);

      $status_list = array(OK=>"All OK",
                           WARNING=>"Warning",
                           ERROR=>"Error");

      $styles = array (OK=>"ok",
                       WARNING=>"warn",
                       ERROR=>"error");

      if (array_key_exists("status", $_GET)) {
          $style = $styles[$_GET['status']];
      }
      else {
          $style = $styles[0];
      }

      $attrs = array('onchange' => 
          "javascript:location.href=
              '?status='+this.options[this.selectedIndex].value;");

      $form = new HTML_QuickForm('frmTest', 'get', null, null, "class=$style");
      $form->addElement('select', 'status', 'Select status:', $status_list, $attrs);

      $form->display();
  ?>

Element groups

By default, each element on the form is rendered to a seperate line. Whilst this is a reasonable default, it does make some elements look untidy. In our earlier examples it would be more aesthetic to have the "Clear" and "Submit" buttons on one line.

Element grouping allows us to create a hybrid element which itself consists of multiple individual elements, and then to add this hybrid element to the form as one entity. Consider the following:

  <?php
      require_once "HTML/QuickForm.php";

      $form = new HTML_QuickForm('frmTest', 'get');
      $form->addElement('header', 'MyHeader', 'Testing QuickForm');
      $form->addElement('text', 'MyTextBox', 'What is your name?');

      $buttons[] = &HTML_QuickForm::createElement('reset', 'btnClear', 'Clear');
      $buttons[] = &HTML_QuickForm::createElement('submit', 'btnSubmit', 'Submit');
      $form->addGroup($buttons, null, null, '&nbsp;');

      $form->addRule('MyTextBox', 'Your name is required', 'required');

      if ($form->validate()) {
          # If the form validates then freeze the data
          $form->freeze();
      }
      $form->display();
  ?>

The first argument to addGroup is an array of the elements to add, which is created on the two line above. The fourth argument is the text to place between the elements, the separator text, which in this case is a simple space.

Note: Do not confuse element groups with HTML groups, such as are often used with radio buttons.

7. Reference: elements

Introduction

This chapter gives a brief overview of each type of element; it is not yet complete and is somewhat terse in places. In some cases the descriptions are taken straight from the source code. All arguments other then the type of element (the first argument to addElement) are optional.

advcheckbox

Normally a checkbox only passes a value back to the form when it is checked. Unchecked boxes not only pass no value back, but also the checkbox variable does not exist in the values passed to the process routine. The advcheckbox overcomes these problems.

  addElement('advcheckbox',
             string element-name,   // name of advcheckbox
             string element-label,  // label output before advcheckbox
             string text,           // label output after advcheckbox
             mixed attributes,      // string or array of attributes
             mixed values);         // see below
  

If values is omitted then the value returned is an empty string if not checked, and '1' if checked. If a string value is passed then the return value is empty string/supplied string, and if an array of two strings is passed they are taken as the unchecked/checked values to return.

button

  addElement('button',
             string element-name,   // name of button
             string value,          // text of button
             mixed attributes);     // string or array of attributes
  

checkbox

  addElement('checkbox',
             string element-name,   // name of checkbox
             string element-label,  // label output before checkbox
             string text,           // label output after checkbox
             mixed attributes);     // string or array of attributes
  

date

This pseudo-element produces multiple select boxes for the user to input a date and/or time.

  addElement('date',
             string element-name,   // name of date
             string element-label,  // label output before date
             array options,         // see below
             mixed attributes);     // string or array of attributes
  

options is an array which sets the language, the date/time format, and the minimum and maximum year offered in the select boxes. The format string determines not only the date/time format, but also the number of select boxes shown. The value of the date returned is an associative array, each element key being the relevant format character and the value being the value selected by the user. An example should make this clear:

  <?php
      require_once "HTML/QuickForm.php";
      $form = new HTML_QuickForm('frmTest', 'get');
      $options = array(
          'language'  => 'en',
          'format'    => 'dMYHi',
          'minYear'   => 2001,
          'maxYear'   => 2005
      );
      $form->addElement('date', 'mydate', 'Choose date', $options);
      $form->addElement('submit', 'btnSubmit', 'Submit');

      if ($form->validate()) {
          // Form is validated, then processes the data
          $form->freeze();
          $form->process('process_data', false);
      }
      else {
          $form->display();
      }

      function process_data ($values) {
          echo "<pre>";
          var_dump($values);
          echo "</pre>";
      }
  ?>

The possible values for the format string are:

  D = Short names of days
  l = Long names of days
  d = Day numbers
  M = Short names of months
  F = Long names of months
  m = Month numbers
  Y = Four digit year
  h = 12 hour format
  H = 23 hour  format
  i = Minutes
  s = Seconds
  a = am/pm
  A = AM/PM
  

To set default values for the date element simply create an array and assign the required values to the format string elements defined above. For example, to set the default date to 28th February 2005:

  $form->setDefaults(array(
    'my_date' => array('d'=>28, 'F'=>"February", 'Y'=>2005)));
  

Here's a complete example that sets the default date to today's date:

  <?php
    require_once "HTML/QuickForm.php";
    $form = new HTML_QuickForm('frmTest', 'get');
    $options = array(
        'language'  => 'en',
        'format'    => 'dMYHi', 
        'minYear'   => 2000, 
        'maxYear'   => 2010 
    ); 
    $date_defaults = array(
        'd' => date('d'),        
        'M' => date('M'),
        'Y' => date('Y'),
        'H' => date('H'),
        'i' => date('i')
    );

    $form->setDefaults(array('mydate' => $date_defaults));
    $form->addElement('date', 'mydate', 'Choose date', $options);
    $form->addElement('submit', 'btnSubmit', 'Submit');
    
    if ($form->validate()) {
        // Form is validated, then processes the data
        $form->freeze();
        $form->process('process_data', false);
    }
    else {
        $form->display();
    }
     
    function process_data ($values) {
        echo "<pre>";
        var_dump($values);
        echo "</pre>";
    }
?>

element

For user-defined elements. This section to be completed.

file

Note: The 'file' documentation was submitted by Leonie Price

  addElement('file',
             string element-name,   // name of file element
             string element_label,  // label for file element
             mixed attributes);     // string or array of attributes
  

This is a pseudo-element that displays a text box and button, and provides all the supporting functions needed to manage the uploading of files.

Warning: The official documentation records this element as being depreciated, and may not be supported in future versions of QuickForm.

Let's look at an example of the use of the file element:

  <?php
      require_once "HTML/QuickForm.php";
      $uploadForm = new HTML_QuickForm('upload_form', 'post');
      $path = "/path/to/uploads";
      $file =& $uploadForm->addElement('file', 'filename', 'File:');
      $uploadForm->addRule('filename', 'You must select a file', 'uploadedfile');
      $uploadForm->addElement('submit', 'btnUpload', 'Upload');
      if ($uploadForm->validate()) {
          $uploadForm->process('process', true);
      }
      else {
          $uploadForm->display();
      }

      function process($values) {
          global $file;
          if ($file->isUploadedFile()) {
              $file->moveUploadedFile($path);
          }
          else {
              print "No file uploaded";
          }
      }
  ?>

There are a couple of points to note in this code. Firstly, the code segment

$file =& $uploadForm->addElement('file', 'filename', 'File:');

creates a reference called $file to the file being uploaded, which is used later in the process function.

Secondly, the rule to check that a file has been selected, uploadedfile, exists specifically for the file element. There are other custom rules for the file element:

maxfilesize - sets the maximum file size that may be uploaded. For example:

  $uploadForm->addRule('filename', 'The file you selected is too large', 'maxfilesize', 524288);

mimetype - defines the type of file which may be uploaded. For example:

  $uploadForm->addRule('filename', 'Must be a jpeg', 'mimetype', array('image/jpeg', 'image/jpeg') );

Finally, after validation the process function is called. The final argument, true, indicates that the uploaded file(s) should be processed with the form.

header

  addElement('header',
             string element-name,   // name of header
             string text);          // text of header
  

hidden

  addElement('hidden',
             string element-name,   // name of hidden element
             string value,          // value of hidden element
             mixed attributes);     // string or array of attributes
  

hiddenselect

This section to be completed.

hierselect

This pseudo-element dynamically creates two HTML Select elements. The values available in the second Select element are determined by the value selected in the first. For example, the first box could list countries and the second cities; only the cities which exist in the selected country would be available.

  addElement('hierselect',
             string element-name,   // name of hierselect element
             string label,          // text label
             mixed attributes);     // string or array of attributes
  
The methods setMainOptions and setSecOptions are used to populate the two select boxes. The argument to setMainOptions is a single dimension array; the argument to setSecOptions is a two-dimension array, the first dimension being the key used to associate the secondary option to the appropriate main option. The value returned is a two-element array, the first element being the value of the main option and the second element being the value of the secondary options. An example should make the use of hierselect easier to understand:
  <?php
      require_once "HTML/QuickForm.php";
      $form = new HTML_QuickForm('frmTest', 'get');

      $main = array();
      $secondary = array();

      $main[0] = "England";
      $main[1] = "Scotland";
      $main[2] = "USA";

      $secondary[0][0] = "London";
      $secondary[0][1] = "Manchester";
      $secondary[0][2] = "Liverpool";
      $secondary[1][3] = "Edinburgh";
      $secondary[1][4] = "Glasgow";
      $secondary[2][5] = "Fort Worth";
      $secondary[2][6] = "Boston";
      $secondary[2][7] = "Los Angles";

      $sel =& $form->addElement('hierselect', 'location', 'Location:');
      $sel->setMainOptions($main);
      $sel->setSecOptions($secondary);    
      $form->addElement('submit', 'btnSubmit', 'Submit');

      if ($form->validate()) {
          // Form is validated, then processes the data
          $form->freeze();
          $form->process('process_data', false);
      }
      else {
          $form->display();
      }

      function process_data ($values) {
          echo "<pre>";
          var_dump($values);
          echo "</pre>";
      }
  ?>

Warning: Note that if a default value for the main box is set this does not automatically set the contents for the secondary box

Set default as follows:

      // First part of form as previous example
      $form->setDefaults(array('location'=>array(1,4)));
      $sel =& $form->addElement('hierselect', 'location', 'Location:');
      $sel->setMainOptions($main);
      $sel->setSecOptions($secondary);    
      $form->addElement('submit', 'btnSubmit', 'Submit');
      // Rest of form as previous example

html

This pseudo-element adds raw HTML to a form.

  addElement('html',
             string html-text);     // the HTML to add
  

image

Adds an image to a form.

  addElement('image',
             string element-name,   // name for image
             string src,            // source file of image
             mixed attributes);     // string or array of attributes
  

link

Creates a link.

  addElement('link',
             string element-name,   // name for link
             string label,          // label for link field
             string href,           // URI of link
             string text,           // text to display
             mixed attributes);     // string or array of attributes
  

password

  addElement('password',
             string element-name,   // name for password
             string label,          // label for password field
             mixed attributes);     // string or array of attributes
  

radio

  addElement('radio',
             string element-name,   // name for radio button
             string label,          // text to display before button
             string text,           // text to display after button
             int value,             // the value returned
             mixed attributes);     // string or array of attributes
  

Note: Adding multiple radio buttons with the same element-name will cause them to behave as a group (ie, only one can be selected).

To select a default radio button from a group, use:

  $form->setDefaults(array(element-name => value));
  

reset

  addElement('reset',
             string element-name,   // name of reset
             string value,          // text of button
             mixed attributes);     // string or array of attributes
  

select

  addElement('select',
             string element-name,   // name of select
             string label,          // label for select
             mixed data,            // data for select; see earlier text
             mixed attributes);     // string or array of attributes
  

static

This element displays static text on the form.

  addElement('static',
             string label,          // label to display
             string text);          // text to display
  

submit

  addElement('submit',
             string element-name,   // name of submit
             string value,          // text of button
             mixed attributes);     // string or array of attributes
  

text

  addElement('text',
             string element-name,   // name of text box
             string label,          // label
             mixed attributes);     // string or array of attributes
  

textarea

  addElement('textarea',
             string element-name,   // name of textarea
             string label,          // label
             mixed attributes);     // string or array of attributes