NAME

CGI::FormMagick - easily create CGI form-based applications

SYNOPSIS

use CGI::FormMagick;

my $f = new CGI::FormMagick();

# all options available to new()
my $f = new CGI::FormMagick(
    TYPE => FILE,  
    SOURCE => $myxmlfile, 
);

# other types available
my $f = new CGI::FormMagick(TYPE => STRING,  SOURCE => $data );

$f->add_lexicon("fr", { "Yes" => "Oui", "No" => "Non"});

$f->display();

DESCRIPTION

FormMagick is a toolkit for easily building fairly complex form-based web applications. It allows the developer to specify the structure of a multi-page "wizard" style form using XML, then display that form using only a few lines of Perl.

How it works:

You (the developer) provide at least:

  • An XML form description

  • HTML templates for the page headers and footers

And may optionally provide:

  • Translations of strings used in your application, for localisation

  • Validation routines for user input data

  • Routines to run before or after a page of the form is displayed

FormMagick brings them all together to create a full application.

METHODS

new()

The new() method requires no arguments, but may take the following optional arguments (as a hash):

TYPE

Defaults to "FILE". "STRING" is also available, in which case you must specify a SOURCE which is either a literal string or a scalar variable.

SOURCE

Defaults to a filename matching that of your script, only with an extension of .xml (we got this idea from XML::Simple).

previousbutton()

With no arguments, tells you whether the previousbutton will be displayed or not. If you give it a true argument (eg 1) it will set the previous button to be displayed. A false value (eg 0) will set it to not be displayed.

nextbutton()

As for previousbutton, but affects the "Next" button. NOTE: NYI.

finishbutton()

Ditto, NYI.

resetbutton()

Ditto.

startoverlink()

Ditto.

debug()

Turns debugging on/off.

sessiondir()

With no arguments, tells you the directory in which session tokens are kept.

With a true value, set the session directory, in which session tokens are kept. Defaults to session-tokens under the directory in which your CGI script is kept, but you probably want to set it to something outside the web tree.

With a false (but defined) value, resets the session dir to its default value.

display()

The display method displays your form. It takes no arguments.

FORMMAGICK XML TUTORIAL

Form descriptions

The main thing you need to know to use FormMagick is the structure and syntax of FormMagick forms. FormMagick is based on a "wizard" sort of interface, in which one form has many pages, and each page has many fields. This is expressed as a nested hierarchy of XML elements.

The following is an example of how a form is described in XML. More complete examples can be found in the examples/ subdirectory in the CGI::FormMagick distribution.

  <FORM TITLE="My form application" POST-EVENT="submit_order">
    <PAGE NAME="Personal" TITLE="Personal details" />
      <DESCRIPTION>
        Please provide us with the following personal details for 
        our records
      </DESCRIPTION>
      <FIELD ID="firstname" LABEL="Your first name" TYPE="TEXT" 
        VALIDATION="nonblank"/>
      <FIELD ID="lastname" LABEL="Your surname" TYPE="TEXT" 
        VALIDATION="nonblank"/>
      <FIELD ID="username" LABEL="Choose a username" TYPE="TEXT" 
        VALIDATION="username" />
      <FIELD ID="color" LABEL="Choose a color" TYPE="RADIO"
        OPTIONS="'red', 'green', 'blue'"/>
    </PAGE>
    <PAGE NAME="Payment" TITLE="Payment details"
    POST-EVENT="check_credit_card" />
      <DESCRIPTION>
        We need your full credit card details to process your 
        order.  Please fill in all fields.  Your card will be 
        charged within 48 hours.
      </DESCRIPTION>
      <FIELD ID="cardtype" LABEL="Credit card type" TYPE="SELECT" 
        OPTIONS="list_credit_card_types" VALIDATION="credit_card_type"
		MULTIPLE="NO"/>
      <FIELD ID="cardnumber" LABEL="Credit card number" TYPE="TEXT" 
        VALIDATION="credit_card_number"/>
      <FIELD ID="cardexpiry" LABEL="Expiry date (MM/YY)" TYPE="TEXT" 
        VALIDATION="credit_card_expiry"/>
    </PAGE>
    <PAGE NAME="Confirmation" TITLE="Confirmation">
      <FIELD ID="confirm" LABEL="Click here to confirm" TYPE="CHECKBOX"
        VALUE="confirm" CHECKED="0"/>
    </PAGE>
  </FORM>

