Building and validating forms and form fields

Portrait de Brandon

This post provides a quick help on creating forms in Dokeos and how you can validate them. Dokeos has a class to handle forms which is based on the PEAR QuickForm package.

Forms

How your script should look like

In the pseudocode below, you can see the organization of a script using the FormValidator to build and process forms:

create the form
for all necessary elements
  add the element to the form
  optional: define some filters for this element
  optional: define some rules for this element
end for
if form validates
then
 get the form values
 process the values
else
 display the form
end if

Including the necessary libraries

To use the Dokeos FormValidator class, you should include the file FormValidator.class.php

require_once (api_get_library_path().'/formvalidator/FormValidator.class.php');

Creating a form-object

Once you've included the library, you can start building your form. The only required parameter of the constructor is the name of the form. As an optional second parameter, you can define if the form-method should be POST or GET.

$form = new FormValidator('my_form_name');

Now you can start to add elements to your form. Several element types are available. To create a textfield for example, you use following code

$form->addElement('text', 'field_name', get_lang('FieldDescription'),array('size'=>60));

In the HTML-output of the form this will look like

<input type="text" name="field_name" size="60"/>

The 3th parameter is the label which will be displayed next to the textfield.

Some Dokeos specific functions

  • FormValidator::add_textfield   : adds a textfield to the form with a filter to trim the result. By default this element is marked as required.
  • FormValidator::add_datepicker  : adds a datepicker to the form with a rule to check the date.
  • FormValidator::add_html_editor : adds a HTML-editor to the form with a filter to clean the HTML (formatting, closing open tags,...). By default this element is marked as required.
  • FormValidator::add_timewindow  : adds 2 date picker elements to the form and a rule to make sure the first date is before the second date.
  • FormValidator::add_progress_bar($delay = 2) : adds a progress bar to the form. When the user submits the form, there will be a delay of $delay seconds before the progress bar starts.

Elements

There are some default elements from QuickForm available (see for example The Linux Consultancy webpage). Dokeos has some other non-trivial elements available:

DatePicker

Using this element, you can easily build a date-picker.

$form->addElement('datepicker', 'start', get_lang('StartTimeWindow'), array ('form_name' => 'system_announcement'));

For now, the 4th argument should contain the form_name to make sure the Javascript works fine.

HTML-editor

Using this element, you can add a HTML-editor to your form. FCKEditor is used.

$form->addElement('html_editor', 'content', get_lang('Content'));

Receivers

This element contains 1 radio-buttons. One with label 'everybody' and one with label 'select users/groups'. Only if the second radio-button is selected, 2 select-list show up. The user can move items between the 2 checkboxes.

Language selection

If you need a dropdown-list in your form in which the user can select a language, you can use this form element. The returned value is the Dokeos folder name of the language

$form->addElement('select_language','course_language',get_lang('Language'));

Rules

Next to the default rules available from QuickForm, Dokeos provides some other rules to validate forms.

Date

This Rule will check if a date is valid. Use this rule in combination with the DatePicker element.

$form->addElement('datepicker', 'start', get_lang('StartTimeWindow'), array ('form_name' => 'system_announcement'));
$form->addRule('start', 'Invalid date', 'date');

DateCompare

Using this rule, you can easily validate the relation between 2 dates. If you have, for example, 2 datepicker elements and you want to make sure the first date is before the second date, you can use this rule.

$form->addElement('datepicker', 'start', get_lang('StartTimeWindow'), array ('form_name' => 'system_announcement'));
$form->addElement('datepicker', 'end', get_lang('EndTimeWindow'), array ('form_name' => 'system_announcement'));
$form->addRule(array ('start', 'end'), get_lang('StartDateShouldBeBeforeEndDate'), 'date_compare', 'lte');

FileType

With this rule, you can validate the filetype of uploaded files. In the next example, only image-files are allowed.

$form->addElement('file', 'picture', $label);
$allowed_picture_types = array ('jpg', 'jpeg', 'png', 'gif');
$form->addRule('picture', get_lang('OnlyImagesAllowed'), 'filetype', $allowed_picture_types);

HTML

Using this rule, you can validate the HTML-input from a user. Currently 3 levels are implemented (NO_HTML,STUDENT_HTML,TEACHER_HTML). For example, if you want to make sure the input of a htmleditor-field only contains HTML allowed to a student, you should use following code

$form->addElement('html_editor', 'openarea', get_lang('MyPersonalOpenArea'));
$form->applyFilter('openarea', 'html_filter');
$form->addRule('openarea', 'Some HTML-tags are not allowed.', 'html', STUDENT_HTML);

Note that you should always use this rule in combination with the html_filter. When processing the form, the html_filter will clean up the HTML by closing all tags, doing some formatting etc. Afterwards the rule will validate the HTML. The allowed tags and their attributes are defined in ~/formvalidator/Rule/allowed_tags.inc.php

Username

This rule will check if the given username is a valid one (only letters, numbers, _, -, .)

Username Available

With this rule, you can make sure a username entered by a user is a valid one. When adding this rule to your form, you should also provide the current username. The rule will check if the new username is available (correct: equals the old username or is a totally new username).

$form->addRule('username', get_lang('ThisFieldIsRequired'), 'required');
$form->addRule('username', 'Your username should only contain letters and numbers', 'alphanumeric');
$form->addRule('username', get_lang('UserTaken'), 'username_available', $user_data['username']);

Filters

HTML-filter

When you use the FormValidator, there's a function html_filter available which can be used as an element-filter for HTML. The same 3 levels as mentioned above are implemented (NO_HTML,STUDENT_HTML,TEACHER_HTML).

$form->applyFilter('element_name', 'html_filter', STUDENT_HTML);

The 3th parameter is optional and its default is NO_HTML. So you should add this filter to all textfields in which you don't want the user to input HTML.

Possible issues

Hidden fields and default values

You might end up blocking on this if you happen to play with forms that are dynamic (they extend in number of fields), or anywhere else where you don't submit the form immediately and alter a hidden field.

If you use hidden fields with quickForms, you will realise that their value is limited to the first value you have given them. As long as you come back to the form, there is no way to reset their value with a $form->setDefaults(). In fact, you have to use $form->setConstants() instead, in order to change the field value.

This is because hidden fields are inherently of constant value when you draw a form. However, sometimes, you might want to be able to change them, if you have changed the nature of the form.

For example, you have changed the quantity of fields to enter people names. As these fields are empty at first, it is not guaranteed that you will get a $_POST or a $_GET element for them when you submit the form, so you would like to store the current number of fields in a hidden field. Well, to do that, the only solution once you have given that hidden field a value, is to use setConstants().

You have been warned.

Dokeos examples

Have a look at following Dokeos scripts to see the FormValidator in action

  • main/admin/course_add.php
  • main/admin/course_edit.php
  • main/admin/system_announcements.php
  • main/admin/user_add.php
  • main/admin/user_edit.php
  • main/course_info/infocours.php
  • main/document/create_document.php

See also