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