HTMLObject::Form(3)

NAME
Form - the HTMLObject::Form class.

SYNOPSIS
 The HTMLObject::Form module is an attempt to make creating and
 validating html forms simpler for the programmer and web page designer.

 This object will use a template provided by the programmer to substitute
 the generated html form items into.  The power behind this module is the
 fact that the template creator is doing layout, but not actually
 creating the form items (text fields, select boxes, etc.).  These form
 items are defined in the data structure and profile structures passed
 into the generate() method so that we can dynamically generate them
 without having to parse the html template and determine the "field" to
 update/populate with values.  It is much easier to just generate the
 form item than try to update the html already generated.

 In an effort to try and reduce duplication of existing code, we are
 using the Data::FormValidator module to do the form validation code and
 the HTMLObject object passed into generate() to do form item creation.

 Your script has to provide 3 things:
 1) the HTML template that represents the form being worked on.  It
   must contain the <form></form> tags and any layout structure you want.
 2) the Data::FormValidator profile structure.
 3) the data structure which is an hash of hash refs, where the key is
   the "name" attribute for the form item being created.

   See the generate() method for details on the data structure.

EXAMPLE
 use HTMLObject::Form;
 use HTMLObject::Normal;
 use HTMLObject::CGILib;

 my %commands = ( display => "Display the form", update => "Update the database", );

 # build up the data structure to pass to the generate() command
 # to build up and display the form from.
 my %data = ( "fname" => { -Label => "First Name:",
                -Type => "text" },
              "lname" => { -Label => "Last Name:",
                -Type => "text" },
              "mname" => { -Label => "Middle Initial:",
                -Type => "text", size => 1, maxlength => 1 },
              "color" => { -Label => "Your Favorite Color:",
                -Type => "select", -Options => getColors() },
              "color2" => { -Label => "All Your Favorite Colors:",
                -Type => "multi-select", -Options => getColors(), -Value => [ "yellow", "green" ],
                -Buttons => [ "All", "Toggle", "None" ] },
              "color3" => { -Label => "Pick a color:", -Type => "color-picker", -Value => "#000000", },
              "startDate" => { -Label => "Start Date:", -Type => "date-picker", -Value => "2004-01-01", -year => "2004", },
              "endDate" => { -Label => "End Date:", -Type => "date-picker", -Value => "2004-12-31", -year => "2004", },
              "comment" => { -Label => "Comment:",
                -Type => "textarea" },
              "command" => { -Type => "hidden",
                -Value => "display" },
              "formSubmitted" => { -Type => "hidden",
                -Value => "1" },
            );

 # create the order array that specifies the order form items should be processed by createTemplate().
 my @order = qw( fname mname lname color color2 color3 startDate endDate comment );

 # build up the profile to pass to the Data::FormValidator for validation
 # of the input when the form is submitted back to us.
 my %profile = ( required => [ qw( fname lname color color2 color3 startDate endDate command formSubmitted ) ],
                 optional => [ qw( mname comment ) ],
                 constraints => { fname => qr/^.+$/,
                                  mname => qr/^.$/,
                                  lname => qr/^.+$/,
                                  color3 => qr/^((#([A-Fa-f0-9]){6})|transparent|inherit)( !important)?$/,
                                  command => sub { my $value = shift; return exists $commands{$value}; },
                                },
               );

 my $template = <<"END_OF_FORM";
 <form #FORMARGS#>
   #FIELD=command#
   #FIELD=formSubmitted#
   <center>
   #FORMREQUIREDSTRING#<br />
   #FORMERRORSTRING#
   </center>
   <table border="0" width="100%" cellpadding="0" cellspacing="2">
     <tr>
       <td align="right">#LABEL=fname# #REQUIRED=fname#</td>
       <td align="left">#FIELD=fname# #INVALID=fname#</td>
     </tr>
     <tr>
       <td align="right">#LABEL=mname# #REQUIRED=mname#</td>
       <td align="left">#FIELD=mname# #INVALID=mname#</td>
     </tr>
     <tr>
       <td align="right">#LABEL=lname# #REQUIRED=lname#</td>
       <td align="left">#FIELD=lname# #INVALID=lname#</td>
     </tr>
     <tr>
       <td align="right">#LABEL=color# #REQUIRED=color# #INVALID=color#</td>
       <td align="left">#FIELD=color#</td>
     </tr>
     <tr>
       <td align="right" valign="top">#LABEL=color2# #REQUIRED=color2# #INVALID=color2#</td>
       <td align="left">#FIELD=color2#</td>
     </tr>
     <tr>
       <td align="right" valign="top">#LABEL=color3# #REQUIRED=color3# #INVALID=color3#</td>
       <td align="left">#FIELD=color3#</td>
     </tr>
     <tr>
       <td colspan="2">
         <table border="0" width="100%" cellpadding="0" cellspacing="2">
           <tr>
             <td align="right">#LABEL=startDate# #REQUIRED=startDate# #INVALID=startDate#</td>
             <td align="left">#FIELD=startDate#</td>
             <td align="right">#LABEL=endDate# #REQUIRED=endDate# #INVALID=endDate#</td>
             <td align="left">#FIELD=endDate#</td>
           </tr>
         </table>
       </td>
     </tr>
     <tr>
       <td align="right" valign="top">#LABEL=comment# #REQUIRED=comment# #INVALID=comment#</td>
       <td align="left">#FIELD=comment#</td>
     </tr>
     <tr>
       <td colspan="2" align="center"><input type="submit" name="submitForm" value="Submit"></td>
     </tr>
   </table>
 </form>
 END_OF_FORM

 my $doc = HTMLObject::Normal->new();
 my $formObj = HTMLObject::Form->new();

 $doc->setTitle("HTMLObject::Form test script");

 # setup the JavaScript error handler support.
 my $email = "changeme@your.domain";
 $doc->enableJavascriptErrorHandler(email => $email, prgName => "form.cgi", prgVersion => "1.0");

 use vars qw ( %input %clientFileNames %fileContentTypes %serverFileNames );

 HTMLObject::CGILib::ReadParse(*input, \%clientFileNames,
                               \%fileContentTypes, \%serverFileNames);

 my %form = ();  # the variable that holds the generated form data.
 my $displayForm = 0; # signal when we need to display the form.
 my $updateData = 0;  # signal when the data is ok to work with
 if (exists $input{formSubmitted})
 {
   # validate the submitted form
   my $result = $formObj->validate(input => \%input, profile => \%profile);
   if ($formObj->error)
   {
     # display the error message.
     die $formObj->errorMessage;
   }
   if (!$result)
   {
     $displayForm = 1;
   }
   else
   {
     # we have a valid form filled out.
     # update the database and continue, etc.
     # use the valid entries from the $formObj instance.
     $displayForm = 1;
     $updateData = 1;
   }
 }
 else
 {
   $displayForm = 1;
 }

 if ($displayForm)
   %form = $formObj->generate(
            data => \%data, #template => $template,  # uncomment to use the template, for now it is using createTemplate().
            name => "mainForm", action => "",
            method => "post", profile => \%profile,
            order => \@order);
   if ($formObj->error)
   {
     # display the error message
     die $formObj->errorMessage;
   }

 }

 if ($updateData)
 {
   # output the found entries
   $form{body} .= "<br /><br />Valid Entries:<br />\n";
   foreach my $f ($formObj->getValid)
   {
     my $value = $formObj->getValidEntry($f);
     $form{body} .= "$f = '" . (ref($value) eq "ARRAY" ? $doc->formEncode(join(", ", @{$value})) : $doc->formEncode($value)) . "'<br />\n";
   }
   $form{body} .= "<br />Unknown Entries:<br />\n";
   foreach my $f ($formObj->getUnknown)
   {
     my $value = $formObj->getUnknownEntry($f);
     $form{body} .= "$f = '" . (ref($value) eq "ARRAY" ? $doc->formEncode(join(", ", @{$value})) : $doc->formEncode($value)) . "'<br />\n";
   }
 }

 # at this time, print the form into your document.
 $doc->print(%form);

 $doc->display();

 exit 0;

 # returns a hashref with names and values entries that
 # are anonymous arrays containg the pairs of data
 # to put in the options tags for a select box.
 sub getColors
 {
   # do a database lookup, etc.
   my %result = ();
   $result{names} = [ qw( Red Blue Green Yellow Black White ) ];
   $result{values} = [ qw( red blue green yellow black white ) ];

   return \%result;
 }

DESCRIPTION
Form is the HTMLObject::Form class.

We use the Data::FormValidator module to do data validation for us.

Exported FUNCTIONS
NOTE: bool = 1(true), 0(false)

scalar new()
    Creates a new instance of the HTMLObject::Form object.

    See HTMLObject::ErrorBase(3) for the variables and methods that are made available for working with the errors.

    requires:

    returns: object reference

    Variables:

     widgets - HTMLObject::Widgets instance.

     requiredString - string displayed to indicate a form item is
       required.
       defaults to '<span style="color: green;">+</span>'.

     invalidString - string displayed to indicate a form item is invalid.
       defaults to '<span style="color: red;">*</span>'.

     formErrorString - string displayed when an error condition exists
       and you want to inform the user.  defaults to '<span
       style="color: red;">Errors exist in this form!</span> Please check
       theform items marked with %s and fix any errors.'.  %s will
       be substituted with the current value of invalidString.

     formRequiredString - string substituted for #FORMREQUIREDSTRING# to
       let the user know what the +'s mean, etc.  Defaults to ;  %s will
       be substituted with the current value of requiredString.

     formSubmittedVariable - name of the hidden form variable that is
       added to the form so we know when the form has been processed.
       Currently: HTMLObjectFormInternalVariable
       This stores the value of the form being generated so that
       checkboxes, etc. know if they are in an initial state or we are
       processing "our" form submission info.  This comes into play
       when you generate multiple forms on the same screen and you
       just validated one of the forms or another form.

bool isValid(void)
     Returns true or false to indicate if the object is valid.
     The error will be available via errorMessage().

void setRequiredString(required)
     updates requiredString.

     Default string is: '<span style="color: green;">+</span>'

scalar getRequiredString(void)
     returns the value of requiredString.

void setInvalidString(invalid)
     updates invalidString.

     Default string is: '<span style="color:red;">*</span>'

scalar getInvalidString(void)
     returns the value of invalidString.

void setFormErrorString(error)
     updates formErrorString.

     The specified string must contain a %s in it so the invalidString
     value can be substituted in to inform the user what the invalid form
     items are going to be marked with.

     Default string is: '<span style="color: red;">Errors exist in this
     form!</span>  Please check the form items marked with %s and fix any
     errors.'

scalar getFormErrorString(void)
     returns the value of formErrorString.

void setFormRequiredString(required)
     updates formRequiredString.

     The specified string must contain a %s where you want the
     requiredString value to be substituted in so that the user knows
     what the required form items are going to be labeled with.

     Default string is: 'Form items marked with %s are required.'

scalar getFormRequiredString(void)
     returns the value of formRequiredString.

bool required(name, profile)
     required: name - name of form item to check on
               profile - the Data::FormValidator profile

     returns: 1 if name is in profile->{required} array,
              0 otherwise.

bool formContainsUserVisibleFields(data, fields)
     required: data - data hash to check for user visible fields
               fields - string of | seperated form field types
                 that you want to treat as not being User
                 Visible or that are not output in the main
                 form display block by the createTemplate() method.
                 Defaults to "hidden|submit|reset"

               Currently, if you have any form entries defined
               with a -Type != "hidden" or "submit" or "reset",
               then your form is treated as having user visible
               form items.

     returns: 1 if the form contains any user visible form items
              0 otherwise.

bool formRequiresFormSubmittedVariable(data)
     required: data - data hash to check for any form items
                 of the type:
                   checkbox
                   select
                   multi-select
                   select-picker
                 which need the formSubmittedVariable defined
                 and required to work properly.

     returns: 1 if we need the formSubmittedVariable required.
              0 otherwise.

bool formContainsVisibleRequiredItems(data, profile)
     required: data - data hash to check
               profile - profile hash to check

     returns: 1 if there is a required array in the profile and any of the
                elements specified are non-hidden.
              0 otherwise.

hash generate(input, data, profile, template, name, action, method, encoding, readOnly, readOnlyMode, readOnlyArgs, readOnlyHidden, javascript, javascriptIncludes, javascriptReadOnly, onsubmit, order, useFormObjData)
     requires:
       data - hashref of anonymous hashes that defines the form
         items to display and their types.
       profile - hashref containing the information for
         Data::FormValidator to use for validation.
       template - the html form snippet to substitute into.
       name - the name of the form.
       readOnly - boolean, defaults to 0 (false).  Indicates if
         the form should be displayed as editable or readonly.
         See readOnlyMode. readOnlyArgs, javascriptReadOnly.
     optional:
       action - the url to submit the form to.  Can be empty to
         submit back to the current location.
       method - get or post.  DEFAULT = post
       encoding - application/x-www-form-urlencoded,
         multipart/form-data
         DEFAULT = application/x-www-form-urlencoded
       readOnlyMode - "DOM" or "text".  Defaults to "text".
         Only used when readOnly is 1 (true).  When "DOM" is
         specified, we use the DOM attribute 'disabled="true"' to
         indicate the form item is disabled and non-editable.
         (This may not work 100% as Mozilla does not send the
         value of a disabled form item to the server!)

         When "text" is specified, we display the value of each
         form item in a <span></span> block and use the
         readOnlyArgs value to allow class, id and/or style
         attributes to be set on the <span>.

       readOnlyArgs - Only used when readOnlyMode = "text".  This
         is a string that can contain the id="" class="" style=""
         attributes that should be output in the <span> when
         displaying the readonly value of each form item.
       readOnlyHidden - boolean, defaults to 1 (true).  Indicates
         we want readOnly entries, when readOnlyMode = 'text',
         to also be output as <input type="hidden"> tags.

       javascript - string, Allows the form caller to specify a block of
         JavaScript text to be output into the generated forms
         javascript section.

       javascriptIncludes - arrayref, Allows the form caller to specify
         url(s) of JavaScript file(s) that should be included.  Each
         entry in the arrayref, will be added to the javascriptIncludes
         section of the generated form.

       javascriptReadOnly - boolean, Allows the caller to specify if
         JavaScript is to be output when the form is readOnly.
         Defaults to 0 (false).

       onsubmit - string, Allows the form caller to specify javascript
         code to be run in the onsubmit form handler.  The code should
         only return false, if the caller decides that the form should
         not be submitted.  You need to allow processing to continue
         to statements that may be auto added by the generate() method,
         otherwise the form may not be properly processed.  Defaults
         to ''.

       order - arrayref that lists all the form items not of
         -Type = hidden, submit or reset, in the order you
         want them output if using the createTemplate() method.  You do
         not have to specify this array, if not using createTemplate() or
         if you do not care what order they are displayed in.

       useFormObjData - boolean, if the formInternalVariable was specified
         and it doesn't match the formname being generated and you want
         to use the valid,invalid,unknown values from this instance
         of the HTMLObject::Form object then you need to set this to 1.
         Defaults to 0 (false).

     returns:
       hash with values "body", "javascript", "javascriptIncludes",
       "onload", "onunload", "onbeforeunload" that contains the updated
       template string with the form items substituted into it for
       #FORMARGS#, #FIELD=#, #FORMERRORSTRING#, #LABEL=#, #REQUIRED=#,
       #INVALID=#, #FORMREQUIREDSTRING#.
       The resulting hash can be passed directly to print() for
       printing to both the body and javascript sections at once.

       #FORMARGS# - is replaced with the name="" method="" action=""
         and enctype="" arguments to the form.

       #FORMERRORSTRING# - is replaced with the the formErrorString
         string if there were issues with the form and the user
         needs to check things out, or it is removed if there is
         nothing wrong with the form yet.

       #FORMREQUIREDSTRING# - is replaced with the formRequiredString
         string to let the user know what the +'s mean (or whatever
         string is used to denote a required field).  The
         requiredString is substituted into it.

       #FIELD=x# - is replaced with form item x's item type.
       #VALUE=x# - is replaced with form item x's value.
       #LABEL=x# - is replaced with the label for form item x.
       #REQUIRED=x# - is replaced with the requiredString if
         form item x is required, else it is removed.
       #INVALID=x# - is replaced with the invalidString if
         form item x is invalid, else it is removed.
       #H=x# - currently only used by the color & date pickers
         to specify the column headers for the populator
         widget so that it is just the -Label phrase and not
         the linkified -Label.

       The following shortcuts are available:
       #LFRI=x# => #LABEL=x# #FIELD=x# #REQUIRED=x# #INVALID=x#
       #LFI=x#  => #LABEL=x# #FIELD=x# #INVALID=x#
       #LFR=x#  => #LABEL=x# #FIELD=x# #REQUIRED=x#
       #LRIF=x# => #LABEL=x# #REQUIRED=x# #INVALID=x# #FIELD=x#
       #LRI=x#  => #LABEL=x# #REQUIRED=x# #INVALID=x#
       #LIR=x#  => #LABEL=x# #INVALID=x# #REQUIRED=x#
       #LIF=x#  => #LABEL=x# #INVALID=x# #FIELD=x#
       #LIFR=x# => #LABEL=x# #INVALID=x# #FIELD=x# #REQUIRED=x#
       #LF=x#   => #LABEL=x# #FIELD=x#
       #LR=x#   => #LABEL=x# #REQUIRED=x#
       #LI=x#   => #LABEL=x# #INVALID=x#
       #L=x#    => #LABEL=x#
       #IL=x#   => #INVALID=x# #LABEL=x#
       #IF=x#   => #INVALID=x# #FIELD=x#
       #IR=x#   => #INVALID=x# #REQUIRED=x#
       #IFR=x#  => #INVALID=x# #FIELD=x# #REQUIRED=x#
       #ILFR=x# => #INVALID=x# #LABEL=x# #FIELD=x# #REQUIRED=x#
       #I=x#    => #INVALID=x#
       #RL=x#   => #REQUIRED=x# #LABEL=x#
       #RF=x#   => #REQUIRED=x# #FIELD=x#
       #RFI=x#  => #REQUIRED=x# #FIELD=x# #INVALID=x#
       #RLFI=x# => #REQUIRED=x# #LABEL=x# #FIELD=x# #INVALID=x#
       #RI=x#   => #REQUIRED=x# #INVALID=x#
       #R=x#    => #REQUIRED=x#
       #FIR=x#  => #FIELD=x# #INVALID=x# #REQUIRED=x#
       #FRI=x#  => #FIELD=x# #REQUIRED=x# #INVALID=x#
       #FR=x#   => #FIELD=x# #REQUIRED=x#
       #FI=x#   => #FIELD=x# #INVALID=x#
       #F=x#    => #FIELD=x#
       #V=x#    => #VALUE=x#

       The data structure is a hash of hashes with the key as the name
       of the form item being created and their value is a hashref with
       the following attributes defined:

         -Label - (OPTIONAL) The string to replace #LABEL=x# with in
           the template.

         -Type - (REQUIRED) The type of the form item.  Valid values
           are:  hidden, text, textarea, password, button, checkbox,
           file, radio, reset, submit, select, multi-select,
           date-picker, datePicker, color-picker, colorPicker, calculator,
           select-picker, populator, searchBox

         -Value - (OPTIONAL) Allows you to specify the default value
           or the value to return for hidden, text, textarea,
           password, checkbox, radio, reset, submit and select tags.

         -ReadOnly - (OPTIONAL) boolean.  Default is 0 (false).
           Allows you to specify that this form item is to be
           displayed in a read-only form.  If -ReadOnlyMode is not
           specified, then we use the readOnlyMode argument passed
           into generate().  If -ReadOnlyArgs is not specified, then
           we use the readOnlyArgs argument passed into generate().
           If readOnly = 1 (true) in generate, then this value is
           ignored as the form overall is going to be read-only.

         -ReadOnlyMode - (OPTIONAL) same as readOnlyMode argument
           to generate().

         -ReadOnlyArgs - (OPTIONAL) same as readOnlyArgs argument
           to generate().

         -ReadOnlyDisplayType - (OPTIONAL) valid only with -Type =
           select or multi-select with -ReadOnlyMode = text.
           Valid values are "both", "name", or "value" where name
           and value just output the "name" or "value" of the
           currently selected entry, while both outputs
           "name = (value)".  If not specified then we default to
           "name".

         -onload - (OPTIONAL) specifies javascript code to be
           executed by the onload handler for the current form
           item.  Any occurences of 'this.' in the string are
           replaced with the document.formname.itemname values,
           where formname and itemname are taken from the data
           you specified to generate() and the current form item.
           The fixed up string is then appended to the onload
           entry in the hash that is returned to the user.

           The substitution checks are not the most complete.
           If someone can come up with a better check for this.
           which doesn't catch uses of the word this followed
           by a period, please let me know.

         -onloadOnce - (OPTIONAL) boolean.  If 1 (true) and
           -onload has been specified, then only the initial
           generation of the html form will contain the onload
           code, otherwise every instance will have the onload
           code generated.

           If you do not specify it, I assume you meant
           -onloadOnce => 0, so the onload code will be generated
           every time.

         -onunload - (OPTIONAL) specifies javascript code to be
           executed by the onunload handler for the current form
           item.  Any occurences of 'this.' in the string are
           replaced with the document.formname.itemname values,
           where formname and itemname are taken from the data
           you specified to generate() and the current form item.
           The fixed up string is then appended to the onunload
           entry in the hash that is returned to the user.

           The substitution checks are not the most complete.
           If someone can come up with a better check for this.
           which doesn't catch uses of the word this followed
           by a period, please let me know.

         -onunloadOnce - (OPTIONAL) boolean.  If 1 (true) and
           -onunload has been specified, then only the initial
           generation of the html form will contain the onunload
           code, otherwise every instance will have the onunload
           code generated.

           If you do not specify it, I assume you meant
           -onunloadOnce => 0, so the onunload code will be generated
           every time.

         -onbeforeunload - (OPTIONAL) specifies javascript code to be
           executed by the onbeforeunload handler for the current form
           item.  Any occurences of 'this.' in the string are
           replaced with the document.formname.itemname values,
           where formname and itemname are taken from the data
           you specified to generate() and the current form item.
           The fixed up string is then appended to the onbeforeunload
           entry in the hash that is returned to the user.

           The substitution checks are not the most complete.
           If someone can come up with a better check for this.
           which doesn't catch uses of the word this followed
           by a period, please let me know.

         -onbeforeunloadOnce - (OPTIONAL) boolean.  If 1 (true) and
           -onbeforeunload has been specified, then only the initial
           generation of the html form will contain the onbeforeunload
           code, otherwise every instance will have the onbeforeunload
           code generated.

           If you do not specify it, I assume you meant
           -onbeforeunloadOnce => 0, so the onbeforeunload code will be
           generated every time.

         -CreateTemplate - (OPTIONAL) hashref.  This is used only by
           the createTemplate() method to allow the developer to signal
           when special output formatting should be done.  The allowed
           tags in this hashref are:

             -Type - (REQUIRED) string.  Currently -Type supports:
               "header" - causes the form item to span both columns
                 and to be output in a larger bold font.

         ** End of special entries in data **

         You can define other attributes like size, maxlength, etc.
         that are valid html attributes for the type of form item
         you are specifying, so that you can influence the
         characteristics of the generated html.

         If -Type = select or multi-select:

          -Options - (REQUIRED)
            A hashref which must contain 'name' and 'values' entries.
            Each entry in the hash is an arrayref containing the
            values to display as the <option> tags for the select box
            being created.

            names - contains the text to output between the <option>
              and </option> tags.

            values - contains the value to return for the selected
              option.

            labels - optional text values to display for
              select/multi-select boxes.  See the HTML spec for more
              info.

            All arrays must contain the same number of elements.

            There is currently no support for the <optgroup> feature.

          -NoSelectByDefault - (OPTIONAL) boolean.  If 1 (true), then if the
            default value is "" and the form did not provide a selection,
            generate -onload code to cause the selectedIndex to be set
            to -1, so that the select box does not have a default
            selection.  Otherwise, we mark the selected option as before.
            This will be used by the Populator widget to make sure that
            only those form items that were not previously selected are
            cleared.

          If -Type = multi-select:
            -Value can be an arrayref which contains the values of
              the entries to select.

            -Buttons - (OPTIONAL)
              An arrayref of the helper buttons you want created.
              Valid entries are "SelectAll", "All", "ToggleSelect",
              "Toggle" or "None".
              These buttons will be output by JavaScript on the
              same line.

              SelectAll or All = [*]
              ToggleSelect or Toggle = ><
              None = [ ]

         If -Type = radio:

          -Options - (REQUIRED)
            A hashref which must contain 'name' and 'values' entries.
            Each entry in the hash is an arrayref containing the
            values to display as the radio buttons being created..

            names - contains the text to output to the right of the
              <input /> type="radio" tag.

            values - contains the value to return for the selected
              radio entry.

            All arrays must contain the same number of elements.

            DEPRECATED: The radio buttons will still use the labels
              entries instead of the names, if and only if, there are
              no names defined.  This will cause a DEPRECATED warning
              to be generated (at the top of your group of radio
              buttons).  This support will be removed in a future
              version of the code.

         Any options for -Type = color-picker, colorPicker, date-picker,
         datePicker, populator, calculator or searchBox, for the
         HTMLObject::Widget methods, are to be defined with a leading
          - (dash) and no longer must be in the -WidgetOptions hash.
          The -WidgetOptions hash is now deprecated and removed.

         If -Type = color-picker, colorPicker, datePicker or date-picker,
           see the HTMLObject::Widgets->generatePickerCode manpage for the
           info on the extra arguments you can specify to affect the
           generated form items.

           colorPicker is an alias for color-picker.
           datePicker is an alias for date-picker.

           You must specify the -Label value for this widget.

           Valid -entries are:
             -baseUrl
             -windowName
             -onClick
             -onChange
             -width
             -height
             -link
             -class
             -linkClass

             date-picker, datePicker specific entries:
               -year
               -seperator
               -displayPrevNextDateLinks

         If -Type = calculator, then specifying the following -entries
           will allow you to specify if you want the Calculate [=],
           Undo [U] and/or Help [?] buttons to be generated and the
           associated Undo support that is available.
           valid -entries are:
             -calcButton - boolean, defaults to 1 (true) to display = button
             -undoButton - boolean, defaults to 1 (true) to display U button,
               and specify to the calculateFormula() call that undo support
               is requested.  The calculateFormula() javascript function now
               takes the form field to work with and a true/false value to
               specify if the undo code is to be processed.
             -helpLink - boolean, defaults to 1 (true) to display the ?

           If the Calc and Undo buttons are generated, they will be named
           <formItemName>Calc and <formItemName>Undo.

         If -Type = select-picker, then 2 multi-select boxes will be
         generated along with 4 buttons between them that allows the
         user to move selected entries between the select boxes and
         updates 2 hidden strings to represent the assigned and
         un-assigned entries for use on the back-end.  The select
         boxes and buttons will be generated in a table that replaces
         the #FIELD=x# entry.  Do not specify the #LABEL=x# string
         in your template as it will not be used.  You must
         specify the names of the hidden fields and the labels
         to use for the select boxes via the following arguments:

           -assignedName - name of the hidden element that
             will contain the list of assigned items.
           -unassignedName - name of the hidden element that
             will contain the list of unassigned items.
           -assignedLabel - string to label the assigned select box.
           -unassignedLabel - string to label the unassigned select box.
           -seperator - the string to use to seperate the entries
             in the hidden elements.  This can not be empty or just
             whitespace.  Defaults to ',' (a comma).

           -assignedValues - value of the hidden element.
           -unassignedValues - value of the hidden element.
           -assignedOptions - -Options hash for the assigned select box.
           -unassignedOptions - -Options hash for the unassigned select box.

           Make sure you specify the class attribute if you want to
           affect how the generated table looks.

           All strings generated in this widget are wrapped in
           <span style="font-size: smaller;"></span> to make it take
           less realty.  Wrap the #FIELD=x# in a <span> and make the
           font-size: larger, if you want to keep the fontsize normal.

           If you specify the -onload, -onunload, and/or -onbeforeunload
           options for this entry, they will only be passed on to the
           generated select boxes and not any of the buttons.

         If -Type = populator, then based upon the following attributes
           and what you specify, javascript will be generated to manage
           the population of "rows" of form items based upon the selection
           from the select box associated with this populator widget.

           Valid -entries are:

             -rows
             -required
             -options
             -manual
             -optionsTypes
             -customLabel
             -htmlTemplate
             -selectLocation
             -clearPhrase
             -tableClass
             -tableStyle
             -selectClass
             -selectStyle
             -debugLevel
             -numSelectRows
             -displayColumnHeaders
             -columnHeaders
             -displayLabels

           See the HTMLObject::Widgets->generatePopulator man page for
           details on these attributes.

           If manual = 0, then the template, data and profile will
           be updated per the parameters specified.  When validate()
           is called, the widget will be processed so that we have
           the profile entries to work with.

           If manual = 1, then only the javascript code will be
           generated.  It will be upto you to have defined all the
           necessary form items in the data and profile structures
           and to have defined your template layout as desired.

         If -Type = searchBox, see the
           HTMLObject::Widgets->generateSearchBox manpage for the
           info on the extra arguments you can specify to affect the
           generated form items.  You do not need to specify the -form,
           -name, -label or -class attributes.
           If you do want to specify a class value, specify it for the
           form entry overall.

           Valid -entries are:
             -data
             -shareData
             -isSorted
             -isAA
             -displayEmpty
             -displayHelp
             -onblur
             -onfocus

         If -Type = checkbox, then specifying the checked attribute
           = 0 will cause the checkbox to be displayed un-selected.
           If checked = 1, then it is set to be checked by default
           when it is displayed.  The display code should now only
           cause the checkbox to be selected if it defaults and there
           is no input (the submitted hidden flag is not set) or the
           user selected it.

           The read-only support now makes sure that we don't generate
           a <input type="hidden"> tag if the checkbox wasn't selected
           by the user.

void processReadOnlyArgs(hash, tagArgs)
     Update the hashref pointed to by hash after
     splitting tagArgs to extract the different
     arguments the user specified.

bool validate(input, profile, data, dontUntaint, form)
     required:
       input - hashref containing input from the browser
       profile - hashref containing the information for
         Data::FormValidator to use for validation.
       data - hashref of anonymous hashes that defines the form
         items to display and their types as passed into
         the generate() method.

     optional:
       dontUntaint - bool (defaults to 0) that indicates
         the user would like the original behaviour done
         and leave it upto the caller to add the
         untaint_all_constraints to their profile when
         dontUntaint = 1.
       form - scalar (defaults to "") indicates the name of the
         form being validated and is used by the formRequiredVariable
         code to properly populate it if the input didn't have it
         defined and we need it.  (See below for more details.)

     returns:
       0 if form invalid, 1 if form valid, undef if error occured.

     For the form to be valid, there just has to be no invalid or
     missing entries.  At this time we are ignoring the unknown hash.

     Updates the valid, missing, invalid and unknown hashes with the
     results returned by Data::FormValidator.

     The input hash is processed to make sure that any entries that
     have \0 in them, indicating that multiple values were specified
     by the browser, are converted to being an arrayref with the
     values split apart.  This is because Data::FormValidator
     requires the input in this manner.  This means that any code
     working with the input hash after calling validate()
     on it, should not be looking for \0 concatenated
     strings to indicate multiple values were sent in.

     If the data hash contains any of the following then we mark
     the formInternalVariable as being optional:
       checkbox
       select
       multi-select
       select-picker

     If we wanted the formInternalVariable to be in the input hash
     and it wasn't, then we default it to be in the valid hash with
     the value of form that you specify.  See generate() as to why
     this is necessary to make checkboxes, etc. work correctly.

