NAME

HTML::FormHandler - form handler written in Moose

SYNOPSIS

An example of a form class:

package MyApp::Form::User;

use HTML::FormHandler::Moose;
extends 'HTML::FormHandler::Model::DBIC';

has '+item_class' => ( default => 'User' );

has_field 'name' => ( type => 'Text' );
has_field 'age' => ( type => 'PosInteger', apply => [ 'MinimumAge' ] );
has_field 'birthdate' => ( type => 'DateTime' );
has_field 'hobbies' => ( type => 'Multiple' );
has_field 'address' => ( type => 'Text' );
has_field 'city' => ( type => 'Text' );
has_field 'state' => ( type => 'Select' );
has_field 'email' => ( type => 'Email' );

has '+dependency' => ( default => sub {
      [ ['address', 'city', 'state'], ]
   }
);

subtype 'MinimumAge'
   => as 'Int'
   => where { $_ > 13 }
   => message { "You are not old enough to register" };

no HTML::FormHandler::Moose;
1;

An example of a Catalyst controller that uses an HTML::FormHandler form to update a 'Book' record:

package MyApp::Controller::Book;
BEGIN {
   use Moose;
   extends 'Catalyst::Controller';
}
use MyApp::Form::Book;
has 'edit_form' => ( isa => 'MyApp::Form::Book', is => 'rw',
    lazy => 1, default => sub { MyApp::Form::Book->new } );

sub book_base : Chained PathPart('book') CaptureArgs(0)
{
   my ( $self, $c ) = @_;
   # setup
}
sub item : Chained('book_base') PathPart('') CaptureArgs(1)
{
   my ( $self, $c, $book_id ) = @_;
   $c->stash( book => $c->model('DB::Book')->find($book_id) );
}
sub edit : Chained('item') PathPart('edit') Args(0)
{
   my ( $self, $c ) = @_;

   $c->stash( form => $self->edit_form, template => 'book/form.tt' );
   return unless $self->edit_form->process( item => $c->stash->{book},
      params => $c->req->parameters );
   $c->res->redirect( $c->uri_for('list') );
}

The example above creates the form as a persistent part of the application with the Moose <C has 'edit_form' > declaration. If you prefer, it also works fine to create the form on each request:

my $form = MyApp::Form->new;
my $validated = $form->update( item => $book, params => $params );

or, for a non-database form:

 my $form = MyApp::Form->new;
 my $validated = $form->validate( $params );

A dynamic form may be created in a controller using the field_list attribute to set fields:

my $form = HTML::FormHandler->new(
    item => $user,
    field_list => {
        fields => {
           first_name => 'Text',
           last_name => 'Text' 
        },
    },
);

DESCRIPTION

HTML::FormHandler allows you to define HTML form fields and validators. It can be used for both database and non-database forms, and will automatically update or create rows in a database.

One of its goals is to keep the controller interface as simple as possible, and to minimize the duplication of code. In most cases, interfacing your controller to your form is only a few lines of code.

With FormHandler you'll never spend hours trying to figure out how to make a simple HTML change that would take one minute by hand. Because you CAN do it by hand. Or you can automate HTML generation as much as you want, with template widgets or pure Perl rendering classes, and stay completely in control of what, where, and how much is done automatically.

You can split the pieces of your forms up into logical parts and compose complete forms from FormHandler classes, roles, fields, collections of validations, transformations and Moose type constraints. You can write custom methods to process forms, add any attribute you like, use Moose before/after/around. FormHandler forms are Perl classes, so there's a lot of flexibility in what you can do. See "apply" in HTML::FormHandler::Field for more info.

The HTML::FormHandler module is documented here. For more extensive documentation on use and a tutorial, see the manual at HTML::FormHandler::Manual.

HTML::FormHandler does not provide a complex HTML generating facility, but a simple, sample rendering role is provided by HTML::FormHandler::Render::Simple, which will output HTML formatted strings for a field or a form. There are also sample Template Toolkit widget files in the example, documented at HTML::FormHandler::Manual::Templates.

