[Catalyst] automatic form generation based on data models

Bill Moseley moseley at hank.org
Wed Nov 8 22:17:53 GMT 2006


On Wed, Nov 08, 2006 at 09:41:56PM +0000, Josef Karthauser wrote:
> On Wed, Nov 08, 2006 at 12:13:53PM -0800, Bill Moseley wrote:
> > Well, in my case currently this is all I'd need to do:
> > 
> >     [% # Template to generate a standard form
> > 
> >         WRAPPER form_wrapper;
> >             FOR f = form.fields;
> >                 field(form, f );
> >             END;
> >         END;
> > 
> >     %]
> 
> Hi Bill,
> 
> Which module are you using to get this syntax?

I have my own form module.  I had started with with sub-classing
Rose::HTML::Objects to add in code to interface with the Model, but
in the end it was just as easy to start from scratch.  My form code
doesn't do any HTML generation (I have a template that knows how to do
that).  Currently, I only have a form model class for working with
Class::DBI, but for months I've wanted to find time to add in a model
class for DBIC.  Some day I'll get to it.

"Form" might be a misnomer -- in my case I wanted something that knew
how to map between CGI parameters and the model, with validation
in between.  The actual HTML form generation was just templates.

> I've started using HTML::Widget, building the edit boxes within the
> controller, and then formatting them in the template:

I don't see that as a function of the controller, I guess.  My
controller just creates the form object, pass in the request parameters
and then if the form validates the form updates the model.  If the
form doesn't validate I display the form.  Here's more of an overview,
if curious:

    http://lists.rawmode.org/pipermail/catalyst/2006-September/009721.html

> The real mess comes though with views which contain data from other
> tables, i.e. $record->owner->username for instance, which in the
> template would look like record.owner.username.  This is a bit of pain
> actually, because there is no such column as "owner.username", i.e. I
> can't do
> 
> 	[% field = "owner.username"; record.field %]
> 
> This means I have to be very careful with column names, both in
> the record, and in the widget.

I guess I don't follow.  Maybe my forms are not that advanced -- or
maybe it's that I have to define a form module that describes the
form.  They are not just automatically created based on the model.
Again, I find that I always have to define by hand what fields should
be in the form, so this setup works well for me.

A form module can have an "object_class" which is basically which
table the form updates.  And the form model class can lookup
relationships in that object class, so if I define a form field:

    state   => 'Select',

the form knows to look up what table the state column references and
then populate the possible options from the lookup table.

The code also knows how to update many-to-many relationships
automatically.  But, for more complex forms (that might update more
than one table) I have to override "update_from_form" in the module
that defines the form.

Hum. Does that make any sense?



-- 
Bill Moseley
moseley at hank.org




More information about the Catalyst mailing list