Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

jk2addict (4946)

  (email not shown publicly)
AOL IM: chrislaco (Add Buddy, Send Message)
Yahoo! ID: (Add User, Send Message)

Journal of jk2addict (4946)

Friday March 02, 2007
09:19 PM

Die Forms, Die!

[ #32550 ]

In this day and age, it amazes me that doing forms in web apps still sucks serious butt. Sure, we have HTML::FormFu, CGI::FormBuilder, HTML::Widget, Text::FormBuilder, FormValidator::Simple, and Data::FormValidator. They're all great at what they do, but they all suck in unique ways.

C::FB is great at form rendering, from a config file even, but it's validaton is lacking (and it only supports D::FV).

FV::S is great at validation, esp getting messages from config files, but getting profiles from config files is another story, and the YAML soon gets crazy.

D::FV is also a good validator, but I'm not terribly fond at how to get all of the errors our of results and setup custom messages...from config files is worse.

H::W make me feel ill every time I use it. All code, no external config. Easy to localize labels though.

FormFu looks promising, but at this point, I'm in crunch time, and it looks a little large for my needs. It's really good at localizaiton, even using the I18N plugin in Cat to do the job.

OF course, I could just hard code the forms, and just use FV::S, but doing the profiles in YAML is ugly as sin.

So, here it is, 2 weeks of form futzing with the various tools. In the end, just writing my own just to fill my needs seems like the only sane option so I can get back to actually getting work done. Plus, it gives me what I really wnat, a sane external config for form/validation/messages and even less code in most of my controllers.

name: roles_edit
method: POST
javascript: 0
stylesheet: 1
sticky: 1
  - id
  - name
  - description
  - created
    type: hidden
    force: 1
      - NOT_BLANK
      - INT
    type: text
    size: 20
    disabled: 1
    force: 1
      - NOT_BLANK
      - LENGTH, 1, 25
    type: text
    size: 50
      - NOT_BLANK
      - LENGTH, 1, 100
      - INT
    size: 20
    disabled: 1

A litte bit of FB. A little bit of FV::S. A little bit of D::FV. And no ugly nested nested arrays of lists. A little controller code to split that up into the various data bits for FB, D::FV and we're off to the races.

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • while that syntax is nice and clean, it's just a little too simple - because 'fields' is a hashref, and not an arrayref, it means that the order of fields is not guaranteed - which isn't great for a consistent user interface ;)

    $ ./local/bin/perl -MYAML::Syck=LoadFile -MData::Dumper -le '
    my $x = LoadFile( q{test.yaml} );
    print for keys %{ $x->{fields} };

    • Is my face red?

      Sorry, I completely missed the 'field_order' section!

      That's interesting, though when it comes to bigger forms I don't think I'd like having all field names repeated like that.
      • Easy enough to fix I guess, just move fields as an array instead of a hash. Either way, it's small, and works for me for now. And since it's still mostly options based on FB, and FV::S, converting to something else later will be pretty easy.

        One thing I didn't mention is the messages and labels. If no message or label is supplid, they default to LABEL_$FIELDNAME and $FIELDNAME_$CONSTRAINNAME.

        Since those are just keys I use in I18N lexicons, all is well.
  • I've been thinking about this sort of thing a lot, lately. I don't have the answers yet (or maybe ever), but I tried this approach and abandoned it.
    • There's a mix of model and view here, and that coupling sometimes causes problems. But, sometimes you have to let that slide if you want to get things into the javascript.
    • Although you can do low level validation (NOT_BLANK), you can't express complex, multi-field relationships. Take, for instance, a date use case I recently wrangled for a client. First it must b
    • In HTML::Widget, you can create a 'callback' constraint which can validate multiple input fields at once.
      For example,

      $form->constraint( Callback => 'foo', 'bar' )
          ->callback( \&sub );

      The &sub() will receive the input values for both 'foo' and 'bar' as its arguments.

      The HTML::FormFu module [] mentioned by the OP is still under heavy development, and I have a proposal that should provide enough flexibility to solve your problem more easily th