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

Andreas Marienborg omega at palle.net
Thu Oct 16 09:04:58 BST 2008


On Oct 14, 2008, at 1:32 PM, Carl Franks wrote:

> 2008/10/14 Andreas Marienborg <omega at palle.net>:
>>
>> 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
>>
>>
>>
> Personally, I would set an 'action' for the login form
>    ---
>    action: __c.uri_for('/login')__
>
> and only check if the login form is submitted in a login() action,
> rather than doing it for every request.


I usually handle it like I did in the example, but an unless ($c- 
 >user_exists) { } around might be a good idea to not process and auth  
every request.

=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;
         unless ($c->user_exists) {

             $login_form->process();

             if ($login_form->submitted_and_valid) {

                 # Since we set indicator, we should only end up here  
if we
                 # have a username in the form
                 $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