From: Kennedy Clark Date: Wed, 21 May 2008 00:00:00 +0000 (+0000) Subject: Add AdvancedCRUD "cover page" and stub files for FormBuilder.pod and FormFu.pod X-Git-Tag: v5.8005~309 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Manual.git;a=commitdiff_plain;h=b80f58e5f205d099fcd8ab2abcbdda4ab9db32d6 Add AdvancedCRUD "cover page" and stub files for FormBuilder.pod and FormFu.pod --- diff --git a/lib/Catalyst/Manual/Tutorial/AdvancedCRUD.pod b/lib/Catalyst/Manual/Tutorial/AdvancedCRUD.pod index 29b1f95..ad415a0 100644 --- a/lib/Catalyst/Manual/Tutorial/AdvancedCRUD.pod +++ b/lib/Catalyst/Manual/Tutorial/AdvancedCRUD.pod @@ -63,708 +63,26 @@ the Update portion of CRUD, such as automated form generation, validation of user-entered data, and automated transfer of data between forms and model objects. -In keeping with the Catalyst (and Perl) spirit of flexibility, there are -many different ways to approach advanced CRUD operations in a Catalyst -environment. One alternative is to use -L -to instantly construct a set of Controller methods and templates for -basic CRUD operations. Although a popular subject in Quicktime -movies that serve as promotional material for various frameworks, -real-world applications generally require more control. Other -options include L and -L. - -Note that HTML::Widget is no longer maintained. -L was developed as a replacement. There is -an example HTML::FormFu application at -L. -Another popular alternative for HTML FormFu is -L -which is used in the L. - -Here, we will make use of the -L to not only ease form creation, but to -also provide validation of the submitted data. The approached used by -this part of the tutorial is to slowly incorporate additional -L functionality in a step-wise fashion (we -start with fairly simple form creation and then move on to more -complex and "magical" features such as validation and -auto-population/auto-saving). - -B Part 8 of the tutorial is optional. Users who do not wish to -use L may skip this part. - -You can checkout the source code for this example from the catalyst subversion repository as per the instructions in L - -=head1 C FORM CREATION - -This section looks at how L can be used to -add additional functionality to the manually created form from Part 3. - -=head2 Add the C Plugin - -Open C in your editor and add the following to the list of -plugins (be sure to leave the existing plugins enabled): - - HTML::Widget - -=head2 Add a Form Creation Helper Method - -Open C in your editor and add the -following method: - - =head2 make_book_widget - - Build an HTML::Widget form for book creation and updates - - =cut - - sub make_book_widget { - my ($self, $c) = @_; - - # Create an HTML::Widget to build the form - my $w = $c->widget('book_form')->method('post'); - - # Get authors - my @authorObjs = $c->model("MyAppDB::Author")->all(); - my @authors = map {$_->id => $_->last_name } - sort {$a->last_name cmp $b->last_name} @authorObjs; - - # Create the form feilds - $w->element('Textfield', 'title' )->label('Title')->size(60); - $w->element('Textfield', 'rating' )->label('Rating')->size(1); - $w->element('Select', 'authors')->label('Authors') - ->options(@authors); - $w->element('Submit', 'submit' )->value('submit'); - - # Return the widget - return $w; - } - -This method provides a central location that builds an -HTML::Widget-based form with the appropriate fields. The "Get authors" -code uses DBIC to retrieve a list of model objects and then uses C -to create a hash where the hash keys are the database primary keys from -the authors table and the associated values are the last names of the -authors. - -=head2 Add Actions to Display and Save the Form - -Open C in your editor and add the -following methods: - - =head2 hw_create - - Build an HTML::Widget form for book creation and updates - - =cut - - sub hw_create : Local { - my ($self, $c) = @_; - - # Create the widget and set the action for the form - my $w = $self->make_book_widget($c); - $w->action($c->uri_for('hw_create_do')); - - # Write form to stash variable for use in template - $c->stash->{widget_result} = $w->result; - - # Set the template - $c->stash->{template} = 'books/hw_form.tt2'; - } - - - =head2 hw_create_do - - Build an HTML::Widget form for book creation and updates - - =cut - - sub hw_create_do : Local { - my ($self, $c) = @_; - - # Retrieve the data from the form - my $title = $c->request->params->{title}; - my $rating = $c->request->params->{rating}; - my $authors = $c->request->params->{authors}; - - # Call create() on the book model object. Pass the table - # columns/field values we want to set as hash values - my $book = $c->model('MyAppDB::Book')->create({ - title => $title, - rating => $rating - }); - - # Add a record to the join table for this book, mapping to - # appropriate author - $book->add_to_book_authors({author_id => $authors}); - - # Set a status message for the user - $c->stash->{status_msg} = 'Book created'; - - # Use 'hw_create' to redisplay the form. As discussed in - # Part 3, 'detach' is like 'forward', but it does not return - $c->detach('hw_create'); - } - -Note how we use C to build the core parts of the form -in one location, but we set the action (the URL the form is sent to when -the user clicks the 'Submit' button) separately in C. Doing -so allows us to have the same form submit the data to different actions -(e.g., C for a create operation but C to -update an existing book object). - -B If you receive an error about Catalyst not being able to find -the template C, please verify that you followed the -instructions in the final section of -L where -you returned to a manually-specified template. You can either use -C/C B default template names, but the two cannot -be used together. - - -=head2 Update the CSS - -Edit C and add the following lines to the bottom of -the file: - - label { - display: block; - width: 10em; - position: relative; - margin: .5em 0em; - } - label input { - position: absolute; - left: 100%; - } - label select { - position: absolute; - left: 100%; - } - .submit { - margin-top: 2em;; - } - .error_messages { - color: [% site.col.error %]; - } - -These changes will display form elements vertically and also show error -messages in red. Note that we are pulling the color scheme settings -from the C file that was created by the TTSite -helper. This allows us to change the color used by various error styles -in the CSS from a single location. - -=head2 Create a Template Page To Display The Form - -Open C in your editor and enter the following: - - [% META title = 'Create/Update Book' %] - - [% widget_result.as_xml %] - -

Return to book list

- -=head2 Add Links for Create and Update via C - -Open C in your editor and add the following to -the bottom of the existing file: - -

- HTML::Widget: - Create -

- - -=head2 Test The Create Form - -Press C to kill the previous server instance (if it's still -running) and restart it: - - $ script/myapp_server.pl - -Login as C. Once at the Book List page, click the HTML::Widget -"Create" link to display for form produced by C. Fill -out the form with the following values: Title = "Internetworking with -TCP/IP Vol. II", Rating = "4", and Author = "Comer". Click Submit, and -you will be returned to the Create/Update Book page with a "Book -created" status message displayed. Click "Return to book list" to view -the newly created book on the main list. - -Also note that this implementation allows you to can create books with -bogus information. Although we have constrained the authors with the -drop-down list, there are no restrictions on items such as the length of -the title (for example, you can create a one-letter title) and value for -the rating (you can use any number you want, and even non-numeric values -with SQLite). The next section will address this concern. - -B Depending on the database you are using and how you established -the columns in your tables, the database could obviously provide various -levels of "type enforcement" on your data. The key point being made in -the previous paragraph is that the I itself is not -performing any validation. - -=head1 C VALIDATION AND FILTERING - -Although the use of L in the previous section -did provide an automated mechanism to build the form, the real power of -this module stems from functionality that can automatically validate and -filter the user input. Validation uses constraints to be sure that -users input appropriate data (for example, that the email field of a -form contains a valid email address). Filtering can be used to remove -extraneous whitespace from fields or to escape meta-characters in user -input. - -=head2 Add Constraints and Filters to the Widget Creation Method - -Open C in your editor and update the -C method to match the following (new sections have -been marked with a C<*** NEW:> comment): - - sub make_book_widget { - my ($self, $c) = @_; - - # Create an HTML::Widget to build the form - my $w = $c->widget('book_form')->method('post'); - - # Get authors - my @authorObjs = $c->model("MyAppDB::Author")->all(); - my @authors = map {$_->id => $_->last_name } - sort {$a->last_name cmp $b->last_name} @authorObjs; - - # Create the form feilds - $w->element('Textfield', 'title' )->label('Title')->size(60); - $w->element('Textfield', 'rating' )->label('Rating')->size(1); - # ***NEW: Convert to multi-select list - $w->element('Select', 'authors')->label('Authors') - ->options(@authors)->multiple(1)->size(3); - $w->element('Submit', 'submit' )->value('submit'); - - # ***NEW: Set constraints - $w->constraint(All => qw/title rating authors/) - ->message('Required. '); - $w->constraint(Integer => qw/rating/) - ->message('Must be an integer. '); - $w->constraint(Range => qw/rating/)->min(1)->max(5) - ->message('Must be a number between 1 and 5. '); - $w->constraint(Length => qw/title/)->min(5)->max(50) - ->message('Must be between 5 and 50 characters. '); - - # ***NEW: Set filters - for my $column (qw/title rating authors/) { - $w->filter( HTMLEscape => $column ); - $w->filter( TrimEdges => $column ); - } - - # Return the widget - return $w; - } - -The main changes are: +In keeping with the Catalyst (and Perl) spirit of flexibility, there are +many different ways to approach advanced CRUD operations in a Catalyst +environment. Therefore, this section of the tutorial allows you to pick +from one of several modules that that cover different form management +tools. Select one or more options from the list below. -=over 4 - -=item * - -The C