X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FCatalyst-Manual.git;a=blobdiff_plain;f=lib%2FCatalyst%2FManual%2FTutorial%2FAdvancedCRUD%2FFormFu.pod;h=367b85079afd0a2eeba37c8056a814df19d1e46b;hp=38eab9b0d3b57c3d8dc479be3b83d973962aac9c;hb=166c90a081d8b306ea1c8965f611c6ca317caec0;hpb=c010ae0de590159369925f16f03dcad4732a91e6 diff --git a/lib/Catalyst/Manual/Tutorial/AdvancedCRUD/FormFu.pod b/lib/Catalyst/Manual/Tutorial/AdvancedCRUD/FormFu.pod index 38eab9b..367b850 100644 --- a/lib/Catalyst/Manual/Tutorial/AdvancedCRUD/FormFu.pod +++ b/lib/Catalyst/Manual/Tutorial/AdvancedCRUD/FormFu.pod @@ -47,7 +47,7 @@ L =item 9 -B +B =item 10 @@ -58,3 +58,567 @@ L =head1 DESCRIPTION +This portion of the tutorial explores L and +how it can be used to manage forms, perform validation of form input, +as well as save and restore data to/from the database. + +See +L +for additional form management options other than +L. + + +=head1 Install C + +If you are following along in Ubuntu, it turns out that C +is not yet available as a package at the time this was written. To +install it with a combination of C packages and traditional +CPAN modules, first use C to install most of the modules +required by C: + + sudo apt-get install libtest-nowarnings-perl libdatetime-format-builder-perl \ + libdatetime-format-strptime-perl libdatetime-locale-perl \ + libhtml-tokeparser-simple-perl liblist-moreutils-perl \ + libregexp-copy-perl libregexp-common-perl libyaml-syck-perl libparams-util-perl + +Then use the following command to install directly from CPAN the modules +that aren't available as Ubuntu/Debian packages via C: + + sudo cpan File::ShareDir Task::Weaken Config::Any HTML::FormFu \ + Catalyst::Controller::HTML::FormFu + + +=head1 C FORM CREATION + +This section looks at how L can be used to +add additional functionality to the manually created form from Part 4. + + +=head2 Inherit From C + +First, change your C to inherit from +L +by changing the C line from the default of: + + use base 'Catalyst::Controller'; + +to use the FormFu base controller class: + + use base 'Catalyst::Controller::HTML::FormFu'; + + +=head2 Add Action to Display and Save the Form + +Open C in your editor and add the +following method: + + =head2 formfu_create + + Use HTML::FormFu to create a new book + + =cut + + sub formfu_create :Local :FormConfig { + my ($self, $c) = @_; + + # Get the form that the :FormConfig attribute saved in the stash + my $form = $c->stash->{form}; + + # Check if the form has been submitted (vs. displaying the initial + # form) and if the data passed validation. "submitted_and_valid" + # is shorthand for "$form->submitted && !$form->has_errors" + if ($form->submitted_and_valid) { + # Create a new book + my $book = $c->model('DB::Books')->new_result({}); + # Save the form data for the book + $form->save_to_model($book); + # Set a status message for the user + $c->flash->{status_msg} = 'Book created'; + # Return to the books list + $c->response->redirect($c->uri_for('list')); + $c->detach; + } else { + # Get the authors from the DB + my @authorObjs = $c->model("DB::Authors")->all(); + # Create an array of arrayrefs where each arrayref is an author + my @authors; + foreach (sort {$a->last_name cmp $b->last_name} @authorObjs) { + push(@authors, [$_->id, $_->last_name]); + } + # Get the select added by the config file + my $select = $form->get_element({type => 'Select'}); + # Add the authors to it + $select->options(\@authors); + } + + # Set the template + $c->stash->{template} = 'books/formfu_create.tt2'; + } + + +=head2 Create a Form Config File + +Although C supports any configuration file handled by +L, most people tend to use YAML. First +create a directory to hold your form configuration files: + + mkdir -p root/forms/books + +Then create the file C and enter the +following text: + + --- + # indicator is the field that is used to test for form submission + indicator: submit + # Start listing the form elements + elements: + # The first element will be a text field for the title + - type: Text + name: title + label: Title + # This is an optional 'mouse over' title pop-up + attributes: + title: Enter a book title here + + # Another text field for the numeric rating + - type: Text + name: rating + label: Rating + attributes: + title: Enter a rating between 1 and 5 here + + # Add a drop-down list for the author selection. Note that we will + # dynamically fill in all the authors from the controller but we + # could manually set items in the drop-list by adding this YAML code: + # options: + # - [ '1', 'Bastien' ] + # - [ '2', 'Nasseh' ] + - type: Select + name: authors + label: Author + + # The submit button + - type: Submit + name: submit + value: Submit + +B Copying and pasting YAML from perl documentation is sometimes +tricky. See the L section of +this document for a more foolproof config format. + + +=head2 Update the CSS + +Edit C and add the following lines to the bottom of +the file: + + input { + display: block; + } + select { + display: block; + } + .submit { + padding-top: .5em; + display: block; + } + +These changes will display form elements vertically. Note that the +existing definition of the C<.error> class is pulling the color scheme +settings from the C file that was created by the +TTSite helper. This allows control over the CSS color settings 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' %] + + [%# Render the HTML::FormFu Form %] + [% form %] + +

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::FormFu: + Create +

+ +This adds a new link to the bottom of the book list page that we can +use to easily launch our HTML::FormFu-based form. + + +=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 (password: mypass). Once at the Book List page, +click the new HTML::FormFu "Create" link at the bottom to display the +form. Fill in the following values: Title = "Internetworking with +TCP/IP Vol. II", Rating = "4", and Author = "Comer". Click Submit, +and you will be returned to the Book List page with a "Book created" +status message displayed. + +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 (note that this isn't bulletproof because we still have +not prevented a user from "hacking" the form to specify other values), +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 also be used to +remove extraneous whitespace from fields or to escape meta-characters in +user input. + + +=head2 Add Constraints + +Open C in your editor and update it +to match: + + --- + # indicator is the field that is used to test for form submission + indicator: submit + # Start listing the form elements + elements: + # The first element will be a text field for the title + - type: Text + name: title + label: Title + # This is an optional 'mouse over' title pop-up + attributes: + title: Enter a book title here + # Use Filter to clean up the input data + filter: + # Remove whitespace at both ends + - TrimEdges + # Escape HTML characters for safety + - HTMLEscape + # Add constraints for the field + constraints: + # The user cannot leave this field blank + - SingleValue + # Force the length to be between 5 and 40 chars + - type: Length + min: 5 + max: 40 + # Override the default of 'Invalid input' + message: Length must be between 5 and 40 characters + + # Another text field for the numeric rating + - type: Text + name: rating + label: Rating + attributes: + title: Enter a rating between 1 and 5 here + # Use Filter to clean up the input data + filter: + # Remove whitespace at both ends + - TrimEdges + # Remove everything except digits + - NonNumeric + # Add constraints to the field + constraints: + - SingleValue + # Make sure it's a number + - Integer + + # Add a select list for the author selection. Note that we will + # dynamically fill in all the authors from the controller but we + # could manually set items in the select by adding this YAML code: + # options: + # - [ '1', 'Bastien' ] + # - [ '2', 'Nasseh' ] + - type: Select + name: authors + label: Author + # Convert the drop-down to a multi-select list + multiple: 1 + # Display 3 entries (user can scroll to see others) + size: 3 + # One could argue we don't need to do filters or constraints for + # a select list, but it's smart to do validation and sanity + # checks on this data in case a user "hacks" the input + # Use Filter to clean up the input data + filter: + # Remove whitespace at both ends + - TrimEdges + # Escape HTML characters for safety + - HTMLEscape + # Add constraints to the field + constraints: + # Make sure it's a number + - Integer + + # The submit button + - type: Submit + name: submit + value: Submit + + # Globally ensure that each field only specified one value + constraints: + # The user cannot leave any fields blank + - Required + +B Copying and pasting YAML from perl documentation is sometimes +tricky. See the L section of +this document for a more foolproof config format. + +The main changes are: + +=over 4 + +=item * + +The C