File: 09_FormHandler.pod

package info (click to toggle)
libcatalyst-manual-perl 5.9004-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 820 kB
  • sloc: perl: 1,974; makefile: 2
file content (305 lines) | stat: -rw-r--r-- 8,050 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
=head1 NAME

Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler - Catalyst Tutorial - Chapter 9: Advanced CRUD - FormHandler


=head1 OVERVIEW

This is B<Chapter 9 of 10> for the Catalyst tutorial.

L<Tutorial Overview|Catalyst::Manual::Tutorial>

=over 4

=item 1

L<Introduction|Catalyst::Manual::Tutorial::01_Intro>

=item 2

L<Catalyst Basics|Catalyst::Manual::Tutorial::02_CatalystBasics>

=item 3

L<More Catalyst Basics|Catalyst::Manual::Tutorial::03_MoreCatalystBasics>

=item 4

L<Basic CRUD|Catalyst::Manual::Tutorial::04_BasicCRUD>

=item 5

L<Authentication|Catalyst::Manual::Tutorial::05_Authentication>

=item 6

L<Authorization|Catalyst::Manual::Tutorial::06_Authorization>

=item 7

L<Debugging|Catalyst::Manual::Tutorial::07_Debugging>

=item 8

L<Testing|Catalyst::Manual::Tutorial::08_Testing>

=item 9

B<09_Advanced CRUD::09_FormHandler>

=item 10

L<Appendices|Catalyst::Manual::Tutorial::10_Appendices>

=back


=head1 DESCRIPTION

This portion of the tutorial explores
L<HTML::FormHandler> and how it can be used to manage
forms, perform validation of form input, and save and restore data
to or from the database. This was written using HTML::FormHandler version
0.28001.

See 
L<Catalyst::Manual::Tutorial::09_AdvancedCRUD>
for additional form management options other than 
L<HTML::FormHandler>.


=head1 Install HTML::FormHandler


Use the following command to install L<HTML::FormHandler::Model::DBIC> directly
from CPAN:

    sudo cpan HTML::FormHandler::Model::DBIC 

It will install L<HTML::FormHandler> as a prerequisite. 

Also, add:

    requires 'HTML::FormHandler::Model::DBIC';

to your C<Makefile.PL>.

=head1 HTML::FormHandler FORM CREATION

This section looks at how L<HTML::FormHandler> can be used to 
add additional functionality to the manually created form from Chapter 4.


=head2 Using FormHandler in your controllers 

FormHandler doesn't have a Catalyst base controller, because interfacing
to a form is only a couple of lines of code.

=head2 Create a Book Form

Create the directory C<lib/MyApp/Form>. Create C<lib/MyApp/Form/Book.pm>:

    package MyApp::Form::Book;

    use HTML::FormHandler::Moose;
    extends 'HTML::FormHandler::Model::DBIC';
    use namespace::autoclean;

    has '+item_class' => ( default =>'Books' );
    has_field 'title';
    has_field 'rating' => ( type => 'Integer' );
    has_field 'authors' => ( type => 'Multiple', label_column => 'last_name' );
    has_field 'submit' => ( type => 'Submit', value => 'Submit' );

    __PACKAGE__->meta->make_immutable;
    1;


=head2 Add Action to Display and Save the Form

At the top of the C<lib/MyApp/Controller/Books.pm> add:

   use MyApp::Form::Book;

Add the following methods:

    =head2 create

    Use HTML::FormHandler to create a new book

    =cut

    sub create : Chained('base') PathPart('create') Args(0) {
        my ($self, $c ) = @_;

        my $book = $c->model('DB::Book')->new_result({});
        return $self->form($c, $book);
    }

    =head2 form

    Process the FormHandler book form

    =cut

    sub form {
        my ( $self, $c, $book ) = @_;

        my $form = MyApp::Form::Book->new;
        # Set the template
        $c->stash( template => 'books/form.tt2', form => $form );
        $form->process( item => $book, params => $c->req->params );
        return unless $form->validated;
        # Set a status message for the user & return to books list
        $c->response->redirect($c->uri_for($self->action_for('list'),
            {mid => $c->set_status_msg("Book created")}));
    }

These two methods could be combined at this point, but we'll use the 'form'
method later when we implement 'edit'.


=head2 Create a Template Page To Display The Form

