PEAR HTML_QuickForm
1. Introduction
That article is an introduction to HTML_QuickForm, one of the parts of PEAR (PHP Extension and Application Repository).
It is supposed that you have already installed PHP and PEAR and you know PHP and HTML. Your web-server should interpret the scripts properly. The following script should print information about the environment where you server works:
Listing 1.1: PHP testing
<?php
phpinfo();
?>
You have to be sure that you have the latest version of PEAR. It can be done with the help of the following command.
Listing 1.2: PHP Upgrade
# Optionally check for upgrades first
pear list-upgrades
# Upgrade PEAR
pear upgrade-all
2. Beginning
Your first form
Let’s start with creating of the simple form. Copy the following code to the file with .php extension and open in your browser:
Listing 2.1: Simple form
<!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>
On opening that file browser will show: "Testing QuickForm" (black letters on the grey background). In that case PEAR and QuickForm are installed properly and work correctly. Let’s view the lines:
Listing 2.2:
require_once "HTML/QuickForm.php";
loads the class definitions for QuickForm. Then we define the object HTML_QuickForm.
Listing 2.3:
$form = new HTML_QuickForm("frmTest", "get");
That line means that the name of the form is frmTest and used method is GET.
Listing 2.4:
$form->addElement("header", "MyHeader", "Testing QuickForm");
That line creates the element on the form. Text area, simple text etc. can be used like an element. In our case it is the header, pseudo-element included to QuickForm. The name of that element is MyHeader and its text value is Testing QuickForm.
3. Practical examples
Real form
Our examples will show the code between opened and closed tags.
Listing 3.1: Form with buttons
<?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 have added three new elements: text area, “Clear” and “Submit” buttons. User can use the text area and “Clear” button, but “Submit” button doesn’t work. We’ll complete it later and show the full syntax of every element that can be added.
HTML_QuickForm presents the conception of elements freezing on the form. If the element is freezed it can be edited by user.
HTML_QuickForm also presents the conception of form validation.
Let’s view these conceptions:
Listing 3.2: Form with buttons
<?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, before the form’s displaying we’ll try to validate it. Don’t forget, for successful checking you have to call it by means of GET parameters. When we call it for the first time there is no GET parameter and checking returns FALSE, and form isn’t freezed.
In spite of it “Submit” button does something. By default the parameter of the action form is URL that displays the form.
Now ?MyTextBox=myname&btnSubmit=Submit line has been added to the GET parameter.
4. Rules and filters
Input checking
HTML_QuickForm provides input data validation means.
Listing 4.1: Input rules
<?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();
?>
As you can see there is one additional line $form->addRule. It means that “MyTextBox” element is required and if it is empty there will appear the error message “Your name is required”.
Checking in the client side
In the previous example checking was fulfilled by server after form sending. Also form can be validated in the client side using JavaScript. The only thing we have to do is to change a little addRule line:
Listing 4.2:
$form->addRule(‘MyTextBox’, ‘Your name is required’, ‘required’, ‘client’);
In that case if validation rules are not satisfied there appears dialog box with error message.
Other checking rules
“Required” is not the only checking rule. You can view the full list of checking rules below:
- required
- maxlength
- rangelength
- regex
- emailorblank
- lettersonly
- alphanumeric
- numeric
- nopunctuation
- nonzero
Some rules (for example maxlength) have additional argument.
Listing 4.3: Example of the rule with additional parameter
$form->addRule(‘postcode’, ‘Maximum postcode 8 characters’, ‘maxlength’, 8, ‘client’);
Filters
In the previous example checking rule will be satisfied by any input to the text area, including space.
In our case we want to escape using space as a symbol. We could write our own “regex” and change our rule with integrated “regex”. But there is another way. Integrated function trim in PHP can help us in solving our problem.
Listing 4.4: Filter using
<?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();
?>
Now, if you enter spaces to the text area and than press “Submit” button checking will be unsuccessful because spaces will be deleted from the line.
applyFilter has two arguments. First argument is element or line’s name ‘__ALL__’ which shows that filter is applied for all elements of the form. Second argument is the function defined by user or integrated, or array.
5. Default values, constants and processing
Default values
Now we don’t have any initial value in the text area. In that part of the article we’ll learn hoe to set the initial values or default values for the form’s elements. We’ll change our example a little and suppose that our form is used for editing the information that is situated in the database.
In that example we’ll edit the name or salutation in the database. Let’s view our form without default values (rules and filters are not included).
Listing 5.1: Usernames editing
<?php
require_once "HTML/QuickForm.php";
$user = array("firstname"=>"Mickey",
"lastname"=>"Mouse",
"sal_id"=>4,
"user_id"=>7);
$salutations = array("0"=>"Mr",
"1"=>"Miss",
"2"=>"Mrs",
"3"=>"Dr",
"4"=>"Sir");
$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->freeze();
echo "\n<HR>\n";
}
$form->display();
?>
After require_once we initialize two arrays - $user and $salutations. Also that form presents new elements - hidden and select. We have just created hidden element named user_id without setting the value in that point.
We could set the value like a third parameter but it can be set automatically. Select element’s syntax is similar to the element used in the text area, but it has fourth parameter that is a values array of the select field.
Our default values have been set in the $user array that can be called from the database. Default values for the form’s elements can be set by means of associative array from element-name=>element-value. Adding only one setDefaults line we can set the default value for every element on the form.
Listing 5.2: Default values setting
<?php $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(); ?>
Constants
Constants can be set using setConstants function. The setting algorithm is similar to default values setting but the main difference is that default values can be interactively changed; constants can be changed neither by user nor by function setDefaults.
Processing
In reality we have to process the sent data. We could place the data processing code after the $form->validate() function call but it will cause some difficulties. We’ll use process method that calls the callback function with the sent values. For example:
Listing 5.3: Form processing
<?php // first part of the form is the same as it was in the 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->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>";
}?>
Here we made some changes. First of all using condition else we guarantee that we have just shown the form without checking. Secondly, we used method process for calling the function process_data defined by user. That function is called with one parameter that includes associative array from element-name=>element-value. Second parameter of function process is used only when user has upgraded files using the form.
6. Miscellaneous
That chapter includes several issues that don’t relate to the listed above material, but they will be enough useful for working with HTML_QuickForm.
Attributes
As you could see the first argument of addElement function is the element type we want to add to the form. Amount and type of the arguments depend on the type of the element we want to add, but some elements have parameter attributes.
First example shows the text area with colored background.
Listing 6.1: Simple using of attributes.
<!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");
if ($form->validate()) {
$form->freeze();
}
$form->display();
First three arguments for addElement are element type, element name and header. Fourth parameter is parameter attributes. In that case we transmitted one attribute as a line and class fills the text area background with yellow color.
In the second example we change as text area class as well as its width and height. Here we use associative array:
Listing 6.2: Several attributes transmitting
<?php
// first part of the form is the same as it was in the previous example
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 using of attributes
Another attribute using is JavaScript code transmitting.
Listing 6.3: Using the JavaScript in attributes
<?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();
?>
Groups of elements
By default every element on the form has its own line. It would be better if in our previous examples "Clear" and "Submit" buttons situate on the same line. Element grouping allows us creating elements that include several elements inside and placing them on the form as one object. Let’s view the following:
Listing 6.4: Groups of elements
<?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, " ");
$form->addRule("MyTextBox", "Your name is required", "required");
if ($form->validate()) {
# If the form validates then freeze the data
$form->freeze();
}
$form->display();
?>
First argument of addGroup function is an array of the added elements. Fourth argument is a text that should be added between the elements.
Recommendations: elements
advcheckbox
checkbox returns the value to the form when it is selected. Unselected fields don’t return their value, checkbox variable doesn’t exist in the transmitted variables. advcheckbox solves these problems.
Listing 7.1: advcheckbox using
addElement("advcheckbox",
string element-name,
string element-label,
string text,
mixed attributes,
mixed values);
button
Listing 7.2: button using
addElement("button",
string element-name, // button name
string value, // button text
mixed attributes); // line or array of the attributes
checkbox
Listing 7.3: checkbox using
addElement("checkbox",
string element-name,
string element-label
string text,
mixed attributes);
date
Pseudo-element creates several select fields; it allows user setting date and time
Listing 7.4: date using
addElement("date",
string element-name, // date name
string element-label, // label before date
array options,
mixed attributes); // line or array of the attributes
options is an array that adjusts language, date/time format and minimal and maximum value for year area. Format line shows date/time format and amount of the displayed select fields. Return value is an associative array.
Listing 7.5: date example
<?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>";
}
?>
Possible values of the format line are as follows:
D = Short names of the days
l = Long names of the days
d = Numbers of the days
M = Short names of the months
F = Long names of the months
m = Numbers of the days
Y = year
h = 12 hours format
H = 24 hours format
i = Minutes
s = Seconds
a = am/pm
A = AM/PM
file
Listing 7.7: file using
addElement("file",
string element-name, // file element name
string element_label, // label for the file element
mixed attributes); // line or array of the attributes
That pseudo-element shows the text area and button, provides all necessary function for files uploading.
Listing 7.8: Example
<?php
require_once "HTML/QuickForm.php";
$uploadForm = new HTML_QuickForm("upload_form", "post");
$path = "e:/uploads";
$uploadForm->addElement("hidden", "path", $path);
$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($values["path"]);
}
else {
print "No file uploaded";
}
}
?>
We have to pay attention to some parts of the code.
$file =& $uploadForm->addElement("file", "filename", "File:");
That part of the code creates the link $file to the uploaded file used in the process function.
Uploadedfile rule exists only for element file. There are some other rules for element file:
maxfilesize defines the maximum size of the file that can be uploaded. For example:
Listing 7.9: Example
$uploadForm->addRule("filename", "The file you selected is too large", "maxfilesize", 524288);
mimetype defines the type of the uploaded file. For example:
Listing 7.10: Example
$uploadForm->addRule("filename", "Must be a jpeg", "mimetype", array("image/jpeg", "image/jpeg") );
header
Listing 7.11: header using
addElement("header",
string element-name, // header’s name
string text); // header’s text
hidden
Listing 7.12: hidden elements using
addElement("hidden",
string element-name, // name of the hidden element
string value, // value of the hidden element
mixed attributes); // line or array of the attributes
hierselect
That pseudo-element dynamically creates two HTML select elements.
Listing 7.13: hierselect using
addElement("hierselect",
string element-name, // hierselect element’s name
string label, // label of the text
mixed attributes); // line or array of the attributes
Listing 7.14: Example
<?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 Angeles";
$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>";
}
?>
Default values are set as follows:
Listing 7.15: Default values setting
$form->setDefaults(array("location"=>array(1,4)));
$sel =& $form->addElement("hierselect", "location", "Location:");
$sel->setMainOptions($main);
$sel->setSecOptions($secondary);
$form->addElement("submit", "btnSubmit", "Submit");
html
That pseudo-element adds unprocessed HTML to the form
Listing 7.16: html using
addElement("html",
string html-text;) // added HTML
image
image adds image to the form.
Listing 7.17: image using
addElement("image",
string element-name, // image name
string src, // initial file of the image
mixed attributes); // line or array of the attributes
link
Creates link.
Listing 7.18: link using
addElement("link",
string element-name, // name of the link
string label, // label
string href, // URI of thr link
string text, // text
mixed attributes); // line or array of the attributes
password
Listing 7.19: password using
addElement("password",
string element-name, // name of the password field
string label, // label for password field
mixed attributes); // line or array of the attributes
radio
Listing 7.20: radio using
addElement("radio",
string element-name, // name
string label, // text before the radio
string text, // text after the radio
int value, // returned value
mixed attributes); // line or array of the attributes
reset
Listing 7.21: reset using
addElement("reset",
string element-name, // name
string value, // text
mixed attributes); // line or array of the attributes
select
Listing 7.22: select using
addElement("select",
string element-name, // name
string label, // lable
mixed data, // data
mixed attributes); // line or array of the attributes
static
Listing 7.23: static using
addElement("static",
string label, // label
string text); // text
submit
Listing 7.24: submit using
addElement("submit",
string element-name, // name
string value, // text
mixed attributes); // line or array of the attributes
text
Listing 7.25: text using
addElement("text",
string element-name, // name
string label, // label
mixed attributes); // line or array of the attributes
textarea
Listing 7.26: textarea using
addElement("textarea",
string element-name, // name
string label, // label
mixed attributes); // line or array of the attributes



