[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