The typical application for FormHandler would be in a Catalyst, DBIx::Class, Template Toolkit web application, but use is not limited to that.

ATTRIBUTES

has_field

See HTML::FormHandler::Manual::Intro for a description of the 'has_field' field declaration syntax.

has_field 'title' => ( type => 'Text', required => 1 );

field_list

A hashref of field definitions.

The possible keys in the field_list hashref are:

required
optional
fields
auto_required
auto_optional

Example of a field_list hashref:

my $field_list => {
    fields => [
        field_one => {
           type => 'Text',
           required => 1
        },
        field_two => 'Text,
     ],
 }; 

For the "auto" field_list keys, provide a list of field names. The field types will be determined by calling 'guess_field_type' in the model. For the DBIC model, the schema must be available for this to work.

auto_required => ['name', 'age', 'sex', 'birthdate'],
auto_optional => ['hobbies', 'address', 'city', 'state'],

fields

The field definitions as built from the field_list and the 'has_field' declarations. This is a MooseX::AttributeHelpers::Collection::Array, and provides clear_fields, add_field, remove_last_field, num_fields, has_fields, and set_field_at methods.

name

The form's name. Useful for multiple forms. It used to construct the default 'id' for fields, and is used for the HTML field name when 'html_prefix' is set. The default is "form" + a one to three digit random number.

In your form:

has '+name' => ( default => 'userform' );

init_object

If an 'init_object' is supplied on form creation, it will be used instead of the 'item' to pre-populate the values in the form. This can be useful when populating a form from default values stored in a similar but different object than the one the form is creating. The 'init_object' should be either a hash or the same type of object that the model uses (a DBIx::Class row for the DBIC model).

See 'init_from_object' method

ran_validation

Flag to indicate that validation has been run. This flag will be false when the form is initially loaded and displayed, since validation is not run until FormHandler has params to validate. It normally shouldn't be necessary for users to check this flag.

validated

Flag that indicates if form has been validated. If you're using the 'update', 'process', or 'validate' methods, you many not need to use this flag, since the return value of those methods is this flag. You might want to use this flag if you've written a method to replace 'update' or 'process', or you're doing something in between update/validate, such as set a stash key.

$form->update( ... );
$c->stash->{...} = ...;
return unless $form->validated;

verbose

Flag to print out additional diagnostic information. See 'dump_fields' and 'dump_validated'.

field_name_space

Use to set the name space used to locate fields that start with a "+", as: "+MetaText". Fields without a "+" are loaded from the "HTML::FormHandler::Field" name space. If 'field_name_space' is not set, then field types with a "+" must be the complete package name.

num_errors

Total number of fields with errors. Set by the validation routine.

user_data

Place to store user data

ctx

Place to store application context

language_handle, build_language_handle

Holds a Local::Maketext language handle

The builder for this attribute gets the Locale::Maketext language handle from the environment variable $ENV{LANGUAGE_HANDLE}, or creates a default language handler using HTML::FormHandler::I18N

field_counter

Used for numbering fields. Used by set_order method in Field.pm. Useful in templates.

html_prefix

Flag to indicate that the form name is used as a prefix for fields in an HTML form. Useful for multiple forms on the same HTML page. The prefix is stripped off of the fields before creating the internal field name, and added back in when returning a parameter hash from the 'fif' method. For example, the field name in the HTML form could be "book.borrower", and the field name in the FormHandler form (and the database column) would be just "borrower".

has '+name' => ( default => 'book' );
has '+html_prefix' => ( default => 1 );

Also see the Field attribute "prename", a convenience function which will return the form name + "." + field name

If you want to use some other pattern to create the HTML field name, you could subclass 'munge_params'.

active_column

The column in tables used for select list that marks an option 'active'. You might use this if all of your tables have the same 'active' column name, instead of setting this for each field.

http_method

For storing 'post' or 'get'

action

Store the form 'action' on submission. No default value.

submit

Store form submit field info. No default value.

params

Stores HTTP parameters. Also: set_param, get_param, clear_params, delete_param, has_params from Moose 'Collection::Hash' metaclass. The 'munge_params' method is a trigger called whenever params is set.

