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

Carl Franks fireartist at gmail.com
Tue Oct 14 12:32:43 BST 2008


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
>
>
> =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 %]

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.

Carl



More information about the HTML-FormFu mailing list