.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler 3pm" .TH Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler 3pm 2024-03-30 "perl v5.38.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler \- Catalyst Tutorial \- Chapter 9: Advanced CRUD \- FormHandler .SH OVERVIEW .IX Header "OVERVIEW" This is \fBChapter 9 of 10\fR for the Catalyst tutorial. .PP Tutorial Overview .IP 1. 4 Introduction .IP 2. 4 Catalyst Basics .IP 3. 4 More Catalyst Basics .IP 4. 4 Basic CRUD .IP 5. 4 Authentication .IP 6. 4 Authorization .IP 7. 4 Debugging .IP 8. 4 Testing .IP 9. 4 \&\fB09_Advanced CRUD::09_FormHandler\fR .IP 10. 4 Appendices .SH DESCRIPTION .IX Header "DESCRIPTION" This portion of the tutorial explores 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. .PP See Catalyst::Manual::Tutorial::09_AdvancedCRUD for additional form management options other than HTML::FormHandler. .SH "Install HTML::FormHandler" .IX Header "Install HTML::FormHandler" Use the following command to install HTML::FormHandler::Model::DBIC directly from CPAN: .PP .Vb 1 \& sudo cpan HTML::FormHandler::Model::DBIC .Ve .PP It will install HTML::FormHandler as a prerequisite. .PP Also, add: .PP .Vb 1 \& requires \*(AqHTML::FormHandler::Model::DBIC\*(Aq; .Ve .PP to your \fIMakefile.PL\fR. .SH "HTML::FormHandler FORM CREATION" .IX Header "HTML::FormHandler FORM CREATION" This section looks at how HTML::FormHandler can be used to add additional functionality to the manually created form from Chapter 4. .SS "Using FormHandler in your controllers" .IX Subsection "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. .SS "Create a Book Form" .IX Subsection "Create a Book Form" Create the directory \fIlib/MyApp/Form\fR. Create \fIlib/MyApp/Form/Book.pm\fR: .PP .Vb 1 \& package MyApp::Form::Book; \& \& use HTML::FormHandler::Moose; \& extends \*(AqHTML::FormHandler::Model::DBIC\*(Aq; \& use namespace::autoclean; \& \& has \*(Aq+item_class\*(Aq => ( default =>\*(AqBooks\*(Aq ); \& has_field \*(Aqtitle\*(Aq; \& has_field \*(Aqrating\*(Aq => ( type => \*(AqInteger\*(Aq ); \& has_field \*(Aqauthors\*(Aq => ( type => \*(AqMultiple\*(Aq, label_column => \*(Aqlast_name\*(Aq ); \& has_field \*(Aqsubmit\*(Aq => ( type => \*(AqSubmit\*(Aq, value => \*(AqSubmit\*(Aq ); \& \& _\|_PACKAGE_\|_\->meta\->make_immutable; \& 1; .Ve .SS "Add Action to Display and Save the Form" .IX Subsection "Add Action to Display and Save the Form" At the top of the \fIlib/MyApp/Controller/Books.pm\fR add: .PP .Vb 1 \& use MyApp::Form::Book; .Ve .PP Add the following methods: .PP .Vb 1 \& =head2 create \& \& Use HTML::FormHandler to create a new book \& \& =cut \& \& sub create : Chained(\*(Aqbase\*(Aq) PathPart(\*(Aqcreate\*(Aq) Args(0) { \& my ($self, $c ) = @_; \& \& my $book = $c\->model(\*(AqDB::Book\*(Aq)\->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 => \*(Aqbooks/form.tt2\*(Aq, 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(\*(Aqlist\*(Aq), \& {mid => $c\->set_status_msg("Book created")})); \& } .Ve .PP These two methods could be combined at this point, but we'll use the 'form' method later when we implement 'edit'. .SS "Create a Template Page To Display The Form" .IX Subsection "Create a Template Page To Display The Form" Open \fIroot/src/books/form.tt2\fR in your editor and enter the following: .PP .Vb 1 \& [% META title = \*(AqCreate/Update Book\*(Aq %] \& \& [%# Render the HTML::FormHandler Form %] \& [% form.render %] \& \&

Return to book list

.Ve .SS "Add Link for Create" .IX Subsection "Add Link for Create" Open \fIroot/src/books/list.tt2\fR in your editor and add the following to the bottom of the existing file: .PP .Vb 5 \& ... \&

\& HTML::FormHandler: \& Create \&

.Ve .PP 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. .SS "Test The HTML::FormHandler Create Form" .IX Subsection "Test The HTML::FormHandler Create Form" Press \f(CW\*(C`Ctrl\-C\*(C'\fR to kill the previous server instance (if it's still running) and restart it: .PP .Vb 1 \& $ script/myapp_server.pl .Ve .PP Login as \f(CW\*(C`test01\*(C'\fR (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: .PP .Vb 3 \& Title = "Internetworking with TCP/IP Vol. II" \& Rating = "4" \& Author = "Comer" .Ve .PP Click the Submit button, and you will be returned to the Book List page with a "Book created" status message displayed. .PP 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. .SS "Add Constraints" .IX Subsection "Add Constraints" Open \fIlib/MyApp/Form/Book.pm\fR in your editor. .PP Restrict the title size and make it required: .PP .Vb 1 \& has_field \*(Aqtitle\*(Aq => ( minlength => 5, maxlength => 40, required => 1 ); .Ve .PP Add range constraints to the 'rating' field: .PP .Vb 1 \& has_field \*(Aqrating\*(Aq => ( type => \*(AqInteger\*(Aq, range_start => 1, range_end => 5 ); .Ve .PP 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: .PP .Vb 2 \& has_field \*(Aqauthors\*(Aq => ( type => \*(AqMultiple\*(Aq, label_column => \*(Aqlast_name\*(Aq, \& required => 1 ); .Ve .PP 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 HTML::FormHandler::Manual. .SS "Try Out the Updated Form" .IX Subsection "Try Out the Updated Form" Press \f(CW\*(C`Ctrl\-C\*(C'\fR to kill the previous server instance (if it's still running) and restart it: .PP .Vb 1 \& $ script/myapp_server.pl .Ve .PP Make sure you are still logged in as \f(CW\*(C`test01\*(C'\fR 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. .SS "Create the 'edit' method" .IX Subsection "Create the 'edit' method" Edit \fIlib/MyApp/Controller/Books.pm\fR and add the following method: .PP .Vb 1 \& =head2 edit \& \& Edit an existing book with FormHandler \& \& =cut \& \& sub edit : Chained(\*(Aqobject\*(Aq) PathPart(\*(Aqedit\*(Aq) Args(0) { \& my ( $self, $c ) = @_; \& \& return $self\->form($c, $c\->stash\->{object}); \& } .Ve .PP Update the \fIroot/src/books/list.tt2\fR, adding an 'edit' link below the "Delete" link to use the FormHandler edit method: .PP .Vb 6 \& \& [% # Add a link to delete a book %] \& Delete \& [% # Add a link to edit a book %] \& Edit \& .Ve .SS "Try Out the Edit/Update Feature" .IX Subsection "Try Out the Edit/Update Feature" Press \f(CW\*(C`Ctrl\-C\*(C'\fR to kill the previous server instance (if it's still running) and restart it: .PP .Vb 1 \& $ script/myapp_server.pl .Ve .PP Make sure you are still logged in as \f(CW\*(C`test01\*(C'\fR and go to the 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. .SS "See additional documentation on FormHandler" .IX Subsection "See additional documentation on FormHandler" HTML::FormHandler::Manual .PP HTML::FormHandler .PP .Vb 1 \& #formhandler on irc.perl.org \& \& mailing list: http://groups.google.com/group/formhandler \& \& code: http://github.com/gshank/html\-formhandler/tree/master .Ve .SH AUTHOR .IX Header "AUTHOR" Gerda Shank, \f(CW\*(C`gshank@cpan.org\*(C'\fR .PP Copyright 2009, Gerda Shank, Perl Artistic License