The 'set_param' method could be used to add additional field input that doesn't come from the HTML form, similar to a hidden field:

my $form = MyApp::Form->new( $item, $params );
$form->set_param('comment', 'updated by edit form');
return unless $form->update;

(Note: 'process' clears params, so you have to use 'update' );

dependency

Arrayref of arrayrefs of fields. If one of a group of fields has a value, then all of the group are set to 'required'.

has '+dependency' => ( default => sub { [
   ['street', 'city', 'state', 'zip' ],] }
);

METHODS

new

New creates a new form object. The constructor takes name/value pairs:

MyForm->new(
    item    => $item,
    init_object => { name => 'Your name here', username => 'choose' }
);

Or a single item (model row object) or item_id (row primary key) may be supplied:

MyForm->new( $id );
MyForm->new( $item );

If you will be processing a persistent form with 'process', no arguments are necessary. Do not pass in item or item_id if you use 'process', because they will be cleared.

The common attributes to be passed in to the constructor are:

item_id
item
schema
item_class (often set in the form class)
dependency
field_list
init_object

Creating a form object:

my $form =  = HTML::FormHandler::Model::DBIC->new(
    item_id         => $id,
    item_class    => 'User', 
    schema          => $schema,
    field_list         => {
        required => {
            name    => 'Text',
            active  => 'Boolean',
        },
    },
);

The 'item', 'item_id', and 'item_class' attributes are defined in HTML::FormHandler::Model, and 'schema' is defined in HTML::FormHandler::Model::DBIC.

FormHandler forms are handled in two steps: 1) create with 'new', 2) handle with 'process' or 'update'. FormHandler doesn't care whether most parameters are set on new or process or update, but a 'field_list' argument should be passed in on 'new'.

BUILD, BUILDARGS

These are called when the form object is first created (by Moose).

A single argument is an "item" parameter if it's a reference, otherwise it's an "item_id".

First BUILD calls the build_fields method, which reads the field_list and creates the fields object array.

Then 'init_from_object' is called to load each field's internal value from the 'init_object' or from the 'item', followed by 'load_options' to load values for select fields.

process

A convenience method for persistent FormHandler instances. This method calls 'clear' and 'update' to processes a form:

my $validated = $form->process( item => $book, 
    params => $c->req->parameters );

or:

my $validated = $form->process( item_id => $item_id,
    schema => $schema, params => $c->req->parameters );

If you set attributes that are not cleared and you have a persistent form, you must either set that attribute on each request or clear it.

If your form is not persistent, you should call 'update' instead, because this method clears the item and item_id.

This method can also be used for non-database forms:

$form->process( params => $params );

This method returns the 'validated' flag. ($form->validated)

update

This is the method to call to update the form if your form is not persistent. Pass in item or item_id/schema and parameters.

my $form = MyApp::Form::Book->new;
$form->update( item => $item, schema => $schema );

It set attributes from the parameters passed in, calls 'init_from_object', loads select options, calls validate if there are parameters, and calls update_model if the form validated. It returns the 'validated' flag.

validate

This is the non-database form processing method.

$self->validate( $params );

or

$self->validate( key => 'something', params => $params );

It will call the validate_form method to perform validation on the fields.

validate_form

The validation routine

The method does the following:

1) sets required dependencies
2) trims params and saves in field 'input' attribute
3) calls the 'fields_validate' routine from HTML::FormHandler::Fields
4) calls cross_validate for validating fields that might be blank and
   checking more complex dependencies. (If this field, then not that field...) 
5) calls the model's validation method. By default, this only checks for
   database uniqueness.
6) counts errors, sets 'ran_validation' and 'validated' flags
7) returns 'validated' flag

Returns true if validation succeeds, false if validation fails.

db_validate

Convenience function to allow validating values in the database object. This is not intended for use with HTML forms. If you've written some nice validators for form data, but there is unvalidated data in the database, this function could be used in a script to check the validity of values in the database. All it does is copy the fill-in-form fields to the parameter hash and call validate. See the test script in HTML::FormHandler::Manual::Intro, and the t/db_validate.t test.