hashref createSelectOptions(data, handler, array)
hashref createSelectOptions(data)
      This creates the -Options hashref suitable for a -Type = select.

      You can call this method just passing in the data and not
      specifying it by name, but then you only get the array
      handling if you pass in a DBI::st object (sth).

      This method does not support being called as a function!

      required:
        data -
          a DBI Statement Handle from a DBIWrapper->read()
          or an arrayref
          or a hashref

      optional:
        handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

        array - boolean.  Indicates how you want the data sth worked
          with when dealing with a DBIWrapper read() result.
          1 = use fetchrow_array, 0 = fetchrow_hash.
          Defaults to 1 (fetchrow_array).

hashref createSelectOptionsSthAsArrayref(sth, handler)
      This creates the -Options hashref suitable for a -Type = select.

      requires: sth - DBI Statement Handle from a DBIWrapper->read().
        The sth will be treated as an array of arrays, where the
        first column = name and the second column = value.  If you
        want it handled differently then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{names} = $a->[0];
      $b{values} = $a->[1]; return %b; }

hashref createSelectOptionsSthAsHashref(sth, handler)
      This creates the -Options hashref suitable for a -Type = select.

      requires: sth - DBI Statement Handle from a DBIWrapper->read().
        The sth will be treated as an array of hashrefs, where the
        columns are named (name and value).  If you
        want it handled differently then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{names} = $a->{name};
      $b{values} = $a->{value}; return %b; }

