Why not adopt me?
NAME
Class::DBI::FormBuilder - Class::DBI/CGI::FormBuilder integration
SYNOPSIS
package Film;
use strict;
use warnings;
use base 'Class::DBI';
use Class::DBI::FormBuilder;
# POST all forms to server
Film->form_builder_defaults( { method => 'post' } );
# These fields must always be submitted for create/update routines
Film->columns( Required => qw( foo bar ) );
# same thing, differently
# Film->form_builder_defaults->{required} = [ qw( foo bar ) ];
# In a nearby piece of code...
my $film = Film->retrieve( $id );
print $film->as_form( params => $q )->render; # or $r if mod_perl
# For a search app:
my $search_form = Film->search_form; # as_form plus a few tweaks
# A fairly complete app:
my $form = Film->as_form( params => $q ); # or $r if mod_perl
if ( $form->submitted and $form->validate )
{
# whatever you need:
my $obj = Film->create_from_form( $form );
my $obj = Film->update_from_form( $form );
my $obj = Film->update_or_create_from_form( $form );
my $obj = Film->retrieve_from_form( $form );
my $iter = Film->search_from_form( $form );
my $iter = Film->search_like_from_form( $form );
my $iter = Film->search_where_from_form( $form );
my $obj = Film->find_or_create_from_form( $form );
my $obj = Film->retrieve_or_create_from_form( $form );
print $form->confirm;
}
else
{
print $form->render;
}
# See CGI::FormBuilder docs and website for lots more information.
DESCRIPTION
This module creates a CGI::FormBuilder form from a CDBI class or object. If from an object, it populates the form fields with the object's values.
Column metadata and CDBI relationships are analyzed and the fields of the form are modified accordingly. For instance, MySQL enum
and set
columns are configured as select
, radiobutton
or checkbox
widgets as appropriate, and appropriate widgets are built for has_a
, has_many
and might_have
relationships. Further relationships can be added by subclassing.
A demonstration app (using Maypole::FormBuilder) can be viewed at
http://beerfb.riverside-cms.co.uk
METHODS
All the methods described here are exported into the caller's namespace, except for the form modifiers (see below).
Form generating methods
- form_builder_defaults( %args )
-
Stores default arguments for the call to
CGI::FormBuilder::new()
. - as_form( %args )
-
Builds a CGI::FormBuilder form representing the class or object.
Takes default arguments from
form_builder_defaults
.The optional hash of arguments is the same as for
CGI::FormBuilder::new()
, and will override any keys inform_builder_defaults
.Note that parameter merging is likely to become more sophisticated in future releases (probably copying the argument merging code from CGI::FormBuilder itself).
- search_form( %args )
-
Build a form with inputs that can be fed to
search_where_from_form
. For instance, all selects are multiple.In many cases, you will want to design your own search form, perhaps only searching on a subset of the available columns. Note that you can acheive that by specifying
fields => [ qw( only these fields ) ]
in the args.
The following search options are available:
- search_opt_cmp
-
Allow the user to select a comparison operator by passing an arrayref:
search_opt_cmp => [ ( '=', '!=', '<', '<=', '>', '>=', 'LIKE', 'NOT LIKE', 'REGEXP', 'NOT REGEXP', 'REGEXP BINARY', 'NOT REGEXP BINARY', ) ]
Or, transparently set the search operator in a hidden field:
search_opt_cmp => 'LIKE'
- search_opt_order_by
-
If true, will generate a widget to select (possibly multiple) columns to order the results by, with an
ASC
andDESC
option for each column.If set to an arrayref, will use that to build the widget.
# order by any columns search_opt_order_by => 1 # or just offer a few search_opt_order_by => [ 'foo', 'foo DESC', 'bar' ]
Form modifiers
These methods use CDBI's knowledge about its columns and table relationships to tweak the form to better represent a CDBI object or class. They can be overridden if you have better knowledge than CDBI does. For instance, form_options
only knows how to figure out select-type columns for MySQL databases.
You can handle new relationship types by subclassing, and writing suitable form_*
methods (e.g. form_many_many)
. Your custom methods will be automatically called on the relevant fields.
-
Ensures primary column fields are included in the form (even if they were not included in the
fields
list), and hides them. - form_options
-
Identifies column types that should be represented as select, radiobutton or checkbox widgets. Currently only works for MySQL
enum
columns.There is a simple patch for Class::DBI::mysql that enables this for MySQL
set
columns - see http://rt.cpan.org/NoAuth/Bug.html?id=12971Patches are welcome for similar column types in other RDBMS's.
Note that you can easily emulate a MySQL
enum
column by setting the validation for the column to an arrayref of values. Haven't poked around yet to see how easily aset
column can be emulated. - form_has_a
-
Populates a select-type widget with entries representing related objects. Makes the field required.
Note that this list will be very long if there are lots of rows in the related table. You may need to override this method in that case. For instance, overriding with a no-op will result in a standard
text
type input widget.This method assumes the primary key is a single column - patches welcome.
Retrieves every row and creates an object for it - not good for large tables.
- form_has_many
-
Also assumes a single primary column.
- form_might_have
-
Also assumes a single primary column.
Form handling methods
Note: if you want to use this module alongside Class::DBI::FromForm, load the module like so
use Class::DBI::FormBuilder BePoliteToFromForm => 1;
and the following 2 methods will instead be imported as create_from_fb
and update_from_fb
.
You might want to do this if you have more complex validation requirements than CGI::FormBuilder provides.
All these methods check the form like this
return unless $fb->submitted && $fb->validate;
which allows you to say things like
print Film->update_from_form( $form ) ? $form->confirm : $form->render;
That's pretty concise!
- create_from_form( $form )
-
Creates and returns a new object.
- update_from_form( $form )
-
Updates an existing CDBI object.
If called on an object, will update that object.
If called on a class, will first retrieve the relevant object (via
retrieve_from_form
). - update_or_create_from_form
-
Class method.
Attempts to look up an object (using primary key data submitted in the form) and update it.
If none exists (or if no values for primary keys are supplied), a new object is created.
Search methods
Note that search methods (except for retrieve_from_form
) will return a CDBI iterator in scalar context, and a (possibly empty) list of objects in list context.
All the search methods require that the submitted form should either be built using search_form
(not as_form
), or should supply all required
(including has_a
) fields.
- retrieve_from_form
-
Use primary key data in a form to retrieve a single object.
- search_from_form
-
Lookup by column values.
- search_like_from_form
-
Allows wildcard searches (% or _).
Note that the submitted form should be built using
search_form
, notas_form
. - search_where_from_form
-
Class::DBI::AbstractSearch must be loaded in your CDBI class for this to work.
If no search terms are specified, then the search
WHERE 1 = 1
is executed (returns all rows), no matter what search operator may have been selected.
- find_or_create_from_form
-
Does a
find_or_create
using submitted form data. - retrieve_or_create_from_form
-
Attempts to look up an object. If none exists, a new object is created.
This is similar to
update_or_create_from_form
, except that this method will not update pre-existing objects.
TODO
Use knowledge about select-like fields ( enum, set, has_a, has_many ) to generate validation rules.
Better merging of attributes. For instance, it'd be nice to set some field attributes (e.g. size) in form_builder_defaults
, and not lose them when the fields list is generated and added to %args
.
Store CDBI errors somewhere on the form. For instance, if update_from_form
fails because no object could be retrieved using the form data.
AUTHOR
David Baird, <cpan@riverside-cms.co.uk>
BUGS
Please report any bugs or feature requests to bug-class-dbi-plugin-formbuilder@rt.cpan.org
, or through the web interface at http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Class-DBI-Plugin-FormBuilder. I will be notified, and then you'll automatically be notified of progress on your bug as I make changes.
COPYRIGHT & LICENSE
Copyright 2005 David Baird, All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.