, and enter
or copy the following:
[% META title = 'Book Form' %]
[% FOR field IN form.error_fields %]
[% FOR error IN field.errors %]
[% field.label _ ': ' _ error %]
[% END %]
[% END %]
Return to book list
=head2 Add links to access create and update actions
Add a link to root/src/books/list.tt2 to allow you to edit
an existing book, by changing the last cell in the book
list:
|
Delete|
Edit
|
Change the link to create a book at the bottom of the file:
Create book
=head2 Test the L Create Form
Start up the server for MyApp:
$ script/myapp_server.pl
(You'll need to login with test01/mypass if you're using the packaged
tutorial.) Click the new "Create book" link at the bottom to display
the form. Fill in the fields and click submit. You should be
returned to the Book List page with a "Book saved" message.
Magic! A new book has been created and saved to the database
with very little code in your controller.
Click on the 'edit' links, and edit the existing books. Changes
should be saved and displayed properly. Try to add an alphabetic
character to the rating field. You should get an error message.
=head2 Add additional attributes to your form's fields
We'll add a couple of 'label' attributes to the fields:
has_field 'title' => ( type => 'Text', label => 'Title of a Book' );
has_field 'rating' => ( type => 'Integer', label => 'Rating (1-5)' );
has_field 'authors' => ( type => 'Multiple', label_column => 'last_name' );
If you want a new attribute in your fields, it's very easy to add it to your
custom Field classes.
package MyApp::Form::Field::Extra;
use Moose;
extends 'HTML::FormHandler::Field';
has 'my_attribute' => ( isa => Str, is => 'ro' );
1;
Now if your Field classes inherit from this, you can have a 'my_attribute'
attribute for all your fields. Or use a Moose role instead of inheritance.
You can also add attributes to the base FormHandler field class using Moose.
This technique is described in L.
=head1 L Validation
Now we'll add more validation to ensure that users
are entering correct data.
Update the fields in the form file:
has_field 'title' => ( type => 'Text', label => 'Title of a Book',
required => 1, size => 40, minlength => 5 );
has_field 'rating' => ( type => 'Integer', label => 'Rating (1-5)',
required => 1, messages => { required => 'You must rate the book' },
range_start => 1, range_end => 5 );
has_field 'authors' => ( type => 'Multiple', label_column => 'last_name',
required => 1 );
We've made all the fields required.
We added 'size' and 'minlength' attributes to the 'title' field. These
are attributes of the 'Text' Field, which will use them to validate.
We've added 'range_start' and 'range_end' attributes to the 'rating' field.
Numbers entered in the form will be checked to make sure they fall within
the defined range. (Another option would have been to use the 'IntRange'
field type, which makes it easy to create a select list of numbers.)
=head2 Add customized validation
You can create a Field class for validation that will
be performed on more than one field, but it is easy to perform
custom validation on a per-field basis.
This form doesn't really require any customized validation,
so we'll add a silly field constraint. Add the following to the form:
sub validate_title {
my ( $self, $field ) = @_;
$field->add_error("The word \'Rainbows\' is not allowed in titles")
if ( $field->value =~ /Rainbows/ );
}
You can also apply Moose constraints and transforms. Validation can also
be performed in a form 'validate_