Home arrow Graphic Design arrow Page 13 - Using HTML Quickform for Form Processing
GRAPHIC DESIGN

Using HTML Quickform for Form Processing


With HTML_QuickForm version 3.1, you can have a consistent look across all your forms and a simplified file upload. This chapter starts with the basics then shows you how to process submitted form data with HTML_QuickForm. (From the book, Essential PHP Tools: Modules, Extensions, and Accelerators, by David Sklar, Apress, 2004, ISBN: 159059280.)

Author Info:
By: Apress Publishing
Rating: 5 stars5 stars5 stars5 stars5 stars / 193
September 01, 2004
TABLE OF CONTENTS:
  1. · Using HTML Quickform for Form Processing
  2. · Steps for the Example
  3. · Individual Elements
  4. · Text, Password, Textarea
  5. · Hidden, Select
  6. · Checkbox, Radio
  7. · Submit, Reset, Button, Image
  8. · File, advcheckbox, Static
  9. · Header, Link, HTML
  10. · Element Groups
  11. · Processing Submitted Data
  12. · Without a Callback Function
  13. · Setting Validation Rules

print this article
SEARCH DEVARTICLES

Using HTML Quickform for Form Processing - Setting Validation Rules
(Page 13 of 13 )

HTML_QuickForm provides a flexible structure to incorporate data validation rules into your form. A number of common rules are included, and you can write your own as well. The addRule() method tells HTML_QuickForm to check the value in an element against a rule. For example, the required rule makes sure that the form element has a value:

$form->addElement('text','subject','Subject: ','size="30" maxlength="128"');
$form->addRule('subject','Enter a subject','required');

The first argument to addRule() is the name of the element to which the rule should be applied. The second argument is the message displayed if the rule isnít satisfied, and the third argument is the rule to apply. You must add an element to a form with addElement() before adding a rule for that element with addRule(). When the required rule is applied to an element, a small red asterisk appears next to the element and a note explaining that the asterisk denotes a required field is displayed at the bottom of the form. Figure 3-4 shows what the browser displays when the form is submitted without a value in the subject field.

sklar 

Figure 3-4. An error message is displayed when a validation rule is not satisfied.

HTML_QuickForm checks if submitted form data passes the rules when you call the validate() method. This method returns true if all the rules are satisfied or if no data was submitted. This makes it a useful condition in the if statement that decides whether to display or process the form. Instead of checking the value of a submitted element, you just call $form->validate():

if ($form->validate()) {
  mail('webmaster@example.com',$data['subject'],$data['body']);
  print "Your message has been sent.";
} else {
  $form->display();
}

If no data is submitted, then validate() returns false and the form is displayed. Similarly, if one or more of the validation rules isnít satisfied, validate() also returns false. This causes the form to be redisplayed, but this time it is displayed with error messages. If all of the validation rules are satisfied, then the form processing code that sends the e-mail message runs.

Built-in Validation Rules

The rules that HTML_QuickForm supports are required, maxlength, minlength, rangelength, regex, email, emailorblank, lettersonly, alphanumeric, nopunctuation, and nonzero. It also supports four rules for checking uploaded files: uploadedfile, maxfilesize, mimetype, and filename. Table 3-3 explains the built-in rules.

Table 3-3. Built-in Validation Rules

Rule NameArgumentRule Description
requiredSome input is required in the field.
maxlength$lengthThe input can be at most $length characters.
minlength$lengthThe input must be at least $length characters.
rangelength$min,$maxThe input must be between $min and $max characters (inclusive).
regex$rxThe input must match the regular expression $rx.
emailThe input must be a likely syntactically valid e-mail address.*
emailorblankThe input must be blank or satisfy the email rule.
lettersonlyThe input must contain only alphabetic characters.
alphanumericThe input must contain only letters and numbers.
numericThe input must contain a valid positive or negative integer or decimal number.
nopunctuationThe input must not contain any of these characters: ( ) . / * ^ ? # ! @ $ % + = , " ' > < ~ [ ] { }.
nonzeroThe input must not begin with zero.
uploadedfileThe element must contain a successfully uploaded file.
maxfilesize$sizeThe uploaded file must be no more than $size bytes.
mimetype$mimeThe uploaded file must have a MIME type of $mime. If $mime is an array of MIME types, the uploaded file must have a MIME type equal to one of the elements in $mime.
filename$file_rxThe uploaded file must have a filename that matches the regular expression $file_rx.

