HTML::FormEngine - create,validate and control html/xhtml forms

Perl Version
5.004

Standard Modules
none

Nonstandard Modules
Clone 0.13 Hash::Merge 0.07 Locale::gettext 1.01 Date::Pcalc 1.2

Example Code
#!/usr/bin/perl use strict; use CGI; use HTML::FormEngine; #use POSIX; # for setlocale #setlocale(LC_MESSAGES, 'german'); # for german error messages my $q = new CGI; print $q->header; my $Form = HTML::FormEngine->new(scalar $q->Vars); my @form = ( { templ => 'select', NAME => 'Salutation', OPTION => ['mr.','mrs.'], }, { SIZE => 10, MAXLEN => 20, SUBTITLE => [['', '&nbsp;/&nbsp;']], NAME => [['forname', 'surname']], TITLE => 'For- / Surname ', ERROR_IN => 'not_null' }, { MAXLEN => 30, NAME => 'Email', ERROR => ['not_null', 'rfc822'] # rfc822 defines the email address standard }, { templ => 'radio', TITLE => 'Subscribe to newsletter?', NAME => 'newsletter', OPT_VAL => [[1, 2, 3]], OPTION => [['Yes', 'No', 'Perhaps']], VALUE => 1 }, { templ => 'check', OPTION => 'I agree to the terms of condition!', NAME => "agree", TITLE => '', ERROR => sub{ return("you've to agree!") if(! shift); } } ); $Form->conf(\@form); $Form->make(); print $q->start_html('FormEngine example: Registration'); if($Form->ok){ $Form->clear(); print "<center>You've successfully subscribed!</center><br>"; } print $Form->get, $q->end_html;

