[html-formfu] Displaying 2 forms in the same page

Andreas Marienborg omega at palle.net
Tue Oct 14 08:59:26 BST 2008


On Oct 13, 2008, at 9:10 PM, Matija Grabnar wrote:

> Andreas Marienborg wrote:
>> Something like that?
>>
>> If no-one objects, I'll commit it tomorrow
>>
>>
>> - andreas
>
> That looks very nice, but, if you'll permit me an observation, it  
> only covers the part with the rendering of the two forms.
>
> Would it be possible for you to document the other part of the  
> usage, too? (I mean the part where you decide which form was  
> submitted, and then process it). It may seem obvious to you, and I  
> **think** I can see how it would be done, but having it spelled out  
> would certainly make it easier for people who are just coming to  
> catalyst/form-fu.
>

More like this? this is untested, and written by memory :p someone  
might wanna write a test-application based on it?

- andreas


=head2 Multiple forms using Catalyst::Controller::HTML::FormFu

Sometimes you need to display multiple forms on a single page. If you
try to use FormConfig on several actions in a chain, or similar, they
all use $c->stash->{form} to store the form, hence you only get the last
form.

One way to work around such problems is to do a little of the work  
yourself:

In this example we have a login_form that we want on every page

     # root/forms/login.yml:
     ---
         indicator: username
         elements:
             -
                 type: Text
                 name: username
                 constraints:
                     - Required
     ...

We also have an edit-form

     # root/forms/foo/edit.yml
     ---
         indicator: name
         elements:
         -
             type: Text
             name: name
             constraints:
                 - Required
         -
             type: Password
             name: password
             constraints:
                 - Required
     ...

We load this in the top-most auto action:

     package MyApp::Controller::Root;

     use parent 'Catalyst::Controller::HTML::FormFu';

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

         # We want to utilize alot of the magic that the controller
         # gives us, so therefore we call $self->form like this

         my $login_form = $self->form;
         $login_form->load_config('forms/login.yml');

         # Notice how we put it into another stash var, not 'form'
         $c->stash->{login_form} = $login_form;

         # Since we set indicator, we should only end up here if we
         # have a username in the form
         $login_form->process();

         if ($login_form->submitted_and_valid) {
             $c->authenticate({
                 username => $login_form->field_value('username'),
                 password => $login_form->field_value('password'),
             });
         }
     }


Any other page that wants to load another form, can now do so freely:

     package MyApp::Controller::Foo;

     sub edit : Local FormConfig {
         my ( $self, $c, $id ) = @_;

         my $form = $c->stash->{form};
         my $item = $c->model('DBIC::Foo')->find($id);
         if ($form->submitted_and_valid) {
             # Do whatever you want with it :p
             $form->model->update($item);
         }
     }

In the view-land we now have two stash-variables:

     root/foo/edit.tt
     [% login_form %]
     <h2>edit</h2>
     [% form %]

  
   



More information about the HTML-FormFu mailing list