1HTML::FormHandler::ManuUasle:r:TCuotnotrriiablu(t3e)d PeHrTlMLD:o:cFuomremnHtaantdiloenr::Manual::Tutorial(3)
2
3
4

NAME

6       HTML::FormHandler::Manual::Tutorial - how to use FormHandler with
7       Catalyst
8

VERSION

10       version 0.40068
11

SYNOPSIS

13       Manual Index
14
15       A tutorial for beginners to HTML::FormHandler
16

Using HTML::FormHandler with Catalyst

18       This tutorial demonstrates how you can use HTML::FormHandler to manage
19       forms, validate form input, and interface your forms with the database.
20

Installation

22       Use CPAN to install HTML::FormHandler
23

Use the Tutorial application

25       We'll use the files that were created in the
26       Catalyst::Manual::Tutorial, in order to concentrate on just the bits
27       where HTML::FormHandler is useful.  You can download a tar file of the
28       tutorial files from the Catalyst code repository. (See
29       Catalyst::Manual::Tutorial::Intro.)
30
31   Create an HTML::FormHandler form
32       Untar the tutorial and make a lib/MyApp/Form directory. In that
33       directory create the file Book.pm.
34
35          package MyApp::Form::Book;
36
37          use utf8; # if using non-latin1 languages
38
39          use HTML::FormHandler::Moose;
40          extends 'HTML::FormHandler::Model::DBIC';
41
42          has '+item_class' => ( default => 'Book' );
43          has_field 'title' => ( type => 'Text' );
44          has_field 'rating' => ( type => 'Integer' );
45          has_field 'authors' => ( type => 'Multiple', label_column => 'last_name' );
46          has_field 'submit' => ( type => 'Submit', value => 'Submit' );
47
48          no HTML::FormHandler::Moose;
49          1;
50
51       This is your Form class. The form initializes the 'item_class' to the
52       source name of your DBIx::Class result class. The form's fields are
53       defined with the 'has_field' sugar, or in a 'field_list'. The names of
54       the fields should match a column, relationship, or other accessor in
55       your DBIx::Class result class.
56
57       The basic fields have only a 'type', such as 'Text', or 'Integer'.
58       These types are actually the names of HTML::FormHandler::Field classes.
59       'Text' and 'Integer' are types that are provided by HTML::FormHandler,
60       in HTML::FormHandler::Field::Text and
61       HTML::FormHandler::Field::Integer.
62
63       The 'Multiple' type will allow you to easily create a multiple select
64       list from the 'authors' relationship.  The 'label_column' attribute
65       must be defined because the column in the 'authors' table which is used
66       to create the select list does not have the default column name
67       ('name').
68
69       The 'submit' field is necessary if you are going to use FormHandler to
70       render your form. It wouldn't be necessary for hand-built templates or
71       HTML.
72
73       Eventually you will want to create your own field classes, but for this
74       simple form the default types are adequate.
75
76   Connect HTML::FormHandler to your controller
77       Edit lib/MyApp/Controller/Books.pm.  Add use Moose:
78
79           use Moose;
80           BEGIN { extends 'Catalyst::Controller' }
81           use MyApp::Form::Book;
82
83       Create an attribute to hold your form:
84
85          has 'form' => ( isa => 'MyApp::Form::Book', is => 'rw',
86              lazy => 1, default => sub { MyApp::Form::Book->new } );
87
88   Add Action to Display and Save the Form
89       In "lib/MyApp/Controller/Books.pm" add the following method:
90
91           sub edit : Local {
92               my ( $self, $c, $book_id ) = @_;
93
94               $c->stash( template => 'books/edit.tt2',
95                          form => $self->form );
96
97               # Validate and insert/update database
98               return unless $self->form->process( item_id => $book_id,
99                  params => $c->req->parameters,
100                  schema => $c->model('DB')->schema );
101
102               # Form validated, return to the books list
103               $c->flash->{status_msg} = 'Book saved';
104               $c->res->redirect($c->uri_for('list'));
105           }
106
107       This will handle both creating new books, and updating old books.  If
108       $book_id is undefined, then HTML::FormHandler will create a new book
109       from your form. If you pass in a DBIx::Class row object instead of a
110       primary key, you don't need to specify the schema.
111
112   Render the form
113       Save a copy of "root/src/books/edit.tt2" and create a new file that
114       contains only:
115
116          [% form.render %]
117
118   Alternative hand-built Template for the form (optional)
119       Although the automatic rendering works well, sometimes it's necessary
120       to hand build HTML. This section contains an example of a Template
121       Toolkit template that may be used to display a FormHandler form.
122
123       In some cases, you might want to use the rendering for just the field
124       and build custom divs or tables or whatever around it:
125
126         <div class="mycustomclass">
127         [% form.render_field('book') %]
128         </div>
129
130       If you don't want to play with HTML at this point, you can skip ahead
131       to the next section.
132
133       You could also use TT macros to do pretty sophisticated template
134       generation. But for now, we'll stick to a straightforward TT template:
135
136       Delete the single statement in "root/src/books/edit.tt2", and enter or
137       copy the following:
138
139          [% META title = 'Book Form' %]
140
141          [% FOR field IN form.error_fields %]
142            [% FOR error IN field.errors %]
143              <p><span class="error" id="error">
144                 [% field.label _ ': ' _ error %] </span></p>
145            [% END %]
146          [% END %]
147
148          <form name="[% form.name %]"
149                action="[% c.uri_for('edit', form.item_id) %]"
150                method="post">
151          <p>
152          [% f = form.field('title') %]
153          <label class="label" for="[% f.name %]">[% f.label %]:</label>
154          <input type="text" name="[% f.name %]" id="[% f.name %]" value="[% f.fif %]">
155          </p>
156          <p>
157          [% f = form.field('rating') %]
158          <label class="label" for="[% f.name %]">[% f.label %]:</label>
159          <input type="text" name="[% f.name %]" id="[% f.name %]" %] value="[% f.fif %]">
160          </p>
161          <p>
162          [% f = form.field('authors') %]
163          <label class="label" for="[% f.name %]">[% f.label %]:</label>
164          <select name="[% f.name %]" multiple="multiple" size="[% f.size %]">
165            [% FOR option IN f.options %]
166              <option value="[% option.value %]"
167                [% FOREACH selval IN f.fif %]
168                    [% IF selval == option.value %]selected="selected"[% END %]
169                [% END %]>
170              [% option.label | html %]</option>
171            [% END %]
172          </select>
173          </p>
174          <input class="button" name="submit" type="submit" value="Submit" />
175          </form>
176
177          <p><a href="[% c.uri_for('list') %]">Return to book list</a></p>
178
179   Add links to access create and update actions
180       Add a link to root/src/books/list.tt2 to allow you to edit an existing
181       book, by changing the last <td> cell in the book list:
182
183          <td>
184             <a href="[% c.uri_for('delete', book.id) %]">Delete</a>|
185             <a href="[% c.uri_for('edit', book.id) %]">Edit</a>
186          </td>
187
188       Change the link to create a book at the bottom of the file:
189
190           <p>
191             <a href="[% c.uri_for('edit') %]">Create book</a>
192           </p>
193
194   Test the HTML::FormHandler Create Form
195       Start up the server for MyApp:
196
197           $ script/myapp_server.pl
198
199       (You'll need to login with test01/mypass if you're using the packaged
200       tutorial.) Click the new "Create book" link at the bottom to display
201       the form.  Fill in the fields and click submit.  You should be returned
202       to the Book List page with a "Book saved" message.
203
204       Magic! A new book has been created and saved to the database with very
205       little code in your controller.
206
207       Click on the 'edit' links, and edit the existing books. Changes should
208       be saved and displayed properly. Try to add an alphabetic character to
209       the rating field. You should get an error message.
210
211   Add additional attributes to your form's fields
212       We'll add a couple of 'label' attributes to the fields:
213
214          has_field 'title' => ( type => 'Text', label => 'Title of a Book' );
215          has_field 'rating' => ( type => 'Integer', label => 'Rating (1-5)' );
216          has_field 'authors' => ( type => 'Multiple', label_column => 'last_name' );
217
218       If you want a new attribute in your fields, it's very easy to add it to
219       your custom Field classes.
220
221          package MyApp::Form::Field::Extra;
222          use Moose;
223          extends 'HTML::FormHandler::Field';
224
225          has 'my_attribute' => ( isa => Str, is => 'ro' );
226
227          1;
228
229       Now if your Field classes inherit from this, you can have a
230       'my_attribute' attribute for all your fields. Or use a Moose role
231       instead of inheritance.
232
233       You can also add attributes to the base FormHandler field class using
234       Moose.  This technique is described in
235       HTML::FormHandler::Manual::Cookbook.
236