Note: *The regular expression that the email and emailorblank rules use to determine a valid e-mail address is /^[a-zA-Z0-9\._-]+\@(\[?)[a-zA-Z0-9\-\.]+\.([a-zA-Z]{2,4}| [0-9]{1,3})(\]?)$/'.

To pass an argument to rules that use one, use the fourth argument of addRule(). The argument for rangelength should be a string containing the minimum and maximum lengths:

// subject must be at least 5 characters
$form->addRule('subject','Enter a valid subject','minlength',5);
// subject must be between 5 and 25 characters
$form->addRule('subject','Enter a valid subject','rangelength',"5,25");

Except for required, elements with no value submitted arenít tested against any validation rules assigned to them. This means that if you assign a minlength rule to an element and a user leaves the element blank when the form is submitted, HTML_QuickForm wonít alert you that the rule isnít satisfied. To avoid this problem, assign both the required rule and the minlength rule to the element:

// subject must be at least 5 characters and must be filled in
$form->addRule('subject','Enter a subject of at least 5 characters', 'minlength',5);
$form->addRule('subject','Enter a valid subject','required');

This way, a blank subject is caught by the validator because the required rule is broken. If subject has a value that is fewer than five characters, the validator catches the broken minlength rule.

Custom Validation Rules

You can add your own validation rules with registerRule(). These rules are one of two types: function or regex. Custom function rules have their logic in a specific user-defined function. To create a custom function rule, first define a function that performs the test for the rule. This function must return true if the rule is satisfied and false otherwise. Then, tell HTML_QuickForm about the function with registerRule(). Once itís registered, you can add the rule to an element with addRule() just like any other rule. This example checks to see whether the first and last letters of an input element are the same:

function compare_firstlast($element_name,$element_value) {

$len = strlen($element_value);

// If the string is empty, then return false

if ($len == 0) { return false; }

$first_letter = $element_value{0};

$last_letter = $element_value{$len-1};

if ($first_letter == $last_letter) {

return true;

} else {

return false;

} }

$form->registerRule('same_firstandlast','function','compare_firstlast'); $form->addRule('user_name','The first and last letters must be the same', 'same_firstandlast');

Custom regex rules check whether a form element matches a specific Perlcompatible regular expression. To create a custom regex rule, call registerRule() with a second argument of regex and pass the regular expression as the third argument to registerRule(). Once itís registered, add the custom regex rule to an element with addRule(). This custom regex rule checks for a valid U.S. ZIP or ZIP+4 code:

$form->registerRule('us_zip','regex','/^\d{5}(-\d{4})?$/');
$form->addRule('zip','Enter a valid US ZIP code','us_zip');

Custom rules can access the fourth argument to addRule() just like minlength or maxlength built-in rules. If it is specified when addRule() is called, this extra value is passed to a custom function rule as a second argument. For example, the custom function rule compare is used to make sure the values of the two password fields match:

$form->addElement('text','password','Password:');
$form->addElement('text','password2','Password (again):');
$form->registerRule('compare','function','compare_field');
$form->addRule('password','Passwords do not match','compare','password2');
function compare_field($element,$value,$arg) {
global $form;
if ($value == $form->getElementValue($arg)) {
return true;
} else {
return false;
}
}

The fourth argument to addRule(), password2, is passed to compare_field() as $arg. Because password and password2 arenít hard-coded into the compare_field() function, you could use the same function and custom rule to compare other fields, such as e-mail address fields. The only difference would be in the second call to addRule(): You would add the rule to a different element and pass a different comparison element name.

A custom regex rule can use the extra value passed to addRule() by having the string %data% in its regular expression. The %data% is replaced by the extra value. In this example, the regular expression in the emaildomain rule as applied to the name element becomes @(example.org)$/:

$form->addElement('text','name','Name:');
$form->registerRule('emaildomain','regex','/@(%data%)$/');
$form->addRule('name','Enter an e-mail address from the example.org domain', 'emaildomain','example.org');

Group Rules

To add a validation rule to a group, use the addGroupRule() method instead of the addGroup() function. If you want to apply the same validation rule individually to each member of the group, the syntax for calling addGroupRule() is the same as addRule(). This rule checks to see if each text field in the name group has input at least five characters long:

$group[] =& HTML_QuickForm::createElement('text','first');
$group[] =& HTML_QuickForm::createElement('text','middle');
$group[] =& HTML_QuickForm::createElement('text','last');
$form->addGroup($group,'name','Your Name:');
$form->addGroupRule('name','Enter a valid name','minlength',5);

