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: Catalyst@lists.rawmode.org Listinfo: http://lists.rawmode.org/mailman/listinfo/catalyst Searchable archive: http://www.mail-archive.com/catalyst@lists.rawmode.org/ Dev site: http://dev.catalyst.perl.org/