Fix date
[catagits/Catalyst-Manual.git] / lib / Catalyst / Manual / Tutorial / AdvancedCRUD / FormFu.pod
CommitLineData
b80f58e5 1=head1 NAME
2
3Catalyst::Manual::Tutorial::AdvancedCRUD::FormFu - Catalyst Tutorial - Part 9: Advanced CRUD - FormFu
4
5
c010ae0d 6NOTE: This part of the tutorial is in progress and will be ready soon.
7
b80f58e5 8=head1 OVERVIEW
9
10This is B<Part 9 of 10> for the Catalyst tutorial.
11
12L<Tutorial Overview|Catalyst::Manual::Tutorial>
13
14=over 4
15
16=item 1
17
18L<Introduction|Catalyst::Manual::Tutorial::Intro>
19
20=item 2
21
22L<Catalyst Basics|Catalyst::Manual::Tutorial::CatalystBasics>
23
24=item 3
25
26L<More Catalyst Basics|Catalyst::Manual::Tutorial::MoreCatalystBasics>
27
28=item 4
29
30L<Basic CRUD|Catalyst::Manual::Tutorial::BasicCRUD>
31
32=item 5
33
34L<Authentication|Catalyst::Manual::Tutorial::Authentication>
35
36=item 6
37
38L<Authorization|Catalyst::Manual::Tutorial::Authorization>
39
40=item 7
41
42L<Debugging|Catalyst::Manual::Tutorial::Debugging>
43
44=item 8
45
46L<Testing|Catalyst::Manual::Tutorial::Testing>
47
48=item 9
49
50B<Advanced CRUD>
51
52=item 10
53
54L<Appendices|Catalyst::Manual::Tutorial::Appendices>
55
56=back
57
58
59=head1 DESCRIPTION
60
cca5cd98 61This portion of the tutorial explores L<HTML::FormFu|HTML::FormFu> and
62how it can be used to manage forms, perform validation of form input,
63as well as save and restore data to/from the database.
64
65See
66L<Catalyst::Manual::Tutorial::AdvancedCRUD|Catalyst::Manual::Tutorial::AdvancedCRUD>
67for additional form management options other than
68L<HTML::FormFu|HTML::FormFu>.
69
70
71=head1 Install C<HTML::FormFu>
72
73If you are following along in Ubuntu, it turns out that C<HTML::FormFu>
74is not yet available as a package at the time this was written. To
75install it with a combination of C<apt-get> packages and traditional
76CPAN modules, first use C<apt-get> to install most of the modules
77required by C<HTML::FormFu>:
78
79 sudo apt-get install libtest-nowarnings-perl libdatetime-format-builder-perl \
80 libdatetime-format-strptime-perl libdatetime-locale-perl \
81 libhtml-tokeparser-simple-perl liblist-moreutils-perl \
82 libregexp-copy-perl libregexp-common-perl libyaml-syck-perl libparams-util-perl
83
84Then use the following command to install directly from CPAN the modules
85that aren't available as Ubuntu/Debian packages via C<apt-get>:
86
87 sudo cpan File::ShareDir Task::Weaken Config::Any HTML::FormFu \
88 Catalyst::Controller::HTML::FormFu
89
90
91=head1 C<HTML::FormFu> FORM CREATION
92
93This section looks at how L<HTML::FormFu|HTML::FormFu> can be used to
94add additional functionality to the manually created form from Part 4.
95
96
97=head2 Inherit From C<Catalyst::Controller::HTML::FormFu>
98
99First, change your C<lib/MyApp/Controller/Books.pm> to inherit from
100L<Catalyst::Controller::HTML::FormFu|Catalyst::Controller::HTML::FormFu>
101by changing the C<use base> line from the default of:
102
103 use base 'Catalyst::Controller';
104
105to use the FormFu base controller class:
106
107 use base 'Catalyst::Controller::HTML::FormFu';
108
109
110=head2 Add Action to Display and Save the Form
111
112Open C<lib/MyApp/Controller/Books.pm> in your editor and add the
113following method:
114
115 =head2 fu_form_create
116
117 Build an HTML::FormFu form for book creation and updates
118
119 =cut
120
121 sub fu_form_create :Local :FormConfig {
122 my ($self, $c) = @_;
123
124 # Get the form that the :FormConfig attribute saved in the stash
125 my $form = $c->stash->{form};
126
127 # Check if the form as been submitted (vs. displaying the initial
128 # form) and if the data based validation. "submitted_and_valid"
129 # is shorthand for "$form->submitted && !$form->has_errors"
130 if ($form->submitted_and_valid) {
131 # Create a new book
132 my $book = $c->model('DB::Books')->new_result({});
133 # Save the form data for the book
134 $form->save_to_model($book);
135 # Set a status message for the user
136 $c->flash->{status_msg} = 'Book created';
137 # Return to the books list
138 $c->response->redirect($c->uri_for('list'));
139 $c->detach;
9cb64a37 140 } else {
141 # Get the authors from the DB
142 my @authorObjs = $c->model("DB::Authors")->all();
143 # Create an array of arrayrefs where each arrayref is an author
144 my @authors;
145 foreach (sort {$a->last_name cmp $b->last_name} @authorObjs) {
146 push(@authors, [$_->id, $_->last_name]);
147 }
148 # Get the select added by the config file
149 my $select = $form->get_element({type => 'Select'});
150 # Add the authors to it
151 $select->options(\@authors);
152 }
153
cca5cd98 154 # Set the template
155 $c->stash->{template} = 'books/fu_form_create.tt2';
156 }
157
158
159=head2 Create a Form Config File
160
161Although C<HTML::FormFu> supports any configuration file handled by
162L<Config::Any|Config::Any>, most people tend to use YAML. First
163create a directory to hold your form configuration files:
164
165 mkdir -p root/forms/books
166
167Then create the file C<root/forms/books/fu_form_create.yml> and enter the
168following text:
169
170 ---
9cb64a37 171 # indicator is the field that is used to test for form submission
cca5cd98 172 indicator: submit
9cb64a37 173 # Start listing the form elements
cca5cd98 174 elements:
9cb64a37 175 # The first element will be a text field for the title
cca5cd98 176 - type: Text
177 name: title
178 label: Title
9cb64a37 179 # This is an optional 'mouse over' title pop-up
cca5cd98 180 attributes:
181 title: Enter a book title here
182 - type: Text
183 name: rating
184 label: Rating
185 attributes:
186 title: Enter a rating between 1 and 5 here
9cb64a37 187 # The submit button
cca5cd98 188 - type: Submit
189 name: submit
190 value: Submit
191
192
193=head2 Update the CSS
194
195Edit C<root/src/ttsite.css> and add the following lines to the bottom of
196the file:
197
198 label {
199 display: block;
200 }
201 .submit {
202 display: block;
203 }
204 .error_messages {
205 color: [% site.col.error %];
206 }
207
208These changes will display form elements vertically and also show error
209messages in red. Note that we are pulling the color scheme settings
210from the C<root/lib/config/col> file that was created by the TTSite
211helper. This allows us to change the color used by various error styles
212in the CSS from a single location.
213
214
215=head2 Create a Template Page To Display The Form
216
217Open C<root/src/books/fu_form_create.tt2> in your editor and enter the following:
218
219 [% META title = 'Create/Update Book' %]
220
221 [%# Render the HTML::FormFu Form %]
222 [% form %]
223
224 <p><a href="[% Catalyst.uri_for('list') %]">Return to book list</a></p>
225
226
227=head2 Add Links for Create and Update via C<HTML::FormFu>
228
229Open C<root/src/books/list.tt2> in your editor and add the following to
230the bottom of the existing file:
231
232 <p>
233 HTML::FormFu:
234 <a href="[% Catalyst.uri_for('fu_form_create') %]">Create</a>
235 </p>
236
237
238=head2 Test The <HTML::Widget> Create Form
239
240Press C<Ctrl-C> to kill the previous server instance (if it's still
241running) and restart it:
242
243 $ script/myapp_server.pl
244
245Login as C<test01>. Once at the Book List page, click the HTML::FormFu
246"Create" link to display for form produced by C<make_book_widget>. Fill
247out the form with the following values: Title = "Internetworking with
248TCP/IP Vol. II", Rating = "4", and Author = "Comer". Click Submit, and
249you will be returned to the Book List page with a "Book created" status
250message displayed.
251
252Also note that this implementation allows you to can create books with
253bogus information. Although we have constrained the authors with the
254drop-down list, there are no restrictions on items such as the length of
255the title (for example, you can create a one-letter title) and value for
256the rating (you can use any number you want, and even non-numeric values
257with SQLite). The next section will address this concern.
258
259B<Note:> Depending on the database you are using and how you established
260the columns in your tables, the database could obviously provide various
261levels of "type enforcement" on your data. The key point being made in
262the previous paragraph is that the I<web application> itself is not
263performing any validation.
264
265
266=head1 C<HTML::FormFu> VALIDATION AND FILTERING
267
268Although the use of L<HTML::FormFu|HTML::FormFu> in the previous section
269did provide an automated mechanism to build the form, the real power of
270this module stems from functionality that can automatically validate and
271filter the user input. Validation uses constraints to be sure that
272users input appropriate data (for example, that the email field of a
273form contains a valid email address). Filtering can be used to remove
274extraneous whitespace from fields or to escape meta-characters in user
275input.
276
277=head2 Add Constraints
278
279
280Open C<root/forms/books/fu_form_create.yml> in your editor and update it
281to match:
282
283 ---
9cb64a37 284 # indicator is the field that is used to test for form submission
cca5cd98 285 indicator: submit
9cb64a37 286 # Start listing the form elements
cca5cd98 287 elements:
9cb64a37 288 # The first element will be a text field for the title
cca5cd98 289 - type: Text
290 name: title
291 label: Title
9cb64a37 292 # This is an optional 'mouse over' title pop-up
cca5cd98 293 attributes:
294 title: Enter a book title here
9cb64a37 295 # Add constraints for the field
cca5cd98 296 constraints:
9cb64a37 297 # The user cannot leave this field blank
cca5cd98 298 - Required
9cb64a37 299 # Force the length to be between 2 and 30 chars
cca5cd98 300 - type: Length
301 min: 2
302 max: 30
9cb64a37 303 # Override the default of 'Invalid input'
cca5cd98 304 message: Length must be between 2 and 30 characters
305 - type: Text
306 name: rating
307 label: Rating
308 attributes:
309 title: Enter a rating between 1 and 5 here
310 constraints:
311 - Required
9cb64a37 312 # Make sure it's a number
cca5cd98 313 - Integer
9cb64a37 314 # The submit button
cca5cd98 315 - type: Submit
316 name: submit
317 value: Submit
9cb64a37 318 # Globally ensure that each field only specified one value
cca5cd98 319 constraints:
320 - SingleValue
321
322...
323
324=head1 AUTHOR
325
326Kennedy Clark, C<hkclark@gmail.com>
327
328Please report any errors, issues or suggestions to the author. The
329most recent version of the Catalyst Tutorial can be found at
330L<http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/>.
331
332Copyright 2006, Kennedy Clark, under Creative Commons License
333(L<http://creativecommons.org/licenses/by-nc-sa/2.5/>).
334