If any one of the group members doesnít pass the validation check, then the Enter a valid name error message is displayed next to the group. To apply different rules to individual elements of a group, the syntax for addGroupRule() is more complicated:

$form->addGroupRule('name',

  array(array(array('Invalid First Name', 'minlength',3)),

    array(array('Invalid Middle Name','minlength',3)),

    array(array('Last Name is required','required'),

        array('Invalid Last Name','maxlength',20))));

The first argument to addGroupRule() is the same: the group to apply the rules against. The second argument to addGroupRule() is now an array. This array holds all of the rules that are applied against the individual elements. This array of rules has one value for each element in the group. That value is in turn an array of rules to apply to the element. Finally, each rule is expressed as a two- or three-element array, consisting of an error message, rule name, and optional argument to pass to the rule. The previous example adds the following rules to the group:

  • The first name must be at least three characters (but is not required).

  • The middle name must be at least three characters (but is not required).

  • The last name is required.

  • The last name canít be more than 20 characters.

Storing each of the subarrays in separate variables for clarity, you can also add these rules to the group like this:

// Define the rules for each element in the group
$first_name_rule = array('Invalid First Name','minlength',3);
$middle_name_rule = array('Invalid Middle Name','minlength',3);
$last_name_rule_1 = array('Last Name is required','required');
$last_name_rule_2 = array('Invalid Last Name','maxlength',20);
// Collect together the rules for each element
$first_rules = array($first_name_rule);
$middle_rules = array($middle_name_rule);
$last_rules = array($last_name_rule_1, $last_name_rule_2);
// Add the rules to the group
$form->addGroupRule('name',array($first_rules, $middle_rules, $last_rules));

Client-Side Validation

By default, the validation rules check submitted data once it has been sent to the server. You can also enable client-side validation for some rules. To have a rule checked by the browser, before the data is submitted, add client as a fifth argument to addRule(). For example, to make sure a value is entered in the subject field that is at least five characters long, youíd use this:

// subject is required and must be at least 5 characters
$form->addRule('subject','Enter a valid subject','required',null,'client'); $form->addRule('subject','Enter a valid subject','minlength',5,'client');

The client-side validation is accomplished by JavaScript functions added to the form by HTML_QuickForm. When a user clicks the formís submit button, the JavaScript functions run the client-side validation rules and pop up an alert box if any of the rules are not satisfied. Client-side validation is available for all of the built-in rules except for uploadedfile, maxfilesize, mimetype, and filename. It is also available for any custom regex rules. You can enable client-side validation on custom function rules if you also define a JavaScript function in the page with the same name as the custom function. That JavaScript function must duplicate the checks that the server-side PHP validation function does.

Filters

HTML_QuickForm provides a way to automatically modify submitted form data. This is useful to trim whitespace from user input or perform other prevalidation tasks. Use the applyFilter() method to run a function on an element or group of elements:

// Trim whitespace from the value of subject
$form->applyFilter('subject','trim');
// Trim whitespace from subject and body
$form->applyFilter(array('subject','body'),'trim');
//Trim whitespace from all elements
$form->applyFilter('__ALL__','trim');

The first argument to applyFilter() specifies the fields to filter. You can pass astring containing a field name, an array containing a list of field names, or the special string __ALL__. The string __ALL__ tells applyFilter() to run the filter function on all submitted form elements. The second argument to applyFilter() is the filter function to run. This can be a built-in function, such as trim(), or a user-defined function. A user-defined filter function should take one argumentóthe submitted valueóand return the modified value. For example, the following is a custom filter function that cleans up a message board post subject line by removing multiple instances of Re: from its beginning:

function clean_re($s) {
    return preg_replace('/^(re:\s*)+/i','Re: ',$s);
}
$form->applyFilter('subject','clean_re');

The applyFilter() function modifies the values in the internal array that HTML_QuickForm uses to keep track of submitted form data. This is the same array that is passed to a callback function invoked by process(). If you want the submitted data to be modified by the filter functions before it is validated, you must call applyFilter() before you call validate() because validate() uses that same internal array. Even after calling applyFilter(), you can access the prefilter value of an element with the getElementValue() function. Pass it the name of an element, and it returns the submitted value, unaffected by any filters.

Group Rules and Filters: An Example

The following code implements a form that contains an element group and applies a filter to a <select> menu to prevent out-of-range submissions:

