update chapter 9 POD
[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 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.
63
64 See 
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>.
68
69
70 =head1 Install HTML::FormHandler
71
72
73 Use the following command to install L<HTML::FormHandler::Model::DBIC> directly
74 from CPAN:
75
76     sudo cpan HTML::FormHandler::Model::DBIC 
77
78 It will install L<HTML::FormHandler> as a prereq. 
79
80 Also add:
81
82     requires 'HTML::FormHandler::Model::DBIC';
83
84 to your C<Makefile.PL>.
85
86 =head1 HTML::FormHandler FORM CREATION
87
88 This section looks at how L<HTML::FormHandler|HTML::FormHandler> can be used to 
89 add additional functionality to the manually created form from Chapter 4.
90
91
92 =head2 Using FormHandler in your controllers 
93
94 FormHandler doen't have a Catalyst base controller, because interfacing
95 to a form is only a couple of lines of code.
96
97 =head2 Create a Book Form
98
99 Create the directory C<lib/MyApp/Form>. Create C<lib/MyApp/Form/Book.pm>:
100
101     package MyApp::Form::Book;
102
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
119 At the top of the C<lib/MyApp/Controller/Books.pm> add:
120
121    use MyApp::Form::Book;
122
123 Add 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;
152         $c->flash( message => 'Book created' );
153         # Redirect the user back to the list page
154         $c->response->redirect($c->uri_for($self->action_for('list')));
155     }
156
157 These two methods could be combined at this point, but we'll use the 'form'
158 method later when we implement 'edit'.
159
160
161 =head2 Create a Template Page To Display The Form
162
163 Open C<root/src/books/form.tt2> in your editor and enter the following:
164
165     [% META title = 'Create/Update Book' %]
166     
167     [%# Render the HTML::FormHandler Form %]
168     [% form.render %]
169     
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
175 Open C<root/src/books/list.tt2> in your editor and add the following to
176 the bottom of the existing file:
177
178     ...
179     <p>
180       HTML::FormHandler:
181       <a href="[% c.uri_for(c.controller.action_for('create')) %]">Create</a>
182     </p>
183
184 This adds a new link to the bottom of the book list page that we can
185 use to easily launch our HTML::FormHandler-based form.
186
187
188 =head2 Test The HTML::FormHandler Create Form
189
190 Press C<Ctrl-C> to kill the previous server instance (if it's still
191 running) and restart it:
192
193     $ script/myapp_server.pl
194
195 Login as C<test01> (password: mypass).  Once at the Book List page,
196 click the new HTML::Formhandler "Create" link at the bottom to display the
197 form.  Fill in the following values:
198
199     Title  = "Internetworking with TCP/IP Vol. II"
200     Rating = "4"
201     Author = "Comer"
202     
203 Click the Submit button, and you will be returned to the Book List page
204 with a "Book created" status message displayed.
205
206 Note that because the 'Author' column is a Select list, only the authors
207 in the database can be entered. The 'ratings' field will only accept
208 integers. 
209
210
211 =head2 Add Constraints
212
213 Open C<lib/MyApp/Form/Book.pm> in your editor. 
214
215 Restrict the title size and make it required:
216
217    has_field 'title' => ( minlength => 5, maxlength => 40, required => 1 );
218
219 Add range constraints to the 'rating' field:
220
221    has_field 'rating' => ( type => 'Integer', range_start => 1, range_end => 5 );
222
223 The 'authors' relationship is a 'many-to-many' pseudo-relation, so this field
224 can be set to Multiple to allow the selection of multiple authors and make it
225 required:
226
227    has_field 'authors' => ( type => 'Multiple', label_column => 'last_name',
228                             required => 1 );
229
230 Note: FormHandler automatically strips whitespace at the beginning or end of fields.
231 If you want some other kind of stripping (or none) you can specify it explicitly.
232 (see L<HTML::FormHandler::Manual>)
233
234 =head2 Try Out the Updated Form
235
236 Press C<Ctrl-C> to kill the previous server instance (if it's still 
237 running) and restart it:
238
239     $ script/myapp_server.pl
240
241 Make sure you are still logged in as C<test01> and try adding a book 
242 with various errors: title less than 5 characters, non-numeric rating, a 
243 rating of 0 or 6, etc.  Also try selecting one, two, and zero authors. 
244
245 =head2 Create the 'edit' method
246
247 Edit C<lib/MyApp/Controller/Books.pm> and add the following method:
248
249  
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
262 Update the C<root/src/books/list.tt2>, adding an 'edit' link below the
263 "Delete" link to use the FormHandler edit method:
264
265     <td>
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>
270     </td>
271
272
273 =head2 Try Out the Edit/Update Feature
274
275 Press C<Ctrl-C> to kill the previous server instance (if it's still 
276 running) and restart it:
277
278     $ script/myapp_server.pl
279
280 Make sure you are still logged in as C<test01> and go to the 
281 L<http://localhost:3000/books/list> URL in your browser.  Click the 
282 "Edit" link next to "Internetworking with TCP/IP Vol. II", change the 
283 rating to a 3, the "II" at end of the title to the number "2", add 
284 Stevens as a co-author (control-click), and click Submit.  You will then 
285 be returned to the book list with a "Book edited" message at the top in 
286 green.  Experiment with other edits to various books.
287
288 =head2 See additional documentation on FormHandler
289
290 L<HTML::FormHandler::Manual>
291
292 L<HTML::FormHandler>
293
294    #formhandler on irc.perl.org
295
296    mailing list: http://groups.google.com/group/formhandler
297
298    code: http://github.com/gshank/html-formhandler/tree/master 
299
300 =head1 AUTHOR
301
302 Gerda Shank, C<gshank@cpan.org>
303
304 Copyright 2009, Gerda Shank, Perl Artistic License