hashref createSelectOptionsFromArrayref(array, handler)
      This creates the -Options hashref suitable for a -Type = select.

      requires: array - arrayref where each entry is an arrayref where the
        first column = name and the second column = value.  If you
        want it handled differently then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{names} = $a->[0];
      $b{values} = $a->[1]; return %b; }

hashref createSelectOptionsFromArrayrefOfHashrefs(array, handler)
      This creates the -Options hashref suitable for a -Type = select.

      requires: array - arrayref where each entry is an hashref with
        entries of name and value.  If you want it handled differently
        then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{names} = $a->{name};
      $b{values} = $a->{value}; return %b; }

hashref createSelectOptionsFromHashref(hash, handler)
      This creates the -Options hashref suitable for a -Type = select.

      requires: hash - hashref where the keys are the values entry and
        the value for each key is the names value. If you want it
        handled differently then specify your own handler.
        The hash will be sorted by the keys.
      optional: handler - anonymous sub that takes the current key and
        value entries and returns a hash containing (names, values).

      handler defaults to:

      handler => sub { my $a = shift; my $b = shift; my %c = (); $c{names} = $b;
      $c{values} = $a; return %c; }

hashref createRadioOptions(data, handler, array)
hashref createRadioOptions(data)
      This creates the -Options hashref suitable for a -Type = radio.

      You can call this method just passing in the data and not
      specifying it by name, but then you only get the array
      handling if you pass in a DBI::st object (sth).

      This method does not support being called as a function!

      required:
        data -
          a DBI Statement Handle from a DBIWrapper->read()
          or an arrayref
          or a hashref

      optional:
        handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

        array - boolean.  Indicates how you want the data sth worked
          with when dealing with a DBIWrapper read() result.
          1 = use fetchrow_array, 0 = fetchrow_hash.
          Defaults to 1 (fetchrow_array).