The XML must comply with the FormMagick DTD (included in the distribution as FormMagick.dtd). A command-line tool to test compliance is planned for a future release.

Here is an explanation of the nesting of elements and the attributes supported by each element.

FORMS

Form sub-elements

A form may contain the following elements:

  • PAGE

Form attributes

The following attributes are supported for forms:

  • PRE-EVENT (a subroutine to run before the form is displayed)

  • POST-EVENT (a subroutine to run after the form is completed)

Example

<FORM PRE-EVENT="setup()" POST-EVENT="submit()>
    <PAGE> ... </PAGE>
    <PAGE> ... </PAGE>
    <PAGE> ... </PAGE>
</FORM>

PAGES

Page sub-elements

A page may contain the following sub-elements:

  • DESCRIPTION

  • FIELD

Page attributes

The following attributes are supported for pages:

  • NAME (required)

Example

<PAGE NAME="RoomType" POST-EVENT="check_availability">
  <DESCRIPTION>
    Please provide us with details of your preferred room.
  </DESCRIPTION>
  <FIELD> ... </FIELD>
  <FIELD> ... </FIELD>
  <FIELD> ... </FIELD>
</PAGE>

FIELDS

Fields are the most important part of the form definition. Several types of HTML fields are supported, and each one has various attributes associated with it.

Field types

You can specify the type of HTML field to be generated using the TYPE attribute:

<FIELD TYPE="...">

The following field types are supported:

TEXT

A plain text field. You may optionally use the SIZE attribute to modify the size of the field displayed. To restrict the length of data entered by the user, use the maxlength() validation routine.

SELECT

A dropdown list. You must provide the OPTIONS attribute to specify the contents of the list (see below for the format of this attribute). If you set the MULTIPLE attribute to 1, multiple selections will be enabled. The optional SIZE attribute sets the number of items displayed at once.

RADIO

Radio buttons allow users to choose one item from a group. This field type requires the OPTIONS attribute (as for SELECT, above).

CHECKBOX

This field type provides a simple check box for yes/no questions. The CHECKED attribute is optional, but if set to 1 will make the checkbox checked by default.

PASSWORD

The PASSWORD field type is like a TEXT field, but obscures the data typed in by the user.

FILE

This field type allows the upload of a file by the user.

Field sub-elements

The following elements may be nested within a field:

  • LABEL (a short description; required)

  • DESCRIPTION (a more verbose description; optional)

Other field attributes

Fields must ALWAYS have a TYPE (described in the previous section) and an ID attribute, which is a unique name for the field. Each type of field may have additional required attributes, and may support other optional attributes.

Here is a list of optional attributes for fields:

VALUE

A default value to fill in; see below for more information on the format of this field.

VALIDATION

a list of validation functions; see CGI::FormMagick::Validator for more information on this subject.

VALIDATION-ERROR-MESSAGE

an error message to present to the user if validation fails. CGI::FormMagick::Validator provides one by default, but you may prefer to override it.

OPTIONS

A list of options required for a SELECT list or RADIO buttons; see below for more information on the format of this attribute.

CHECKED

For CHECKBOX fields, used to make the box checked by default. Defaults to 0.

MULTIPLE

For SELECT fields, used to allow the user to select more than one value.

SIZE

For SELECT fields, height; for TEXT and TEXTAREA fields, length.

Notes on parsing of VALUE attribute

If your VALUE attribute ends in parens, it'll be taken as a subroutine to run. Otherwise, it'll just be taken as a literal.

This will be literal:

VALUE="username"

This will run a subroutine:

VALUE="get_username()"

The subroutine will be passed the CGI object as an argument, so you can use the CGI params to help you generate the value you need.

Your subroutine should return a string containing the value you want.

