[Catalyst] Forms: Chapter 1647

Christopher H. Laco claco at chrislaco.com
Wed May 30 13:51:13 GMT 2007


Christopher H. Laco wrote:
> Carl Franks wrote:
>> On 24/05/07, Christopher H. Laco <claco at chrislaco.com> wrote:
>>> One of the never ending topics for Catalyst seems to be forms: how to
>>> build them, validate them, localize them and generally just live with
>>> them without hating the toolset or wanting to strangle someone.
>>>
>>> I don't have a solution for everyone, but I did create a solution for
>>> me. I offer it here as yet another piece of the puzzle for those in need
>>> of another path. Feel free to steal the code as you see fit.
>>>
>>> In general, I like FormBuilder for building forms, but I hate its
>>> validation. I like FormValidator::Simples ability to accept yaml profile
>>> configs (ProfileManager::YAML). I hate that it can't also take messages
>>> from yaml, or both in the same shot. And most of all, I hate having to
>>> have at least 3 configs: FB, Profile, Messages) and nothing localizing
>>> everything in the same way. This is a marriage of all three.
>>>
>>> The config file format is simple. The root data is FB options. The
>>> fields collection holds FB field config and constraints (FVS options)
>>> and messages (FVS messages)
>>>
>>>>     ---
>>>>     name: form_name
>>>>     method: POST
>>>>     javascript: 0
>>>>     stylesheet: 1
>>>>     sticky: 1
>>>>     submit: LABEL_CREATE
>>>>     fields:
>>>>       - sku:
>>>>           type: text
>>>>           size: 25
>>>>           maxlength: 25
>>>>           constraints:
>>>>             - NOT_BLANK
>>>>             - LENGTH, 1, 25
>>>>             - UNIQUE
>>>>           messages:
>>>>             - NOT_BLANK: "sku may not be blank"
>>>>       - name:
>>>>           type: text
>>>>           size: 25
>>>>           maxlength: 25
>>>>           constraints:
>>>>             - NOT_BLANK
>>>>             - LENGTH, 1, 25
>>>
>>> If you don't specify a message for a constraint, it defaults to
>>> FIELDNAME_CONSTRAINT. If you don't label a field, it defaults to
>>> LABEL_FIELDNAME. In my case, I use those as keys to a %Lexicon in a I18N
>>> module...they could just as well be real names/messages.
>>>
>>> If you won't want to use yaml, you can just pass the same data structure
>>> to parse/new
>>>
>>>> {
>>>>    name =3D> 'form_name',
>>>>    method =3D> 'POST'
>>>>    fields =3D> [
>>>>       sku =3D> {
>>>>           type =3D> 'text',
>>>>           constraints =3D> [
>>>>               'NOT_BLANK',
>>>>               'LENGTH, 1, 25'
>>>>           ]
>>>>       }
>>>>    ]
>>>> }
>>> When the form is validated/rendered, the labels and messages are all
>>> passed to an I18N sub you specify for localization...
>>>
>>> The api mostly mimics FB usage:
>>>
>>>> my $form =3D Mango::Form->new({
>>>>   source =3D> 'path/to/some/config.yml',
>>>>   values =3D> $object->get_columns,
>>>>   localizer =3D> sub {MyI18N->localize(@_)},
>>>>   params =3D> $c->request
>>>> });
>>>>
>>>> $form->field(name =3D> 'someselect', options =3D> \@options);
>>>>
>>>> $form->render;
>>>>
>>>> if ($form->submitted) {
>>>>   my $results =3D $form->validate;
>>>>   if (!$results->success) {
>>>>       print @{$results->errors};
>>>>   };
>>>> };
>>> The code isn't the greatest under the covers and does some evil , but it
>>> works for me and at least separated my form handling from my controllers
>>> with an API.
>>>
>>> You can steal the form code from here:
>>> http://svn.mangoframework.com/CPAN/Mango/trunk/lib/Mango/Form.pm
>>>
>>> Here's a real config:
>>> http://svn.mangoframework.com/CPAN/Mango/trunk/share/forms/admin/produc=
ts/create.yml
>>>
>>>
>>> It'll change. It'll evolve. It works for me, for now. Have fun with it
>>> if you need it, or parts of it. :-)

Just an update to this thread for those searching later for bits of
code, pointers to magic, and options.

I've finally finished tinkering with a controller base that uses the
Mango::Form magic. It does things like auto form loading/mapping and
with some pointers from mst/jmax, has some custom attribute magic as
well. All in all, bits and pieces of ideas/flow from other form handlers
with out all the code to be a solution for everyone.

http://svn.mangoframework.com/CPAN/Mango/trunk/lib/Mango/Catalyst/Controlle=
r/Form.pm

    ## base auto loads forms in root/forms/foo
    ## root/forms/foo/edit.yml
    ## root/forms/foo/myform.yml
    package MyApp::Contoller:Foo;
    use base 'Mango::Catalyst::Controller::Form';

    sub edit : Local {
        # root/forms/foo/edit.yml
        my $form =3D $self->form;
    };

    sub stuff : Local FormFile('/path/to/otherform.yml') {

    };

    sub bar : Local Form('myform') {

    };

Like I said before. It's not a solution for everyone, but it works for
me. Steal some code. Be happy.

-=3DChris

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 187 bytes
Desc: OpenPGP digital signature
Url : http://lists.scsys.co.uk/pipermail/catalyst/attachments/20070530/c3e8=
fa63/signature.pgp


More information about the Catalyst mailing list