$form = new HTML_QuickForm('info');
// Add a Header for formatting
$form->addHeader('Enter Your Information');
// Create an element group of three textboxes for phone number
$phone[] = &HTML_QuickForm::createElement('text','areacode',null,'size="3"');
$phone[] = &HTML_QuickForm::createElement('text','exchange',null,'size="3"');
$phone[] = &HTML_QuickForm::createElement('text','last4',null,'size="4"');

// Add the group with a separator of "-"
$form->addGroup($phone,'phone_number','Phone: ','-');

// Add rules for phone number parts: each is required and must be
// specific lengths
$form->addGroupRule('phone_number',
   array(array(array('Area code is required', 'required'),
    array('Area code must be 3 numbers',
    'rangelength','3,3')),
    array(array('Exchange is required','required'),
    array('Exchange must be 3 numbers',
    'rangelength','3,3')),
    array(array('Phone number is required','required'),
    array('Phone number must be 7 digits',
    'rangelength','4,4'))));

// Add a select menu for choosing number type
// First, define the choices, with the zero'th choice being a prompt
$number_types = array('[ Select One ]','Home','Business','Mobile');

// Add the element to the form
$form->addElement('select','number_type','Number Type: ',$number_types);

// Prevent users from selecting the zero'th choice
$form->addRule('number_type','Please Select a Number Type','nonzero');

// Add a filter that prevents out of range submissions
$form->applyFilter('number_type','filter_number_type');

// Every good form needs a submit button
$form->addElement('submit','submit','Send Information');

// The main logic: display or process
if ($form->validate()) {
$form->process('display_info');
} else {
$form->display();
}

// The filter function that ensures a submitted number type is in the
// $number_types array
function filter_number_type($i) {
return (array_key_exists($i,$GLOBALS['number_types']) ? $i : 0);
}
// Format the submitted data nicely for printing
function display_info($data) {
$number_type_string = $GLOBALS['number_types'][$data['number_type']];
printf("Your %s number is (%03d) %03d-%04d.",
strtolower($number_type_string),
  $data['phone_number']['areacode'],
  $data['phone_number']['exchange'],
  $data['phone_number']['last4']);
}

The phone_number group contains three text elements: one for the area code, one for the exchange (the first three digits of the phone number), and one for the last four digits of the phone number. Each element of this group has two rules applied to it. First, they each get a required rule. Next, they each have a rangelength rule with the same number for the minimum and maximum length: three for the area code and exchange and four for the last four digits. This ensures that the area code and exchange are each exactly three characters long and the last four digits field is, as its name implies, exactly four digits long.

The number_type select element offers choices as to what kind of number has been entered: Home, Business, or Mobile. The nonzero rule applied to number_type makes the first choice in the $number_types array, [ Select One ], invalid. The filter function applied to number_type prevents an out-of-range submission. Even though the menu displayed in the form offers choices from zero to three, a malicious user could construct a request that submits a different value for number type. This filter rule, using the filter_number_type() function, maps any number type value to 0 that isnít 0, 1, 2, or 3.

When this form is submitted and validated, the code runs the display_info() function. This function uses printf() to format and display the submitted information. The submitted numeric value for number_type is turned back into a string by looking it up in the global $number_types array, and the components of the phone number are also printed.

This chapter is from Essential PHP Tools: Modules, Extensions, and Accelerators, by David Sklar, (Apress, 2004, ISBN: 1590592808). Check it out at your favorite bookstore today.

Buy this book now.


DISCLAIMER: The content provided in this article is not warranted or guaranteed by Developer Shed, Inc. The content provided is intended for entertainment and/or educational purposes in order to introduce to the reader key ideas, concepts, and/or product reviews. As such it is incumbent upon the reader to employ real-world tactics for security and implementation of best practices. We are not liable for any negative consequences that may result from implementing any information covered in our articles or tutorials. If this is a hardware review, it is not recommended to open and/or modify your hardware.

blog comments powered by Disqus
GRAPHIC DESIGN ARTICLES

- Customizing Wordpress Favicons and Gravatars
- Building Corner Effects with Transparent Bac...
- 3D Graphics Technology: VRML Part I - Introd...
- Creating Visual Effects
- Web Page Design Overview
- Creating Artistic Photographs
- Working with Tools in Paint Shop Pro 8
- Using HTML Quickform for Form Processing
- Introduction to Adobe FrameMaker
- WebLogic Workshop, WebLogic Platform, and th...
- Planning the Site
- Working with Web Services
- WebLogic Workshop Application Development Ba...
- Scanning Images for Web Use
- Web Graphics Overview

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials