FAQ
I am a new user to Catalyst, but have done a few small projects using
CGI::Application. In that framework, I tended to not map by URL to page but
used the runmode parameter coded into forms. I am now beginning to see the
power of URL mapping and wondered what other folks are doing when a form is
submitted.

In CGI::App, I typically had a form submit back to itself and them used
something like ->forward (an "internal redirect") to move to the next page
if the form validated. Using URL mapping, one needs to do a real redirect.
I'm just curious what peoples' thoughts are on an idiom that works for
Catalyst, as the two-queries per page (one to collect data, and the second
to do a redirect after the data is validated) seems slightly tedious for
many cases.

Thanks,
Sean

Search Discussions

  • Bill Moseley at Aug 1, 2005 at 10:53 pm

    On Mon, Aug 01, 2005 at 04:19:14PM -0400, Sean Davis wrote:
    In CGI::App, I typically had a form submit back to itself and them used
    something like ->forward (an "internal redirect") to move to the next page
    if the form validated. Using URL mapping, one needs to do a real redirect.
    I'm just curious what peoples' thoughts are on an idiom that works for
    Catalyst, as the two-queries per page (one to collect data, and the second
    to do a redirect after the data is validated) seems slightly tedious for
    many cases.
    I'm new too all this, too. Here's what I'm doing in one controller --
    I'll post in hopes someone can point out what I could do better.. ;)

    This is in a general CRUD controller.


    sub update_record : Private {
    my ( $self, $c ) = @_;

    my $form = $c->form(
    optional => [ qw/ optional / ],
    required => [ qw/ name foo bar active / ],
    constraints => {
    active => qr/(?:0|1)/,
    },
    missing_optional_valid => 1, # see Data::FormValidator
    );

    if ( $form->has_missing || $form->has_invalid ) {
    $c->stash->{message} = 'Fix the form, will ya!';
    $c->stash->{errors} = $form->msgs;
    return $c->forward('edit');
    }

    # "item" was loaded a previous action.

    if ( $c->stash->{item} ) {
    $c->stash->{item}->update_from_form( $c->form );
    } else {
    $c->stash->{class}->create_from_form( $c->form );
    }

    # redisplay the list of items
    $c->forward('list');
    }

    I'm using Catalyst::Plugin::FormValidator and ::FillInForm which does
    a bit of the magic. Namely, it calls FillInForm automatically when it
    seems $form->has_missing or $form->has_invalid.





    --
    Bill Moseley
    moseley@hank.org
  • Kevin Old at Aug 25, 2005 at 9:39 pm

    On 8/1/05, Bill Moseley wrote:
    On Mon, Aug 01, 2005 at 04:19:14PM -0400, Sean Davis wrote:
    In CGI::App, I typically had a form submit back to itself and them used
    something like ->forward (an "internal redirect") to move to the next page
    if the form validated. Using URL mapping, one needs to do a real redirect.
    I'm just curious what peoples' thoughts are on an idiom that works for
    Catalyst, as the two-queries per page (one to collect data, and the second
    to do a redirect after the data is validated) seems slightly tedious for
    many cases.
    I'm new too all this, too. Here's what I'm doing in one controller --
    I'll post in hopes someone can point out what I could do better.. ;) [snip]
    if ( $form->has_missing || $form->has_invalid ) {
    $c->stash->{message} = 'Fix the form, will ya!';
    $c->stash->{errors} = $form->msgs;
    return $c->forward('edit');
    }
    [snip]

    Hi Bill,

    Thanks for the example above. I am implementing this too, and was
    wondering if you have any code showing how you display $form->msgs. I
    see they are a hash of <span> tags, but wondering if there was another
    option in displaying them other than just looping through the hash and
    printing the <span>'s.

    Specifically, I'd like to have the <span> placed beside the field that
    had the problem. One thing I thought about is using some JS to add
    the <span> after the element with the error.

    The only thing is I'm dealing with a "conditional" form. By that I
    mean that I have 20 questions/form elements over all and rather than
    coding a multi-page form, I have some JavaScript that displays the
    appropriate question, based on that question, the next, and so on.
    So, I might just need to display the <span>'s at the top of the page.

    Either way, I'd like to know if you (or anyone on the list) has the
    <span>'s displaying next to the field with the error.

    Any help is greatly appreciated,
    Kevin
    --
    Kevin Old
    kevinold@gmail.com
  • Perrin Harkins at Aug 25, 2005 at 11:34 pm

    On Thu, 2005-08-25 at 15:42 -0400, Kevin Old wrote:
    Thanks for the example above. I am implementing this too, and was
    wondering if you have any code showing how you display $form->msgs. I
    see they are a hash of <span> tags, but wondering if there was another
    option in displaying them other than just looping through the hash and
    printing the <span>'s.
    We turn them into keys to be used to retrieve messages from a
    Class::Phrasebook file.

    This is some code to change a D::FV error about an invalid first_name
    field into the string first_name_invalid:

    sub _errs_to_messages {
    my ($self, $errs) = @_;

    foreach my $field_name ( sort keys %{$errs} ) {
    # decode error type from value set
    my $value = $errs->{$field_name};
    my $error_type;
    if ($value =~ /missing/i) {
    $error_type = 'missing';
    } elsif ($value =~ /invalid/i) {
    $error_type = 'invalid';
    } else {
    croak("Unknown error type for field '$field_name' value
    '$value'");
    }

    # add a message for the error
    add_message("${field_name}_$error_type", from_module => ref
    ($self));
    }
    }
    Specifically, I'd like to have the <span> placed beside the field that
    had the problem.
    For this, we use background colors to highlight the invalid or missing
    fields. For example:
    <input name="first_name" type="text" value="" style="width:
    200px;<tmpl_if err_first_name> background-color: #ffe66b;</tmpl_if>" />

    (We set err_${field_name} for each of the D::FV errors.)
    One thing I thought about is using some JS to add
    the <span> after the element with the error.
    You should be able to get your template to do that.

    - Perrin
  • Kevin Old at Aug 26, 2005 at 3:23 pm
    On 8/25/05, Perrin Harkins wrote:
    [snip]
    200px;<tmpl_if err_first_name> background-color: #ffe66b;</tmpl_if>" />
    Perrin,

    Thanks for the example code. Any idea if HTML::Mason has an
    equivalent of HTML::Template's <tmpl_if>? I'm trying to avoid a huge
    <%perl> block with an if statement in each <input>.


    Thanks for your help,
    Kevin
    --
    Kevin Old
    kevinold@gmail.com
  • João Gomes at Aug 26, 2005 at 5:36 pm

    On Aug 26, 2005, at 2:26 PM, Kevin Old wrote:

    On 8/25/05, Perrin Harkins wrote:
    [snip]
    200px;<tmpl_if err_first_name> background-color: #ffe66b;</
    tmpl_if>" />
    Perrin,

    Thanks for the example code. Any idea if HTML::Mason has an
    equivalent of HTML::Template's <tmpl_if>? I'm trying to avoid a huge
    <%perl> block with an if statement in each <input>.
    <% (condition) ? 'true value to print' : 'false value to print' %>
    --
    Jo?o Gomes
    joao.gomes@log.pt

    Thanks for your help,
    Kevin
    --
    Kevin Old
    kevinold@gmail.com

    _______________________________________________
    Catalyst mailing list
    Catalyst@lists.rawmode.org
    http://lists.rawmode.org/mailman/listinfo/catalyst
  • Perrin Harkins at Aug 26, 2005 at 5:48 pm

    On Fri, 2005-08-26 at 16:39 +0100, Jo?o Gomes wrote:
    <% (condition) ? 'true value to print' : 'false value to print' %>
    Or this:

    % if (condition) {
    background-color: #ffe66b;
    % }

    - Perrin
  • Kevin Old at Aug 26, 2005 at 6:11 pm

    On 8/26/05, Perrin Harkins wrote:
    On Fri, 2005-08-26 at 16:39 +0100, Jo?o Gomes wrote:
    <% (condition) ? 'true value to print' : 'false value to print' %>
    Or this:

    % if (condition) {
    background-color: #ffe66b;
    % }

    - Perrin
    Thanks everyone!
    --
    Kevin Old
    kevinold@gmail.com
  • Thomas L Shinnick at Aug 1, 2005 at 10:54 pm

    At 15:19 8/1/2005, Sean Davis wrote:
    I am a new user to Catalyst, but have done a few small projects using
    CGI::Application. In that framework, I tended to not map by URL to page but
    used the runmode parameter coded into forms. I am now beginning to see the
    power of URL mapping and wondered what other folks are doing when a form is
    submitted.

    In CGI::App, I typically had a form submit back to itself and them used
    something like ->forward (an "internal redirect") to move to the next page
    if the form validated. Using URL mapping, one needs to do a real redirect.
    I'm just curious what peoples' thoughts are on an idiom that works for
    Catalyst, as the two-queries per page (one to collect data, and the second
    to do a redirect after the data is validated) seems slightly tedious for
    many cases.
    One small example of a pattern is shown in the ServerDB example.
    (see Catalyst Wiki catalyst.perl.org front page, section Examples,
    which links to http://www.hybridized.org/catalyst/)

    If you look in the source for its ServerDB::C::Server controller,
    you will see two actions, 'view' and 'do_edit'. 'view' is used to
    display the form (template at root/server/view.xhtml). The form
    references the submit action 'do_edit'. 'do_edit' has the code
    which _could_ do the validation of form values. If there were
    errors it could just as easily do what it already does after
    processing correct values, just forward (not redirect) to action
    'view' to redisplay the form:
    $c->forward('view', join "/", @name);

    If you will notice in some of the other examples and documentation,
    including the plugin FillInForm in the application class
    use Catalyst qw{ -Debug FillInForm ... };
    means that forms easily and automatically (and spookily) have the
    prior form fields value filled in. That is, just redisplaying the
    form will show the problem values!

    So anyway, with the forward() capability, it is easy to have one
    action that displays forms, and another that validates values
    submitted. If there is an error, just forward to the display
    action and return from the submit action. At least, that's _my_ theory. ;)

    Thanks,
    Sean

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupcatalyst @
categoriescatalyst, perl
postedAug 1, '05 at 10:16p
activeAug 26, '05 at 6:11p
posts9
users6
websitecatalystframework.org
irc#catalyst

People

Translate

site design / logo © 2022 Grokbase