hashref createRadioOptionsSthAsArrayref(sth, handler)
      This creates the -Options hashref suitable for a -Type = radio.

      requires: sth - DBI Statement Handle from a DBIWrapper->read().
        The sth will be treated as an array of arrays, where the
        first column = label and the second column = value.  If you
        want it handled differently then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{labels} = $a->[0];
      $b{values} = $a->[1]; return %b; }

hashref createRadioOptionsSthAsHashref(sth, handler)
      This creates the -Options hashref suitable for a -Type = radio.

      requires: sth - DBI Statement Handle from a DBIWrapper->read().
        The sth will be treated as an array of hashrefs, where the
        columns are named (label and value).  If you
        want it handled differently then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (labels, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{labels} = $a->{label};
      $b{values} = $a->{value}; return %b; }

hashref createRadioOptionsFromArrayref(array, handler)
      This creates the -Options hashref suitable for a -Type = radio.

      requires: array - arrayref where each entry is an arrayref where the
        first column = label and the second column = value.  If you
        want it handled differently then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (names, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{labels} = $a->[0];
      $b{values} = $a->[1]; return %b; }

hashref createRadioOptionsFromArrayrefOfHashrefs(array, handler)
      This creates the -Options hashref suitable for a -Type = radio.

      requires: array - arrayref where each entry is an hashref with
        entries of label and value.  If you want it handled differently
        then specify your own handler.
      optional: handler - anonymous sub that takes the current entry
        and returns a hash containing (labels, values).

      handler defaults to:

      handler => sub { my $a = shift; my %b = (); $b{labels} = $a->{label};
      $b{values} = $a->{value}; return %b; }

