Form(3)
NAME
WWW::Form - Simple and extendable OO module for form vali
dation and display
SYNOPSIS
Simple and easily extendable module that allows developers to handle form programming flexibly and consistently.
DESCRIPTION
This module:
· provides functionality to handle all of the various
types of HTML form inputs this includes displaying HTML
for the various form inputs)
· handles populating form inputs with user entered data or
progammer specified default values
· provides robust validation of user entered input
· handles presenting customizable error feedback to users
· is easily extended, the WWW::Form module is designed to
be easily inherited from, so you can add your own fea
tures.
The most time consuming process (and it's not too bad) is
creating the data structure used for instantiating a
WWW::Form object. Once you have a WWW::Form object almost
all your work is done, as it will have enough information
to handle just about everything.
- Before we get too involved in the details, let's take a
look at a sample usage of the WWW::Form module in a typi
cal setting. Note: If you're using Apache::Request and
mod_perl then your code would look a little different, but
not in how the WWW::Form module is used, however. - #!/usr/bin/perl
use strict;
use warnings; - use CGI;
use WWW::Form;
# used by WWW::Form to perform various
# validations on user entered input
use WWW::FieldValidator; - # Define values for form input names as constants
use constant EMAIL_FIELD_NAME => 'emailAddress';
use constant PASSWORD_FIELD_NAME => 'password'; - # gets us access to the HTTP request data
my $q = CGI->new(); - # hash ref of HTTP vars
# would be $r->param() if you're using mod_perl
my $params = $q->Vars() || {}; - my $form = WWW::Form->new(get_form_fields(), $params,
- [&EMAIL_FIELD_NAME, &PASSWORD_FIELD_NAME]);
- # check to see that the form was submitted by the user
# if you're using mod_perl, instead of $ENV{RE - QUEST_METHOD}
# you'd have $r->method()
if ($form->is_submitted($ENV{REQUEST_METHOD})) {
# validate user entered data
$form->validate_fields();# if the data was good, do something
if ($form->is_valid()) {# do some stuff with params because we knowthe
# user entered data passed all of its
# validation} - }
- # display the HTML web page
print <<HTML;
Content-Type: text/html - <html>
<head>
<title>A Simple HTML Form</title>
</head>
<body>
HTML# Display the form
$form->get_form_HTML(action => './form_test.pl'); - print <<HTML;
</body>
</html>
HTML - # returns data structure suitable for passing
# to WWW::Form object constructor, the keys will
# become the names of the HTML form inputs
sub get_form_fields {my %fields = (&EMAIL_FIELD_NAME => {label => 'Email address',
defaultValue => 'you@emailaddress.com',
type => 'text',
validators => [WWW::FieldValidator->new(WWW::FieldValidator::WELL_FORMED_EMAIL,
'Make sure email address is well formed')]},
&PASSWORD_FIELD_NAME => {label => 'Password',
defaultValue => '',
type => 'password',
validators => [WWW::FieldValidator->new(WWW::FieldValidator::MIN_STR_LENGTH,
'Password must be atleast 6 characters', 6)]});
return fields;}Instantiating A WWW::Form ObjectAs I said, instantiating a form object is the trickiest
part. The WWW::Form constructor takes three parameters.
The first parameter called $fieldsData, is a hash refer
ence that describes how the form should be built.
$fieldsData should be keyed with values that are suitable
for using as the value of the form inputs' name HTML
attributes. That is, if you call a key of your $fields
Data hash 'full_name', then you will have some type of
form input whose name attribute will have the value
'full_name'. The values of the $fieldsData keys (i.e.,
$fieldsData->{$fieldName}) should also be hash references.
This hash reference will be used to tell the WWW::Form
module about your form input. All of these hash refer
ences will be structured similarly, however, there are a
couple of variations to accommodate the various types of
form inputs. The basic structure is as follows:
{label => 'Your name', # UI presentable value that willlabel the form input
defaultValue => 'Homer Simpson', # if set, the form input will be pre-populated with this value# you could hard codea default value or use a value retrieved
# from a data base table, for example.type => 'text', # the type of form input, i.e. text,checkbox, textarea, etc. (more on this later)
validators => [] # an array ref of various validationsthat should be performed on the user entered input}So to create a WWW::Form object with one text box you
would have the following data structure:
my $fields = {emailAddress => {label => 'Email address',
defaultValue => 'you@emailaddress.com',
type => 'text',
validators => [WWW::FieldValidator->new(WWW::FieldValidator::WELL_FORMED_EMAIL,'Make sure email address is wellformed')]}};You could then say the following to create that WWW::Form
object:
my $form = WWW::Form->new($fields);Now let's talk about the second parameter. If a form is
submitted, the second parameter is used. This parameter
should be a hash reference of HTTP POST parameters. So if
the previous form was submitted you would instantiate the
WWW::Form object like so:
my $params = $r->param(); # or $q->Vars if you're using
CGI
- my $form = WWW::Form->new($fields, $params);
- At this point, let me briefly discuss how to specify val
idators for your form inputs. - The validators keys in the $fieldsData->{$fieldName} hash
reference can be left empty, which means that the user
entered input does not need to be validated at all, or it
can take a comma separated list of WWW::FieldValidator
objects. The basic format for a WWW::FieldValidator con
structor is as follows:
WWW::FieldValidator->new($validatorType,$errorFeedbackIfFieldNotValid,
$otherVarThatDependsOnValidatorType, # optional, depends on type of validator
# an optional boolean, if inputis
# entered validation is run,
# if nothing is entered inputis OK
$isOptional)- The FieldValidator types are:
WWW::FieldValidator::WELL_FORMED_EMAIL
WWW::FieldValidator::MIN_STR_LENGTH
WWW::FieldValidator::MAX_STR_LENGTH
WWW::FieldValidator::REGEX_MATCH
WWW::FieldValidator::USER_DEFINED_SUB- So to create a validator for a field that would make sure
the input of said field was a minimum length, if any input
was entered you would have:
WWW::FieldValidator->new(WWW::FieldValida- tor::MIN_STR_LENGTH,
'String must be at least 6characters',
6, # input must be at least 6chars
# input is only validated ifuser entered something
# if field left blank, it's OK
my $isOptional = 1) - Now for the third parameter. The third parameter is sim
ply an array reference of the keys of the $fieldsData
hash, but the order of elements in the array ref should be
the order that you want your form inputs to be displayed
in. This array ref is used by the get_form_HTML method to
return a form block that can be displayed in an HTML page.
# The third parameter will be used to generate an HTML- form
# whose inputs will be in the order of their appearance - in the
# array ref, note this is the constructor format you - should use when instantiating
# form objects
my $form = WWW::Form($fieldsData, $params, ['name', - 'emailAddress', 'password']);
- How To Create All The Various Form Inputs
- The following form input types are supported by the
WWW::Form module (these values should be used for the
'type' key of your $fieldsData->{$fieldName} hash ref): - text password hidden checkbox radio select textarea
- The following structure can be used for text, password,
hidden, and textarea form inputs:
$fieldName => {label => 'Your name',
defaultValue => 'Homer Simpson',
type => 'text',
validators => []- }
- The following structure should be used for radio and
select form inputs: - The data structure for input types radio and select use an
array of hash references alled optionsGroup. The options
Group label is what will be displayed in the select box or
beside the radio button, and the optionsGroup value is the
value that will be in the hash of HTTP params depending on
what the user selects. To pre-select a select box option
or radio button, set its defaultValue to a value that is
found in the optionsGroup hash ref. For example, if you
wanted the option 'Blue' to be selected by default in the
example below, you would set defaultValue to 'blue'.
$fieldName => {label => 'Favorite color',
defaultValue => '',
type => 'select',
optionsGroup => [{label => 'Green', value => 'green'},{label => 'Red', value => 'red'},
{label => 'Blue', value => 'blue'}],validators => []- }
- The following structure should be used for checkboxes:
- Note: All checkbox form inputs need a defaultValue to be
specified, this is the value that will be used if the
checkbox is checked when the form is submitted. If a
checkbox is not checked then there will not be an entry
for it in the hash of HTTP POST params. If defaultChecked
is 1 the checkbox will be selected by default, if it is 0
it will not be selected by default.
$fieldName => {label => 'Do you like spam>',
defaultValue => 'Yes, I love it!',
defaultChecked => 0, # 1 or 0
type => 'checkbox',
validators => []- }
- Function Reference
- NOTE: For style conscious developers all public methods
are available using internalCapsStyle and underscore_sepa
rated_style. So 'isSubmitted' is also available as
'is_submitted', and 'getFieldHTMLRow' is also available as
'get_field_HTML_row', and so on and so forth. - new
Creates a WWW::Form object. $fieldsData is a hash refer
ence that describes your WWW::Form object. (See instanti
ating a WWW::Form object above.) $fieldsValues (i.e.,
$params below) has keys identical to $fieldsData.
$fieldsValues is a hash reference of HTTP POST variables.
$fieldsOrder is an array reference of $fieldsData keys
that is used to determine the order that form inputs are
displayed in when getFormHTML() is called. If you don't use this parameter you should use the other public methods
provided and display your form inputs by hand.
Example:- my $params = $r->param() || {};
my $form;
$form = WWW::Form->new($fieldsData, $params, $fieldsOr - der);
- validateFields
- Validates field's values input according to the validators
(WWW::FieldValidators) that were specified when the
WWW::Form object was created. This will also set error
feedback as necessary for form inputs that are not valid. - Returns hash reference of all the fields that are valid
(generally you don't need to use this for anything though
because if all the validation passes you can just use your
hash ref of HTTP $params, i.e. $r->param()).
Example:- if ($form->isSubmitted($r->method)) {
# validate fields because form was POSTed
$form->validateFields(); - }
- getFields
- Returns hash ref of fields data.
- getField
Returns hash ref of field data that describes the form
input that corrsponds to the passed $fieldName. - getFieldErrorFeedback
Returns an array of all the error feedback (if any) for
the specified $fieldName. - The next couple of methods are somewhat miscellaneous.
They may be useful but in general you shouldn't need them. - getFieldsOrder
Returns array ref of field names in the order they should
be displayed. - getFieldValue Returns the current value of the specified $fieldName.
- getFieldType Returns value of a field's 'type' key.
- getFieldLabel
Returns the label associated with the specified $field
Name. - setFieldValue
Sets the value of the specified $fieldName to $value. You
might use this if you need to convert a user entered value
to some other value. - isValid
Returns true is all form fields are valid or false other
wise.
Example:- if ($form->isSubmitted($r->method)) {
# validate fields because form was POSTed
$form->validateFields($params);# now check to see if form inputs are all valid
if ($form->isValid()) {# do some stuff with $params because we know
# the validation passed for all the form inputs} - }
- isSubmitted
- Returns true if the HTTP request method is POST. If for
some reason you're using GET to submit a form then this
method won't be of much help. If you're not using POST as
the method for submitting your form you may want to over
ride this in a subclass.
Example:- # Returns true if HTTP method is POST
$form->isSubmitted($r->method()); - getFieldHTMLRow
- Returns HTML to display in a web page. $fieldName is a
key of the $fieldsData hash that was used to create a
WWW::Form object. $attributesString is an (optional) arbi
trary string of HTML attribute key='value' pairs that you
can use to add attributes to the form input. - The only caveat for using this method is that it must be
called between <table> and </table> tags. It produces the
following output:
<!-- NOTE: The error feedback row(s) are only displayed- if the field input was not valid -->
<tr>
<td colspan="2">$errorFeedback</td>
</tr>
<tr>
<td>$fieldLabel</td>
<td>$fieldFormInput</td>
</tr> - Example:
- $form->getFieldHTMLRow('name', " size='6' class='form
- Field' ");
- getFieldFeedbackHTML
- Returns HTML error content for each vaildator belonging to
$fieldName that doesn't pass validation. - Returns following HTML:
<div class='feedback'>
$validatorOneErrorFeedback
</div>
<div class='feedback'>
$validatorTwoErrorFeedback
</div>
<div class='feedback'>
$validatorNErrorFeedback
</div>- Note: If you use this, you should implement a CSS class
named 'feedback' that styles your error messages appropri
ately. - startForm
Title: startForm - Usage: $form->start_form(action => '/some_script',
- name => 'MyFormName',
attributes => {class => - 'MyFormClass'});
- Function: Returns opening form element.
- Returns: HTML to open a form.
- Arguments: action - Value of form's action attribute.
name - Value that will be used for form's name- and id attribute.
- attributes - hashref of key value pairs that
- can be used
to add arbitrary attributes to theopening form element.
- endForm
- Returns HTML to close form.
- getFormHTML Title: get_form_HTML
- Usage: $form->get_form_HTML();
- Functions: Loops through the fieldsOrder array and builds
- markup for each form input in your form.
- Returns: Markup that when output will display your form.
- Arguments: action - Value of form's action attribute.
name - Value that will be used for form's name- and id attribute.
- attributes - hashref of key value pairs that
- can be used
to add arbitrary attributes to theopening form element.
- submit_label - Optional label for your form's
- submit button.
- submit_name - Optional Value of your submit
- button's name attribute.
- This value will also be used for
- your submit button's id
attribute. - submit_type - Optional string value, defaults
- to submit, if you want to
- use an image submit button pass
- submit_type as 'image'.
- submit_src - Optional unless submit_type is
- 'image' then an image src should be specified
- with submit_src, e.g. submit_src
- => './img/submit_button.png'.
- submit_class - Optional string that specifies a
- CSS class.
- submit_attributes - Optional hash ref of arbi
- trary name => 'value'
- attributes.