Release commit for 5.9013
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / 09_AdvancedCRUD / 09_FormHandler.pod
CommitLineData
0abc72ed 1=head1 NAME
2
3Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler - Catalyst Tutorial - Chapter 9: Advanced CRUD - FormHandler
4
0abc72ed 5=head1 OVERVIEW
6
7This is B<Chapter 9 of 10> for the Catalyst tutorial.
8
9L<Tutorial Overview|Catalyst::Manual::Tutorial>
10
11=over 4
12
13=item 1
14
15L<Introduction|Catalyst::Manual::Tutorial::01_Intro>
16
17=item 2
18
19L<Catalyst Basics|Catalyst::Manual::Tutorial::02_CatalystBasics>
20
21=item 3
22
23L<More Catalyst Basics|Catalyst::Manual::Tutorial::03_MoreCatalystBasics>
24
25=item 4
26
27L<Basic CRUD|Catalyst::Manual::Tutorial::04_BasicCRUD>
28
29=item 5
30
31L<Authentication|Catalyst::Manual::Tutorial::05_Authentication>
32
33=item 6
34
35L<Authorization|Catalyst::Manual::Tutorial::06_Authorization>
36
37=item 7
38
39L<Debugging|Catalyst::Manual::Tutorial::07_Debugging>
40
41=item 8
42
43L<Testing|Catalyst::Manual::Tutorial::08_Testing>
44
45=item 9
46
47B<09_Advanced CRUD::09_FormHandler>
48
49=item 10
50
51L<Appendices|Catalyst::Manual::Tutorial::10_Appendices>
52
53=back
54
55
56=head1 DESCRIPTION
57
30fc2cda 58This portion of the tutorial explores
2217b252 59L<HTML::FormHandler> and how it can be used to manage
30fc2cda 60forms, perform validation of form input, and save and restore data
61to or from the database. This was written using HTML::FormHandler version
620.28001.
0abc72ed 63
7ce05098 64See
2217b252 65L<Catalyst::Manual::Tutorial::09_AdvancedCRUD>
7ce05098 66for additional form management options other than
2217b252 67L<HTML::FormHandler>.
0abc72ed 68
69
70=head1 Install HTML::FormHandler
71
72
73Use the following command to install L<HTML::FormHandler::Model::DBIC> directly
74from CPAN:
75
7ce05098 76 sudo cpan HTML::FormHandler::Model::DBIC
0abc72ed 77
7ce05098 78It will install L<HTML::FormHandler> as a prerequisite.
0abc72ed 79
30fc2cda 80Also, add:
9372a4db 81
82 requires 'HTML::FormHandler::Model::DBIC';
83
f4e9de4a 84to your F<Makefile.PL>.
0abc72ed 85
86=head1 HTML::FormHandler FORM CREATION
87
7ce05098 88This section looks at how L<HTML::FormHandler> can be used to
0abc72ed 89add additional functionality to the manually created form from Chapter 4.
90
91
7ce05098 92=head2 Using FormHandler in your controllers
0abc72ed 93
433f1ad4 94FormHandler doesn't have a Catalyst base controller, because interfacing
0abc72ed 95to a form is only a couple of lines of code.
96
97=head2 Create a Book Form
98
f4e9de4a 99Create the directory F<lib/MyApp/Form>. Create F<lib/MyApp/Form/Book.pm>:
0abc72ed 100
101 package MyApp::Form::Book;
9372a4db 102
0abc72ed 103 use HTML::FormHandler::Moose;
104 extends 'HTML::FormHandler::Model::DBIC';
105 use namespace::autoclean;
106
107 has '+item_class' => ( default =>'Books' );
108 has_field 'title';
109 has_field 'rating' => ( type => 'Integer' );
110 has_field 'authors' => ( type => 'Multiple', label_column => 'last_name' );
111 has_field 'submit' => ( type => 'Submit', value => 'Submit' );
112
113 __PACKAGE__->meta->make_immutable;
114 1;
115
116
117=head2 Add Action to Display and Save the Form
118
f4e9de4a 119At the top of the F<lib/MyApp/Controller/Books.pm> add:
0abc72ed 120
121 use MyApp::Form::Book;
122
123Add the following methods:
124
125 =head2 create
126
127 Use HTML::FormHandler to create a new book
128
129 =cut
130
131 sub create : Chained('base') PathPart('create') Args(0) {
132 my ($self, $c ) = @_;
133
134 my $book = $c->model('DB::Book')->new_result({});
135 return $self->form($c, $book);
136 }
137
138 =head2 form
139
140 Process the FormHandler book form
141
142 =cut
143
144 sub form {
145 my ( $self, $c, $book ) = @_;
146
147 my $form = MyApp::Form::Book->new;
148 # Set the template
149 $c->stash( template => 'books/form.tt2', form => $form );
150 $form->process( item => $book, params => $c->req->params );
151 return unless $form->validated;
8358866c 152 # Set a status message for the user & return to books list
153 $c->response->redirect($c->uri_for($self->action_for('list'),
154 {mid => $c->set_status_msg("Book created")}));
0abc72ed 155 }
156
157These two methods could be combined at this point, but we'll use the 'form'
158method later when we implement 'edit'.
159
160
161=head2 Create a Template Page To Display The Form
162
f4e9de4a 163Open F<root/src/books/form.tt2> in your editor and enter the following:
0abc72ed 164
165 [% META title = 'Create/Update Book' %]
7ce05098 166
0abc72ed 167 [%# Render the HTML::FormHandler Form %]
168 [% form.render %]
7ce05098 169
0abc72ed 170 <p><a href="[% c.uri_for(c.controller.action_for('list')) %]">Return to book list</a></p>
171
172
173=head2 Add Link for Create
174
f4e9de4a 175Open F<root/src/books/list.tt2> in your editor and add the following to
0abc72ed 176the bottom of the existing file:
177
178 ...
179 <p>
02bb2b5a 180 HTML::FormHandler:
181 <a href="[% c.uri_for(c.controller.action_for('create')) %]">Create</a>
0abc72ed 182 </p>
183
184This adds a new link to the bottom of the book list page that we can
185use to easily launch our HTML::FormHandler-based form.
186
187
188=head2 Test The HTML::FormHandler Create Form
189
190Press C<Ctrl-C> to kill the previous server instance (if it's still
191running) and restart it:
192
193 $ script/myapp_server.pl
194
195Login as C<test01> (password: mypass). Once at the Book List page,
196click the new HTML::Formhandler "Create" link at the bottom to display the
197form. Fill in the following values:
198
199 Title = "Internetworking with TCP/IP Vol. II"
200 Rating = "4"
201 Author = "Comer"
7ce05098 202
0abc72ed 203Click the Submit button, and you will be returned to the Book List page
204with a "Book created" status message displayed.
205
206Note that because the 'Author' column is a Select list, only the authors
207in the database can be entered. The 'ratings' field will only accept
7ce05098 208integers.
0abc72ed 209
210
211=head2 Add Constraints
212
f4e9de4a 213Open F<lib/MyApp/Form/Book.pm> in your editor.
0abc72ed 214
215Restrict the title size and make it required:
216
217 has_field 'title' => ( minlength => 5, maxlength => 40, required => 1 );
218
219Add range constraints to the 'rating' field:
220
221 has_field 'rating' => ( type => 'Integer', range_start => 1, range_end => 5 );
222
223The 'authors' relationship is a 'many-to-many' pseudo-relation, so this field
30fc2cda 224can be set to Multiple to allow the selection of multiple authors; also, make it
0abc72ed 225required:
226
9372a4db 227 has_field 'authors' => ( type => 'Multiple', label_column => 'last_name',
228 required => 1 );
0abc72ed 229
30fc2cda 230Note: FormHandler automatically strips whitespace at the beginning and
231end of fields. If you want some other kind of stripping (or none) you
232can specify it explicitly; see L<HTML::FormHandler::Manual>.
0abc72ed 233
234=head2 Try Out the Updated Form
235
7ce05098 236Press C<Ctrl-C> to kill the previous server instance (if it's still
0abc72ed 237running) and restart it:
238
239 $ script/myapp_server.pl
240
7ce05098 241Make sure you are still logged in as C<test01> and try adding a book
242with various errors: title less than 5 characters, non-numeric rating, a
243rating of 0 or 6, etc. Also try selecting one, two, and zero authors.
0abc72ed 244
245=head2 Create the 'edit' method
246
f4e9de4a 247Edit F<lib/MyApp/Controller/Books.pm> and add the following method:
0abc72ed 248
7ce05098 249
0abc72ed 250 =head2 edit
251
252 Edit an existing book with FormHandler
253
254 =cut
255
256 sub edit : Chained('object') PathPart('edit') Args(0) {
257 my ( $self, $c ) = @_;
258
259 return $self->form($c, $c->stash->{object});
260 }
261
f4e9de4a 262Update the F<root/src/books/list.tt2>, adding an 'edit' link below the
0abc72ed 263"Delete" link to use the FormHandler edit method:
264
265 <td>
02bb2b5a 266 [% # Add a link to delete a book %]
267 <a href="[% c.uri_for(c.controller.action_for('delete'), [book.id]) %]">Delete</a>
268 [% # Add a link to edit a book %]
269 <a href="[% c.uri_for(c.controller.action_for('edit'), [book.id]) %]">Edit</a>
0abc72ed 270 </td>
271
272
273=head2 Try Out the Edit/Update Feature
274
7ce05098 275Press C<Ctrl-C> to kill the previous server instance (if it's still
0abc72ed 276running) and restart it:
277
278 $ script/myapp_server.pl
279
7ce05098 280Make sure you are still logged in as C<test01> and go to the
281L<http://localhost:3000/books/list> URL in your browser. Click the
282"Edit" link next to "Internetworking with TCP/IP Vol. II", change the
283rating to a 3, the "II" at end of the title to the number "2", add
284Stevens as a co-author (control-click), and click Submit. You will then
285be returned to the book list with a "Book edited" message at the top in
0abc72ed 286green. Experiment with other edits to various books.
287
288=head2 See additional documentation on FormHandler
289
f7f5632e 290L<HTML::FormHandler::Manual>
0abc72ed 291
f7f5632e 292L<HTML::FormHandler>
0abc72ed 293
294 #formhandler on irc.perl.org
295
296 mailing list: http://groups.google.com/group/formhandler
297
7ce05098 298 code: http://github.com/gshank/html-formhandler/tree/master
0abc72ed 299
300=head1 AUTHOR
301
302Gerda Shank, C<gshank@cpan.org>
303
304Copyright 2009, Gerda Shank, Perl Artistic License