hashref createRadioOptionsFromHashref(hash, handler)
      This creates the -Options hashref suitable for a -Type = radio.

      requires: hash - hashref where the keys are the values entry and
        the value for each key is the labels value. If you want it
        handled differently then specify your own handler.
        The hash will be sorted by the keys.
      optional: handler - anonymous sub that takes the current key and
        value entries and returns a hash containing (labels, values).

      handler defaults to:

      handler => sub { my $a = shift; my $b = shift; my %c = (); $c{labels} = $b;
      $c{values} = $a; return %c; }

scalar createTemplate(data, profile, class, id, formTag, header, headerClass, footer, footerClass, rowsAlternate, evenRow, oddRow, order)
     Create a default web form template snippet based upon the specified
     data.

     required:
     data - hash of form items that generate() would work with.

     optional:
     profile - the profile hash that generate() would work with.
     class - Specify the table class.  Defaults to ''.
     id - Specify the table id.  Defaults to ''.
     formTag - boolean that specifies if you want the <form> tag generated.
       If 1 (true), then we generate the <form> tag, else we don't.
       Defaults to 1 (true).
       if formTag is false, then hidden, submit and reset form items will
       not be output into the template.
     header - text/html you want output before the table.  Defaults to ''.
     headerClass - string defining the class to apply to the header <p>.
       Default is 'formHeader'.
     footer - text/html you want output after the table.  Defaults to ''.
     footerClass - string defining the class to apply to the footer <p>.
       Default is 'formFooter'.
     rowsAlternate - boolean that indicates if you want alternating table
       rows to display differently.  If 1 (true), then even rows will have
       the evenRow class set, and odd rows will have the oddRow
       class set.  If 0 (false), then no class will be set on the rows.
       Defaults to 1 (true).
     evenRow - string to allow you to define what class should be output
       for the even rows, when rowsAlternate is true.
       Defaults to 'evenRow';
     oddRow - string to allow you to define what class should be output
       for the odd rows, when rowsAlternate is true.
       Defaults to 'oddRow';
     order - arrayref that lists all the form items not of
       -Type = hidden, submit or reset, in the order you
       want them output if using the createTemplate() method.  You do
       not have to specify this array if you do not care what order they
       are displayed in.

     returns the generated form template snippet or undef if an error
     occured.

NOTE
 All data fields are accessible by specifying the object
 and pointing to the data member to be modified on the
 left-hand side of the assignment.
 Ex.  $obj->variable($newValue); or $value = $obj->variable;

 This module based off of the Portal::Base module.

AUTHOR
James A. Pattie (mailto:james@pcxperience.com)

SEE ALSO
perl(1), HTMLObject::Base(3), HTMLObject::Normal(3), HTMLObject::Template(3), Data::FormValidator(3)