Open C<root/src/books/form.tt2> in your editor and enter the following:

    [% META title = 'Create/Update Book' %]
    
    [%# Render the HTML::FormHandler Form %]
    [% form.render %]
    
    <p><a href="[% c.uri_for(c.controller.action_for('list')) %]">Return to book list</a></p>


=head2 Add Link for Create

Open C<root/src/books/list.tt2> in your editor and add the following to
the bottom of the existing file:

    ...
    <p>
      HTML::FormHandler:
      <a href="[% c.uri_for(c.controller.action_for('create')) %]">Create</a>
    </p>

This adds a new link to the bottom of the book list page that we can
use to easily launch our HTML::FormHandler-based form.


=head2 Test The HTML::FormHandler Create Form

Press C<Ctrl-C> to kill the previous server instance (if it's still
running) and restart it:

    $ script/myapp_server.pl

Login as C<test01> (password: mypass).  Once at the Book List page,
click the new HTML::Formhandler "Create" link at the bottom to display the
form.  Fill in the following values:

    Title  = "Internetworking with TCP/IP Vol. II"
    Rating = "4"
    Author = "Comer"
    
Click the Submit button, and you will be returned to the Book List page
with a "Book created" status message displayed.

Note that because the 'Author' column is a Select list, only the authors
in the database can be entered. The 'ratings' field will only accept
integers. 


=head2 Add Constraints

Open C<lib/MyApp/Form/Book.pm> in your editor. 

Restrict the title size and make it required:

   has_field 'title' => ( minlength => 5, maxlength => 40, required => 1 );

Add range constraints to the 'rating' field:

   has_field 'rating' => ( type => 'Integer', range_start => 1, range_end => 5 );

The 'authors' relationship is a 'many-to-many' pseudo-relation, so this field
can be set to Multiple to allow the selection of multiple authors; also, make it
required:

   has_field 'authors' => ( type => 'Multiple', label_column => 'last_name',
                            required => 1 );

Note: FormHandler automatically strips whitespace at the beginning and
end of fields. If you want some other kind of stripping (or none) you
can specify it explicitly; see L<HTML::FormHandler::Manual>.

=head2 Try Out the Updated Form

Press C<Ctrl-C> to kill the previous server instance (if it's still 
running) and restart it:

    $ script/myapp_server.pl

Make sure you are still logged in as C<test01> and try adding a book 
with various errors: title less than 5 characters, non-numeric rating, a 
rating of 0 or 6, etc.  Also try selecting one, two, and zero authors. 

=head2 Create the 'edit' method

Edit C<lib/MyApp/Controller/Books.pm> and add the following method:

 
    =head2 edit

    Edit an existing book with  FormHandler

    =cut

    sub edit : Chained('object') PathPart('edit') Args(0) {
        my ( $self, $c ) = @_;

        return $self->form($c, $c->stash->{object});
    }

Update the C<root/src/books/list.tt2>, adding an 'edit' link below the
"Delete" link to use the FormHandler edit method:

    <td>
      [% # Add a link to delete a book %]
      <a href="[% c.uri_for(c.controller.action_for('delete'), [book.id]) %]">Delete</a>
      [% # Add a link to edit a book %]
      <a href="[% c.uri_for(c.controller.action_for('edit'), [book.id]) %]">Edit</a>
    </td>


=head2 Try Out the Edit/Update Feature

Press C<Ctrl-C> to kill the previous server instance (if it's still 
running) and restart it:

    $ script/myapp_server.pl

Make sure you are still logged in as C<test01> and go to the 
L<http://localhost:3000/books/list> URL in your browser.  Click the 
"Edit" link next to "Internetworking with TCP/IP Vol. II", change the 
rating to a 3, the "II" at end of the title to the number "2", add 
Stevens as a co-author (control-click), and click Submit.  You will then 
be returned to the book list with a "Book edited" message at the top in 
green.  Experiment with other edits to various books.

=head2 See additional documentation on FormHandler

L<HTML::FormHandler::Manual>

L<HTML::FormHandler>

   #formhandler on irc.perl.org

   mailing list: http://groups.google.com/group/formhandler

   code: http://github.com/gshank/html-formhandler/tree/master 

=head1 AUTHOR

Gerda Shank, C<gshank@cpan.org>

Copyright 2009, Gerda Shank, Perl Artistic License