The Perl Toolchain Summit needs more sponsors. If your company depends on Perl, please support this very important event.
NAME
    WWW::Form - Object-oriented module for HTML form input validation and
    display

SYNOPSIS
    Simple and extendable module that allows developers to handle HTML form
    input validation and display flexibly and consistently.

DESCRIPTION
    This module:

    * provides functionality to handle all of the various types of HTML form
    inputs
    * handles populating form inputs with user entered data or progammer
    specified default values
    * provides support for validation of user entered input
    * handles presenting customizable error feedback to users
    * should be easy to extend, the WWW::Form module is designed to be
    inherited from, so you can add your own features.
    * Can be used in both mod_perl and CGI environments

    A sample usage:

        #!/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 name attributes 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{REQUEST_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 know the 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 HTML form content
            print $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 at least 6 characters',
                        6
                    )]
                }
            );
            return \%fields;
        }

  Creating WWW::Form Objects
     {
         # UI presentable value that will label the form input
         label => 'Your name',
         # If set, the form input will be pre-populated with this value
         # you could hard code a default value or use a value retrieved
         # from a data base table, for example
         defaultValue => 'Homer Simpson',
         # The type of form input, i.e. text, checkbox, textarea, etc.
         # (more on this later)
         type => 'text',
         # An array ref of various validations that should be performed on the
         # user entered input
         validators => [],
         # A hash ref that contains extra HTML attributes to add to the
         # container.
         container_attributes => {},
         # A hint that will be displayed to the user near the control and its
         # label to guide him what to fill in that control. (optional)
         hint => 'text',
         # A hash ref that contains extra HTML attributes to add to the
         # container of the hint.
         hint_container_attributes => {},
     }

  Supported 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
      file
      checkbox
      radio
      select
      textarea

    The following structure can be used for text, password, hidden, file,
    and textarea form inputs:

      $fieldName => {
          label => 'Your name',
          defaultValue => 'Homer Simpson',
          type => 'text', # or file, password, hidden, textarea
          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 called optionsGroup. The optionsGroup 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: All methods are available using internalCapsStyle and
    underscore_separated_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 reference that
    describes your WWW::Form object. (See instantiating 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 = WWW::Form->new($fieldsData, $params, $fieldsOrder);

  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.

      Example:

      my $fields = $form->getFields();

  resetFields
    Resets values and default values for all fields

      Example:

      $form->resetFields(include_defaults => 1);

  getField
    Returns hash ref of field data that describes the form input that
    corresponds to the passed $fieldName ($fieldName should be a value of a
    key in the $fieldsData hash ref you used to construct your WWW::Form
    instance).

      Example:

      my $field = $form->getField('address');

  getFieldErrorFeedback
    Returns an array of all the error feedback (if any) for the specified
    $fieldName.

      Example:

      my $name_feedback = $form->getFieldErrorFeedback('fullName');

  getFieldsOrder
    Returns array ref of field names in the order that they will be
    displayed.

      Example:

      $form->getFieldsOrder();

  getFieldValue
    Returns the current value of the specified $fieldName.

      Example:

      $form->getFieldValue('comments');

  isFieldValid
    Returns 1 or 0 depending on whether or not the specified field name is
    valid.

      Example:

      $form->isFieldValid('zip_code');

  getFieldValidators
    Returns array ref of validators for the passed field name.

      Example:

      $validators = $form->getFieldValidators($fieldName);

  getFieldType
    Returns value of a field's 'type' key for the specified $fieldName.

      Example:

      my $input_type = $form->getFieldType('favoriteColor');

  getFieldLabel
    Returns the label associated with the specified $fieldName.

      Example:

      my $ui_label = $form->getFieldLabel('favoriteBand');

  getFieldHint
    Returns the hint associated with the specified $fieldName or undef if it
    does not exist.

      Example:

      my $hint = $form->getFieldHint('favoriteBand');

  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.

      Example:

      $form->setFieldValue('fullName', uc($form->getFieldValue('fullName')));

  isValid
    Returns true if all form fields are valid or false otherwise.

      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 override this method in a subclass.

      Example:

      # Returns true if HTTP method is POST
      if ($form->isSubmitted($r->method())) {
          print "You submitted the form.";
      }

  asString
    Returns a string representation of the current instance.

      Example:

      &LOG->debug("WWW::Form instance: " . $form->asString());

  getFieldFormInputHTML
    Returns an HTML form input for the specified $fieldName.
    $attributesString is an (optional) arbitrary string of HTML attribute
    key='value' pairs that you can use to add attributes to the form input,
    such as size='20' or onclick='someJSFunction()', and so forth.

      Example:

      $html .= $form->getFieldFormInputHTML(
          'password',
          " size='6' class='PasswordInput' "
      );

  getFieldHTMLRow
    Note: Need to make sure you can pass in attributesString param unnamed!

        $self->getFieldHTMLRow($fieldName,
            'attributesString' => $attributesString,
            'form_args' => \%form_args,
        );

    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) arbitrary string of HTML attribute
    key='value' pairs that you can use to add attributes to the form input.
    %form_args are the parameters passed to the form as a whole, and this
    function will extract relevant parameters out of there.

    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>

  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 appropriately.

      Example:

      $html .= $form->getFieldFeedbackHTML('emailAddress');

  startForm
    Returns an opening HTML form tag.

    Arguments:

    name - Value of HTML name attribute.

    action - Value of action HTML attribute.

    attributes - Optional hash ref of HTML attribute name value pairs.

    is_file_upload - Optional, boolean, should be true if your form contains
    file inputs.

      Example:

      $form->start_form(
          action => '/some_script.pl',
          name   => 'MyFormName',
          attributes => {class => 'MyFormClass'}
      );

    Returns HTML similar to:

      <form action='/some_script.pl'
            method='post'
            name='MyFormName'
            id='MyFormName'
            class='MyFormClass'>

  endForm
    Returns HTML to close form.

      Example:

      $html .= $form->endForm();

  getFormHTML
    Loops through the fieldsOrder array and builds markup for each form
    input in your form.

    Returns HTML 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 the opening 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 arbitrary name => 'value' HTML
    attributes.

    is_file_upload - Optional boolean that should be true if your form
    contains a file input.

    hint_container_attributes - Optional HTML attributes for all the table
    rows containing the hints.

    buttons - Use this if you want your form to have multiple submit
    buttons. See API documentation for getSubmitButtonHTML() for more info
    on this parameter.

      Example:

      print $form->getFormHTML(
          action => './my_form.pl',
          name => 'LoginForm',
          attributes => {
              class => 'FormBlueBackground'
          },
          submit_label => 'Login',
          is_file_upload => 1
      );

  getSubmitButtonHTML
    Used by get_form_HTML to get HTML to display a type of a submit button.

    Returns string of HTML.

    Arguments: submit_type - 'submit' or 'image', defaults to 'submit' if
    not specified.

    submit_src - If type is 'image', this specifies the image to use.

    submit_label - Optional label for the button, defaults to 'Submit'.

    submit_class - Optional value for class attribute.

    submit_attributes - Optional hash ref of name => value pairs used to
    specify arbitrary attributes.

    buttons - Optional, array reference of hash refs of the previous
    arguments. You can use this parameter if you want your form to have
    multiple submit buttons.

SEE ALSO
    WWW::FieldValidator

    To see some demos of WWW::Form and WWW::FieldValidator point your web
    browser to:

      http://www.benschmaus.com/cgi-bin/perl/form_test.pl

    or

      http://benschmaus.com/cgi-bin/perl/form_test_subclass_example.pl

    The following modules are related to WWW::Form and WWW::FieldValidator,
    you might want to check them out.

    Data::FormValidator

    Embperl::Form::Validate

    Rose::HTML::Form

    HTML::Form

AUTHOR
    Ben Schmaus

    If you find this module useful or have any suggestions or comments
    please send me an email at perlmods@benschmaus.com.

CHANGELOG
    July 2, 2003

    Code formatting and cleanup.

    Adds support for file inputs.

    July 3, 2003

    Adds code examples to documentation for public methods.

    September 25, 2003

    Adds new methods including: resetFields(), isFieldValid(), and
    getFieldValidators().

    Changes _setFields method to handle empty user values. That is, in
    previous releases, if a form is submitted and the value for a field is
    empty, the value of the field will be set to the field's default value
    if it has one. This release updates _setFields to prefer submitted
    values over default values.

    Fixes some pdoc stuff.

    September 26, 2003

    More pdoc changes.

    January 10, 2004

    Adds support for displaying multiple submit buttons.

    Adds new public method: getSubmitButtonHTML.

    Adds support for escaping the value of HTML input 'value' attributes.

    January 5, 2005

    Adds README file to distribution.

    Makes some minor documentation changes.

TODO
    Add more helpful error logging.

    Add functionality for generating client side validation.

    Give this module a better namespace?

  Extension Idea
    Write a subclass that supports a templating library like
    Text::MicroMason or Text::Template.

THANKS
    Thanks to Shlomi Fish for suggestions and code submissions.

BUGS
    Nothing that I'm aware of, but please let me know if you have any
    problems.

    Send email to perlmods@benschmaus.com.

COPYRIGHT
    Copyright 2003, Ben Schmaus. All Rights Reserved.

    This program is free software. You may copy or redistribute it under the
    same terms as Perl itself.