HTML::FormHandler Validation

238       Now we'll add more validation to ensure that users are entering correct
239       data.
240
241       Update the fields in the form file:
242
243          has_field 'title' => ( type => 'Text', label => 'Title of a Book',
244             required => 1, size => 40, minlength => 5 );
245          has_field 'rating' => ( type => 'Integer', label => 'Rating (1-5)',
246             required => 1, messages => { required => 'You must rate the book' },
247             range_start => 1, range_end => 5 );
248          has_field 'authors' => ( type => 'Multiple', label_column => 'last_name',
249             required => 1 );
250
251       We've made all the fields required.  We added 'size' and 'minlength'
252       attributes to the 'title' field. These are attributes of the 'Text'
253       Field, which will use them to validate.  We've added 'range_start' and
254       'range_end' attributes to the 'rating' field.  Numbers entered in the
255       form will be checked to make sure they fall within the defined range.
256       (Another option would have been to use the 'IntRange' field type, which
257       makes it easy to create a select list of numbers.)
258
259   Add customized validation
260       You can create a Field class for validation that will be performed on
261       more than one field, but it is easy to perform custom validation on a
262       per-field basis.
263
264       This form doesn't really require any customized validation, so we'll
265       add a silly field constraint.  Add the following to the form:
266
267          sub validate_title {
268             my ( $self, $field ) = @_;
269             $field->add_error("The word \'Rainbows\' is not allowed in titles")
270                if ( $field->value =~ /Rainbows/ );
271          }
272
273       You can also apply Moose constraints and transforms. Validation can
274       also be performed in a form 'validate_<field_name' method, in a
275       'validate_model' routine, and in a custom field class.  You can
276       validate that the field is unique, or use a dependency list to make
277       more fields required if one is updated.
278
279   Check out the validation
280       Restart the development server, login, and try adding books with
281       various errors: title length less than 5 or more than 40, rating above
282       5, leaving out a particular field.  Create a book with 'Rainbows' in
283       the title.
284
285       You should get error messages for every error.
286

AUTHOR

288       FormHandler Contributors - see HTML::FormHandler
289
291       This software is copyright (c) 2017 by Gerda Shank.
292
293       This is free software; you can redistribute it and/or modify it under
294       the same terms as the Perl 5 programming language system itself.
295
296
297
298perl v5.32.0                      2020-07H-T2M8L::FormHandler::Manual::Tutorial(3)
Impressum