Notes on parsing of OPTIONS attribute

The OPTIONS attribute has automagical Do What I Mean (DWIM) abilities. You can give it a value which looks like a Perl list, a Perl hash, or a subroutine name. For instance:

OPTIONS="'red', 'green', 'blue'"

OPTIONS="'ff0000' => 'red', '00ff00' => 'green', '0000ff' => 'blue'"

OPTIONS="get_colors()"

How it works is that FormMagick looks for the => operator, and if it finds it it evals the OPTIONS string and assigns the result to a hash. If it finds a comma (but no little => arrows) it figures it's a list, and evals it and assigns the results to an array. Otherwise, it tries to interpret what's there as the name of a subroutine in the scope of the script that called FormMagick.

A few gotchas to look out for:

  • Make sure you quote strings in lists and hashes. "red,blue,green" will fail (silently) because of the barewords.

  • Single-element lists ("red") will fail because the DWIM parsing doesn't find a comma there and treats it as the name of a subroutine. But then, a single-element radio button group or select dropdown is pretty meaningless anyway, so why would you do that?

  • Arrays will result in options being sorted in the same order they were listed. Hashes will be sorted by value using the Perl's cmp() function (ASCIIbetical sort, in other words).

  • An anti-gotcha: subroutine names do not require the parens on them. "get_colors" and "get_colors()" will work the same.

INTERNAL, DEVELOPER-ONLY ROUTINES

The following routines are used internally by FormMagick and are documented here as a developers' reference. If you are using FormMagick to develop web applications, you can skip this section entirely.

magic_wherenext

We allow FM users to set the wherenext param explicitly in their code, to do branching of program logic. This routine checks to see if they have a magic wherenext param and returns it. Gives undef if it's not set.

prepare_for_next_page

This does all the things needed before going on to the next page. Specifically, it validates the data from this page, and then if validation was successful it puts the current page onto the page stack and then sets page_number to whatever page we should be visiting next.

$fm->cleanup_checkboxes()

Checkbox params only get passed around if they're checked. An unchecked box doesn't send "checkbox=0" ... no, it just completely fails to send anything at all. This is a PITA, as it's impossible to distinguish an explicity unchecked box from one that never got seen at all.

This subroutine is intended to clean up the mess, by checking the checkboxes that were expected on the current page against what it actually saw on the CGI parameters, and explicitly setting any missing ones to 0.

$fm->commit_session()

Commits a session's details to disk, in the same way as CGI::Persistent.

get_option_labels_and_values ($fieldinfo)

returns labels and values for fields that require them, by running a subroutine or whatever else is needed. Returns a hashref containing:

{ labels => \@options_labels, $vals => \@option_values }

parse_options_attribute($options_field)

parses the OPTIONS attibute from a FIELD element and returns a reference to either a hash or an array containing the relevant data to fill in a SELECT box or a RADIO group.

do_external_routine($self, $routine, @optional_args)

Runs an external routine, for whatever purpose (filling in default values of fields, validation, etc). If anything is in @optional_args, the routine is called using those. If @optional_args is ommitted, then $self->{cgi} is passed. Returns the return value of the routine, or undef on failure. Also emits a warning (to your webserver's error log, most likely) if it can't run the routine.

The routine is always called in the package which called FormMagick (usually main::, but possibly something else).

The CGI object is passed to your routine, so you can do stuff like $cgi->param("foo") to it to find out CGI parameters and so on.

SEE ALSO

CGI::FormMagick::Utils

CGI::FormMagick::Events

CGI::FormMagick::Setup

CGI::FormMagick::L10N

CGI::FormMagick::Validator

CGI::FormMagick::FAQ

BUGS

The VALIDATION attribute must be very carefully formatted, with spaces between the names of routines but not between the arguments to a routine. See description above.

AUTHOR

Kirrily "Skud" Robert <skud@infotrope.net>

Contributors:

Shane R. Landrum <slandrum@turing.csc.smith.edu>

James Ramirez <jamesr@cogs.susx.ac.uk>

More information about FormMagick may be found at http://sourceforge.net/projects/formmagick/