Christopher H. Laco wrote:
> Carl Franks wrote:
>> On 24/05/07, Christopher H. Laco <[EMAIL PROTECTED]> 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 => 'form_name',
>>>> method => 'POST'
>>>> fields => [
>>>> sku => {
>>>> type => 'text',
>>>> constraints => [
>>>> '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 = Mango::Form->new({
>>>> source => 'path/to/some/config.yml',
>>>> values => $object->get_columns,
>>>> localizer => sub {MyI18N->localize(@_)},
>>>> params => $c->request
>>>> });
>>>>
>>>> $form->field(name => 'someselect', options => [EMAIL PROTECTED]);
>>>>
>>>> $form->render;
>>>>
>>>> if ($form->submitted) {
>>>> my $results = $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/products/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/Controller/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 = $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. -=Chris
signature.asc
Description: OpenPGP digital signature
_______________________________________________ List: [email protected] Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/[email protected]/ Dev site: http://dev.catalyst.perl.org/
