3 Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler - Catalyst Tutorial - Chapter 9: Advanced CRUD - FormHandler
8 This is B<Chapter 9 of 10> for the Catalyst tutorial.
10 L<Tutorial Overview|Catalyst::Manual::Tutorial>
16 L<Introduction|Catalyst::Manual::Tutorial::01_Intro>
20 L<Catalyst Basics|Catalyst::Manual::Tutorial::02_CatalystBasics>
24 L<More Catalyst Basics|Catalyst::Manual::Tutorial::03_MoreCatalystBasics>
28 L<Basic CRUD|Catalyst::Manual::Tutorial::04_BasicCRUD>
32 L<Authentication|Catalyst::Manual::Tutorial::05_Authentication>
36 L<Authorization|Catalyst::Manual::Tutorial::06_Authorization>
40 L<Debugging|Catalyst::Manual::Tutorial::07_Debugging>
44 L<Testing|Catalyst::Manual::Tutorial::08_Testing>
48 B<09_Advanced CRUD::09_FormHandler>
52 L<Appendices|Catalyst::Manual::Tutorial::10_Appendices>
59 This portion of the tutorial explores L<HTML::FormHandler|HTML::FormHandler> and
60 how it can be used to manage forms, perform validation of form input,
61 as well as save and restore data to/from the database. This was written
62 using HTML::FormHandler version 0.28001.
65 L<Catalyst::Manual::Tutorial::09_AdvancedCRUD|Catalyst::Manual::Tutorial::09_AdvancedCRUD>
66 for additional form management options other than
67 L<HTML::FormHandler|HTML::FormHandler>.
70 =head1 Install HTML::FormHandler
73 Use the following command to install L<HTML::FormHandler::Model::DBIC> directly
76 sudo cpan HTML::FormHandler::Model::DBIC
78 It will install L<HTML::FormHandler> as a prereq.
81 =head1 HTML::FormHandler FORM CREATION
83 This section looks at how L<HTML::FormHandler|HTML::FormHandler> can be used to
84 add additional functionality to the manually created form from Chapter 4.
87 =head2 Using FormHandler in your controllers
89 FormHandler doen't have a Catalyst base controller, because interfacing
90 to a form is only a couple of lines of code.
92 =head2 Create a Book Form
94 Create the directory C<lib/MyApp/Form>. Create C<lib/MyApp/Form/Book.pm>:
96 package MyApp::Form::Book;
97 use HTML::FormHandler::Moose;
98 extends 'HTML::FormHandler::Model::DBIC';
99 use namespace::autoclean;
101 has '+item_class' => ( default =>'Books' );
103 has_field 'rating' => ( type => 'Integer' );
104 has_field 'authors' => ( type => 'Multiple', label_column => 'last_name' );
105 has_field 'submit' => ( type => 'Submit', value => 'Submit' );
107 __PACKAGE__->meta->make_immutable;
111 =head2 Add Action to Display and Save the Form
113 At the top of the C<lib/MyApp/Controller/Books.pm> add:
115 use MyApp::Form::Book;
117 Add the following methods:
121 Use HTML::FormHandler to create a new book
125 sub create : Chained('base') PathPart('create') Args(0) {
126 my ($self, $c ) = @_;
128 my $book = $c->model('DB::Book')->new_result({});
129 return $self->form($c, $book);
134 Process the FormHandler book form
139 my ( $self, $c, $book ) = @_;
141 my $form = MyApp::Form::Book->new;
143 $c->stash( template => 'books/form.tt2', form => $form );
144 $form->process( item => $book, params => $c->req->params );
145 return unless $form->validated;
146 $c->flash( message => 'Book created' );
147 # Redirect the user back to the list page
148 $c->response->redirect($c->uri_for($self->action_for('list')));
151 These two methods could be combined at this point, but we'll use the 'form'
152 method later when we implement 'edit'.
155 =head2 Create a Template Page To Display The Form
157 Open C<root/src/books/form.tt2> in your editor and enter the following:
159 [% META title = 'Create/Update Book' %]
161 [%# Render the HTML::FormHandler Form %]
164 <p><a href="[% c.uri_for(c.controller.action_for('list')) %]">Return to book list</a></p>
167 =head2 Add Link for Create
169 Open C<root/src/books/list.tt2> in your editor and add the following to
170 the bottom of the existing file:
175 <a href="[% c.uri_for(c.controller.action_for('create')) %]">Create</a>
178 This adds a new link to the bottom of the book list page that we can
179 use to easily launch our HTML::FormHandler-based form.
182 =head2 Test The HTML::FormHandler Create Form
184 Press C<Ctrl-C> to kill the previous server instance (if it's still
185 running) and restart it:
187 $ script/myapp_server.pl
189 Login as C<test01> (password: mypass). Once at the Book List page,
190 click the new HTML::Formhandler "Create" link at the bottom to display the
191 form. Fill in the following values:
193 Title = "Internetworking with TCP/IP Vol. II"
197 Click the Submit button, and you will be returned to the Book List page
198 with a "Book created" status message displayed.
200 Note that because the 'Author' column is a Select list, only the authors
201 in the database can be entered. The 'ratings' field will only accept
205 =head2 Add Constraints
207 Open C<lib/MyApp/Form/Book.pm> in your editor.
209 Restrict the title size and make it required:
211 has_field 'title' => ( minlength => 5, maxlength => 40, required => 1 );
213 Add range constraints to the 'rating' field:
215 has_field 'rating' => ( type => 'Integer', range_start => 1, range_end => 5 );
217 The 'authors' relationship is a 'many-to-many' pseudo-relation, so this field
218 can be set to Multiple to allow the selection of multiple authors and make it
221 has_field 'authors' => ( type => 'Multiple', required => 1 );
223 Note: FormHandler automatically strips whitespace at the beginning or end of fields.
224 If you want some other kind of stripping (or none) you can specify it explicitly.
225 (see L<HTML::FormHandler::Manual>)
227 =head2 Try Out the Updated Form
229 Press C<Ctrl-C> to kill the previous server instance (if it's still
230 running) and restart it:
232 $ script/myapp_server.pl
234 Make sure you are still logged in as C<test01> and try adding a book
235 with various errors: title less than 5 characters, non-numeric rating, a
236 rating of 0 or 6, etc. Also try selecting one, two, and zero authors.
238 =head2 Create the 'edit' method
240 Edit C<lib/MyApp/Controller/Books.pm> and add the following method:
245 Edit an existing book with FormHandler
249 sub edit : Chained('object') PathPart('edit') Args(0) {
250 my ( $self, $c ) = @_;
252 return $self->form($c, $c->stash->{object});
255 Update the C<root/src/books/list.tt2>, adding an 'edit' link below the
256 "Delete" link to use the FormHandler edit method:
259 [% # Add a link to delete a book %]
260 <a href="[% c.uri_for(c.controller.action_for('delete'), [book.id]) %]">Delete</a>
261 [% # Add a link to edit a book %]
262 <a href="[% c.uri_for(c.controller.action_for('edit'), [book.id]) %]">Edit</a>
266 =head2 Try Out the Edit/Update Feature
268 Press C<Ctrl-C> to kill the previous server instance (if it's still
269 running) and restart it:
271 $ script/myapp_server.pl
273 Make sure you are still logged in as C<test01> and go to the
274 L<http://localhost:3000/books/list> URL in your browser. Click the
275 "Edit" link next to "Internetworking with TCP/IP Vol. II", change the
276 rating to a 3, the "II" at end of the title to the number "2", add
277 Stevens as a co-author (control-click), and click Submit. You will then
278 be returned to the book list with a "Book edited" message at the top in
279 green. Experiment with other edits to various books.
281 =head2 See additional documentation on FormHandler
283 L<HTML::FormHandler::Manual>
287 #formhandler on irc.perl.org
289 mailing list: http://groups.google.com/group/formhandler
291 code: http://github.com/gshank/html-formhandler/tree/master
295 Gerda Shank, C<gshank@cpan.org>
297 Copyright 2009, Gerda Shank, Perl Artistic License