Example Output
This output is produced by FormEngine when using the example code and no data was submitted: <form action="/cgi-bin/FormEngine/registration.cgi" method="post"> <table border=0 align="center" summary=""> <tr> <td valign="top">Salutation</td> <td> <select size="1" name="Salutation"> <option value="mr.">mr.</option> <option value="mrs.">mrs.</option> </select> </td> <td style="color:#FF0000" valign="bottom"></td> </tr> <tr> <td valign="top">For- / Surname </td> <td> <table border=0 cellspacing=0 cellpadding=0 summary=""> <tr> <td valign="top"> <table border=0 cellspacing=0 cellpadding=0 summary=""> <tr> <td></td> <td> <input type="text" value="" name="forname" maxlength="20" size="10" /><br/> </td> </tr> <tr><td></td><td style="color:#FF0000"></td></tr> </table> </td> <td valign="top"> <table border=0 cellspacing=0 cellpadding=0 summary=""> <tr> <td>&nbsp;/&nbsp;</td> <td> <input type="" value="" name="surname" maxlength="20" size="10" /><br/> </td> </tr> <tr><td></td><td style="color:#FF0000"></td></tr> </table> </td> </tr> </table> </td> <td style="color:#FF0000" valign="bottom"></td> </tr> <tr> <td valign="top">Email</td> <td> <table border=0 cellspacing=0 cellpadding=0 summary=""> <tr> <td valign="top"> <table border=0 cellspacing=0 cellpadding=0 summary=""> <tr> <td></td> <td> <input type="text" value="" name="Email" maxlength="30" size="20" /><br/> </td> </tr> <tr><td></td><td style="color:#FF0000"></td></tr> </table> </td> </tr> </table> </td> <td style="color:#FF0000" valign="bottom"></td> </tr> <tr> <td valign="top">Subscribe to newsletter?</td> <td> <table border=0 summary=""> <tr> <td><input type="radio" value="1" name="newsletter" checked />Yes</td> <td><input type="radio" value="2" name="newsletter" />No</td> <td><input type="radio" value="3" name="newsletter" />Perhaps</td> </tr> </table> </td> <td style="color:#FF0000" valign="bottom"></td> </tr> <tr> <td valign="top"></td> <td> <table summary=""> <tr> <td> <input type="checkbox" value="I agree to the terms of condition!" name="agree" /> I agree to the terms of condition! <font style="color:#FF0000"></font> </td> </tr> </table> </td> <td valign="bottom" style="color:#FF0000"></td> </tr> <tr> <td align="right" colspan=3> <input type="submit" value="Ok" name="FormEngine" /> </td> </tr> </table> </form> FormEngine.pm is a Perl 5 object class which provides an api for managing html/xhtml forms. FormEngine has its own, very flexible template system for defining form skins. A default skin is provided, it should be sufficent in most cases, but making your own isn't difficult (please send them to me!). FormEngine also provides a set of functions for checking the form input, here too it is very easy to define your own check methods or to adapt the given. gettext is used for international error message support. So use "setlocale(LC_MESSAGES, 'german')" if you want to have german error messages (there isn't support for any other language yet, but it shouldn't be difficult to translate the .po file, don't hesitate!). Another usefull feature is the "confirm" method, which forces the user to read through his input once again before submitting it. FormEngine is designed to make extension writing an easy task! Start with calling the "new" method, it will return an FormEngine object. As argument you can pass a reference to an hash, which should contain the input values (calling "set_input" is also possible). Now you should define an array or hash which contains the form configuration. Pass a reference to that hash or array to "conf". Now call "make", this will generate the html code. Next you should use "ok" to check if the form was submitted and all input values are correct. If this is the case, you should display a success message and call "get_input(fieldname)" for getting the value of a certain field and e.g. write it in a database. Else you should call "get" (which will return the html form code) or "print" which will directly print the form. If you want the form to be always displayed, you can use "clear" to empty it (resp. display the defaults) when the transmission was successfull. The easiest way to define your form is to create an array of hash references: my @form = ( { templ => 'select', NAME => 'Salutation', OPTION => ['mr.','mrs.'], }, { SIZE => 10, MAXLEN => 20, SUBTITLE => [['', '&nbsp;/&nbsp;']], NAME => [['forname', 'surname']], TITLE => 'For- / Surname ', ERROR_IN => 'not_null' }, { MAXLEN => 30, NAME => 'Email', ERROR => ['not_null', 'rfc822'] # rfc822 defines the email address standard }, { templ => 'radio', TITLE => 'Subscribe to newsletter?', NAME => 'newsletter', OPT_VAL => [[1, 2, 3]], OPTION => [['Yes', 'No', 'Perhaps']], VALUE => 1 }, { templ => 'check', OPTION => 'I agree to the terms of condition!', NAME => "agree", TITLE => '', ERROR => sub{ return("you've to agree!") if(! shift); } } ); This is taken out of the example above. The templ key defines the field type (resp. template), the capital written keys are explained below. If templ is not defined, it is expected to be "text". You then pass a reference to that array to the "conf" method like this: $Form->conf(\@form); Another possibility is to define a hash of hash references and pass a reference on that to "conf". This is seldom needed, but has the advantage that you can define low level variables: my %form = ( METHOD => 'get', FORMNAME => 'myform', SUBMIT => 'Yea! I want that!', 'sub' => [ # Here you place your form definition (see above) ] ); $Form->conf(\%form); The meaning of the keys is explained below. You can call "set_main_vars" for setting low level (main) variables as well, so the hash notation isn't necessary.

The Default Skin (FormEngine)
Normally it is no problem to call the same template with the same name several times in one form (except "check_uniq"), but it might cause problems if you use the same name in diffrent templates. The following field types are known by the default skin: text - text input field(s), one row textarea - text input field(s), several rows radio - selection list in terms of buttons (one can be selected) select - selection list in terms of a pull down menu (one can be selected) check - selection list in terms of buttons (several can be selected) Using this template, you must give every option a diffrent name: option1, option2 ... The Advantage is, that it enables you to use the same option-list in one form several times. You might need that if you e.g. want to administrate several users at once. check_uniq - selection list in terms of buttons (several can be selected) Using this template, you only have to give one name for all options, but you can't use this name again in the form. Normally, this doesn't matter and so you'll use this template instaed of "check". hidden - invisible field(s), can be used for passing data print - this template simply prints out the given value button - displays a button emb_text - text field, designed to be embedded (nested) in another template (see below)

Variables
Note that if you don't use the default skin, things might be diffrent. But mostly only the layout changes. A skin which doesn't fit to the following conventiones should have its own documentation. These Variables are always available: NAME - the form fields name (this must be passed to "get_input" for getting the complying value) TITLE - the displayed title of the field, by default the value of NAME VALUE - the default (or initial) value of the field ERROR - accepts name of an FormEngine check routine (see Config.pm and Checks.pm), an anonymous function or an reference to a named method. If an array reference is passed, a list of the above mentioned values is expected. FormEngine will then call these routines one after another until an errormessage is returned or the end of the list is reached. These variables are available for the "text" and "emb_text" field type only: SIZE - the physical length of the field (in characters) [default: 20] MAXLEN - max. count of characters that can be put into the field [default: no limit] TYPE - if set to password for each character a * is printed (instead of the character) [default: text] These variables are available for selection field types ("radio", "select", "check") only: OPTION - accepts an reference to an array with options OPT_VAL - accepts an reference to an array with values for the options (by default the value of OPTION is used) These variables are available for the "textarea" field type only: COLS - the width of the text input area [default: 27] ROWS - the height of the text input area [default: 10] These variables are available for the "button" field type only: TYPE - can be 'button', 'submit' or 'reset' [default: 'button'] These variables are so called main variables they can be set by using the hash notation (see above) or by calling "set_main_vars" (see below): ACTION - the url of the page to which the form data should be submitted [default: $ENV{REQUEST_URI}, that means: the script calls itself]. Normally it doesn't make sense to change this value, but when you use mod_perl, you should set it to '$r->uri'. METHOD - can be 'post' (transmit the data in HTTP header) or 'get' (transmit the data by appeding it to the url) [default: post]. SUBMIT - the text that should be displayed on the submit button [default: Ok] FORMNAME - the string by which this form should be identified [default: FormEngine]. You must change this if you have more than one FormEngine-made form on a page. Else FormEngine won't be able to distinguish which form was submitted. Note: only NAME must be set, all other variables are optional.

Methods For Creating Forms
new ([ HASHREF ]) This method is the constructor. It returns an FormEngine object. You can pass the user input in a hash reference to it, but you can use "set_input" as well. set_input ( HASHREF ) To this method you must pass a reference to a hash with input values. You can pass this hash reference to the constructor ("new") as well, then you don't need this function. If you use mod_perl you can get this reference by calling 'scalar $m->request_args'. If you use CGI.pm you get it by calling 'scalar $q->Vars'. conf ( FORMCONF ) You have to pass the configuration of your form as array or hash reference (see above). set_main_var ( HASHREF ) You can use this method for setting the values of the main template variables (e.g. SUBMIT). Another possibility to do that is using the hash notation when configuring the form (see above). clear If the form was submitted, this method simply calls "set_use_input" and "set_error_chk". It sets both to false. If make was already called, it calls it again, so that no input is used and no error check is done. set_error_chk ( VALUE ) Sets wether the error handler should be called or not. Default is true (1). set_use_input ( VALUE ) Sets wether the given input should be displayed in the form fields or not. Default is true (1). make Creates the html/xhtml output, but doesn't return it (see "get" and "print" below). Every method call which influences this output must be called before calling make! print Sends the html/xhtml output directly to STDOUT. "make" must be called first! get Returns the html/xhtml form code in a string. "make" must be called first! ok Returns true (1) if the form was submitted and no errors were found! Else it returns false (0). This method simply calls "is_submitted" and "get_error_count". get_error_count Returns the count of errors which where found by the error handler. is_submitted Returns true (1) if the form was submitted, false (0) if not. get_input ( FIELDNAME ) Returns the input value of the corresponding field. confirm ( [CONFIRMMSG] ) Calling this method will print the users input data and ask him to klick 'Ok' or 'Cancel'. 'Ok' will submit the data once again and then "is_confirmed" will return true (1). 'Cancel' will display the form, so that the user can change the data. By default the message defined in Config.pm will be displayed, but you can also pass your own text. is_confirmed This method returns true (1) when the form input was affirmed by the user (see "confirm" method).

Methods For Configuring FormEngine
set_skin ( NAME ) If you want to use an alternate skin, call this method. You have to pass the name of an registered skin (see Config.pm). add_skin ( HASHREF ) If you only want to add or overwrite some templates of the current skin, call this method. You have to pass a reference to the hash which stores these templates. set_default ( HASHREF ) By using this method, you completly reset the default values of the template variables. You have to pass a reference to the hash which stores the new settings. Look at Config.pm to see the current settings. In most cases you better call "add_default". add_default ( HASHREF ) Pass a hash reference to this method for adding or overwriting default values. Look at Config.pm for more information. set_handler ( HASHREF ) This method resets the handler settings. Look at Config.pm for the default settings. If you just want to add or overwrite a handler setting, use "add_handler" (see below). add_handler ( HASHREF ) This method adds or overwrites template handlers. Look at Config.pm and Handler.pm for more information. add_checks ( HASHREF ) This method temporary adds or overwrites check routines. Look at Config.pm and Checks.pm for more information. set_confirm_skin ( HASHREF ) The confirm method replaces the form-templates with confirm-templates. The default replacements are defined in Config.pm. For Example the "main" template is replaced by the "confirm" template. The defaults are still taken from the original templates. The special key default defines the template, which will be used when for a certain form-template no confirm-template was defined. So the referenced hash, which you must pass to this method, has to look like this: FORM_TEMPLATE_NAME => CONFIRM_TEMPLATE_NAME, FORM_TEMPLATE_NAME => CONFIRM_TEMPLATE_NAME, . . . add_confirm_skin ( HASHREF ) With this method, you can update the current confirm skin settings. For more information see above. set_confirm_handler ( HASHREF ) Sometimes, it might make sense to call a special confirm handler instead of the really referenced one. So the referenced hash must assign a handler method to a handler- or template name. add_confirm_handler ( HASHREF ) With this method, you can update the current confirm handler settings. For more information see above.

Debug Methods
set_debug ( DEBUGLEVEL ) Sets the debug level. The higher the value the more output is printed. get_method Returns the value of mains METHOD variable (should be get or post). get_formname Returns the value of mains FORMNAME variable. If you have several FormEngine forms on one page, these forms mustn't have the same FORMNAME value! You can set it with "set_main_vars". get_conf Returns a reference to a hash with the current form configuration. Changing this hash DOESN'T influence the configuration, because it is just a copy. print_conf ( HASHREF ) Prints the given form configuration to STDOUT.

Special Features
nesting templates There are two ways how you can nest templates. The first one is to put a handler call in the template definition. This is a less flexible solution, but it might be very usefull. See the POD of Skin.pm for more information. The second and flexible way is, to assign a handler call to a template variable (see the POD of Skin.pm for more information about handler calls). A good example for this way is hobbies.cgi. There you have a option called other and an input field to put in the name of this alternative hobby. When you look at the form definition below, you see that the value of the OPTION variable of this option is simply <&emb_text&>, this is a handler call. So the handler is called and its return value (in this case the processed emb_text template) is assigned to the variable. The form definition of hobbies.cgi: my @form = ( { templ => 'check', NAME => [['hobbies1','hobbies2'],['hobbies3','hobbies4'],['hobbies5','hobbies6'],'hobbies7','hobbies8'], TITLE => 'hobbies', OPTION => [['Parachute Jumping', 'Playing Video Games'], ['Doing Nothing', 'Soak'], ['Head Banging', 'Cat Hunting'], "Don't Know", '<&emb_text&>'], OPT_VAL => [[1,2], [3,4], [5,6], 7, 8], VALUE => [1,2,7], 'sub' => {'emb_text' => {'NAME' => 'Other', 'VALUE' => ''}}, ERROR => sub{if(shift eq 4) { return "That's not a faithfull hobby!" }} } ); If you have a closer look at the form definition above, you'll recognize that there is a key called 'sub'. With help of this key you can define the variables of the nested templates. If the nested templates don't use the same variable names as their parents, you don't need that, because then you can assign these variables on the same level with the parents template variables.

Modify A Skin
To modify the current skin, use the method "add_skin" (see above). You should have a look at Skin.pm and read its POD.

Write A New Skin
Have a look at Skin.pm for this task. You can easily change the layout by copying the skin hash, fitting the html code to your needs and then using "set_skin" (see above) to overwrite the default. Please send me your skins.

Write A Handler
Look at the POD of Handler.pm. You can use "add_handler" to add your handler temporary, edit Config.pm to make it persistent.

Write A Check Routine
The design of a check routine is explained in the POD of Checks.pm. You can easily refer to it by reference or even define it in line as an anonymous function (see the ERROR template variable). If your new written routine is of general usage, you should make it part of FormEngine by placing it in Checks.pm and refering to it in Config.pm. Please send me such methods! Have a look at ... the POD of Skin.pm for information about FormEngines template system. the POD of Handler.pm for information about FormEngines handler architecture. the POD of Checks.pm for information about FormEngines check methods. Config.pm for the default configuration. Send bug reports to: moritz@freesources.org Thanks! (c) 2003, Moritz Sinn. This module is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License (see http://www.gnu.org/licenses/gpl.txt) as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This module is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. I am always interested in knowing how my work helps others, so if you put this module to use in any of your own code then please send me the URL. Also, if you make modifications to the module because it doesn't work the way you need, please send me a copy so that I can roll desirable changes into the main release. Address comments, suggestions, and bug reports to moritz@freesources.org. Special thanks go to Darren Duncan. His HTML::FormTemplate module gave me a good example how to write a documentation. There are several similarities between HTML::FormEngine and HTML::FormTemplate, we both came to an related API design, the internal processes are completly diffrent. It wasn't my purpose to have these api design decisions in common with HTML::FormTemplate. When i wrote the php version of HTML::FormEngine, i didn't know anything about HTML::FormTemplate. Later i just ported this php class to perl. I think we both came to an likewise API because its just the most obvious solution. Features which FormEngine has and FormTemplate hasn't: Skinsystem More flexible validation and error message report Common checking methods are predefined, others can be added on the fly Internationalization with help of gettext Adaptation through Config.pm Due to the handler system and the modular design FormEngine can easily be extended A flexible set of methods to let the user confirm his input Features which FormTemplate has and FormEngine hasn't: This list will be filled in later. (I ask the author to send me some notes, he told me he'll do so at opportunity.) HTML::FormTemplate by Darren Duncan