my $form = MyApp::Form::Book->new( item => $item );
my $validated = $form->db_validate;

clear

Calls clear_state,clear_params, clear_model (in the model), and clears 'ctx'

clear_state

Clears out state information in the form.

validated
ran_validation
num_errors
fields: errors, fif  
params

clear_values

Clears field values

clear_errors

Clears field errors

clear_fif

Clears fif values

dump_fields

Dumps the fields of the form for debugging. This method is called when the verbose flag is turned on.

dump_validated

For debugging, dump the validated fields. This method is called when the verbose flag is on.

fif (fill in form)

Returns a hash of values suitable for use with HTML::FillInForm or for filling in a form with $form->fif->{fieldname}. The fif value for a 'title' field in a TT form:

[% form.fif.title %] 

values

Returns a hashref of all field values. Useful for non-database forms. The 'fif' and 'values' hashrefs will be the same unless there's a difference in format between the HTML field values (in fif) and the saved value or unless the field 'name' and 'accessor' are different. 'fif' returns a hash with the field names for the keys and the field's 'fif' for the values; 'values' returns a hash with the field accessors for the keys, and the field's 'value' for the the values.

field NAME

This is the method that is usually called in your templates to access a field:

[% f = form.field('title') %]

Searches for and returns a field named "NAME". Dies on not found.

my $field = $form->field('first_name');

Pass a second true value to not die on errors.

my $field = $form->field('something', 1 );

value

Convenience function to return the value of the field. Returns undef if field not found.

field_exists

Returns true (the field) if the field exists

munge_params

Munges the parameters when they are set. Currently just adds keys without the "html_prefix". Can be subclassed. You might want to use this if you want to use different names in your html form than your field names.

cross_validate

This method is useful for cross checking values after they have been saved as their final validated value, and for performing more complex dependency validation.

This method is called even if some fields did not validate.

has_error

Returns true if validate has been called and the form did not validate.

has_errors

Checks the fields for errors and return true or false.

error_fields

Returns list of fields with errors.

error_field_names

Returns a list of the names of the fields with errors.

errors

Returns a single array with all field errors

uuid

Generates a hidden html field with a unique ID using Data::UUID which the can be used to check for duplicate form postings. Creates following html:

<input type="hidden" name="form_uuid" value="..some_uuid..">

Call with:

[% form.uuid %]

METHODS used in internal processing

Most users won't need these methods.

setup_form

Puts parameters into attributes, initializes fields, loads options

init_from_object

Populates the field 'value' attributes from an 'init_object' or $form->item by calling a form's custom init_value_$fieldname method, passing in the field and the item.

The value is stored in both the 'init_value' attribute, and the 'value' attribute.

init_value

This method populates a form field's value from the item object.

load_options

For 'Select' or 'Multiple' fields (fields which have an 'options' method), call an "options_$field_name" method if it exists (is defined in your form), or else call the model's "lookup_options" to retrieve the list of options from the database.

An example of an 'options' routine in your form class:

sub options_fruit {
    return (
        1 => 'Apple',
        2 => 'Grape',
        3 => 'Cherry',
    );
}

See HTML::FormHandler::Field::Select

load_field_options

Load the options array into a field. Pass in a field object, and, optionally, an options array.

set_dependency

Process the dependency lists

SUPPORT

IRC:

Join #formhandler on irc.perl.org

Mailing list:

http://groups.google.com/group/formhandler

Code repository:

http://github.com/gshank/html-formhandler/tree/master

SEE ALSO

HTML::FormHandler::Manual

HTML::FormHandler::Manual::Tutorial

HTML::FormHandler::Manual::Intro

HTML::FormHandler::Manual::Templates

HTML::FormHandler::Manual::Cookbook

HTML::FormHandler::Field

HTML::FormHandler::Model::DBIC

HTML::FormHandler::Moose

AUTHOR

gshank: Gerda Shank <gshank@cpan.org>

Based on the original source code of Form::Processor by Bill Moseley

COPYRIGHT

This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself.