Class-DBI-FormBuilder
view release on metacpan or search on metacpan
lib/Class/DBI/FormBuilder.pm view on Meta::CPAN
# interested in. So the map is only stored on $caller.
$caller->mk_classdata( __mutator_to_name__ => {} );
my @export = qw( as_form
search_form
as_form_with_related
as_multiform
create_from_multiform
update_or_create_from_form
update_from_form_with_related
retrieve_from_form
search_from_form
search_like_from_form
search_where_from_form
find_or_create_from_form
retrieve_or_create_from_form
);
if ( $args{BePoliteToFromForm} )
{
no strict 'refs';
*{"$caller\::${_}_fb"} = \&{"${_}_form"} for qw( update_from create_from );
}
else
{
push @export, qw( update_from_form create_from_form );
}
no strict 'refs';
*{"$caller\::$_"} = \&$_ for @export;
}
=head1 NAME
Class::DBI::FormBuilder - Class::DBI/CGI::FormBuilder integration
=head1 SYNOPSIS
package Film;
use strict;
use warnings;
use base 'Class::DBI';
use Class::DBI::FormBuilder;
# for indented output:
# use Class::DBI::FormBuilder PrettyPrint => 'ALL';
# POST all forms to server
Film->form_builder_defaults->{method} = 'post';
# customise how some fields are built:
# 'actor' is a has_a field, and the
# related table has 1000's of rows, so we don't want the default popup widget,
# we just want to show the current value
Film->form_builder_defaults->{process_fields}->{actor} = 'VALUE';
# 'trailer' stores an mpeg file, but CDBI::FB cannot automatically detect
# file upload fields, so need to tell it:
Film->form_builder_defaults->{process_fields}->{trailer} = 'FILE';
# has_a fields will be automatically set to 'required'. Additional fields can be specified:
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 mini-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.
=head1 DESCRIPTION
B<Errata: use of column name/accessor/mutator is currently broken if your column
accessors/mutators are different from the column name>. The documentation is also broken w.r.t. this.
This module creates a L<CGI::FormBuilder|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 C<enum> and C<set> columns are configured as C<select>, C<radiobutton> or
C<checkbox> widgets as appropriate, and appropriate widgets are built for C<has_a>, C<has_many>
and C<might_have> relationships. Further relationships can be added by subclassing. C<has_a> columns
are set as 'required' fields in create/update forms.
A demonstration app (using L<Maypole::FormBuilder|Maypole::FormBuilder>) can be viewed at
http://beerfb.riverside-cms.co.uk
=head1 Customising field construction
Often, the default behaviour will be unsuitable. For instance, a C<has_a> relationship might point to
a related table with thousands of records. A popup widget with all these records is probably not useful.
Also, it will take a long time to build, so post-processing the form to re-design the field is a
poor solution.
Instead, you can pass an extra C<process_fields> argument in the call to C<as_form> (or you can
set it in C<form_builder_defaults>).
Many of the internal routines use this mechanism for configuring fields. A manually set '+'
(basic) processor will be B<added> to any other automatic processing, whereas a manually set shortcut
processor (no '+') will B<replace> all automatic processing.
You can add your own processors to the internal table of processors - see C<new_field_processor>.
=head2 process_fields
This is a hashref, with keys being field names. Values can be:
=over 4
=item Name of a built-in
basic shortcut
-------------------------------------------------------------------------------
+HIDDEN HIDDEN make the field hidden
+VALUE VALUE display the current value
+READONLY READONLY display the current value - not editable
+DISABLED DISABLED display the current value - not editable, not selectable, (not submitted?)
+FILE FILE build a file upload widget
+OPTIONS_FROM_DB OPTIONS_FROM_DB check if the column is constrained to a few values
+REQUIRED make the field required
+NULL no-op - useful for debugging
+ADD_FIELD add a new field to the form (only necessary if the field is empty)
TIMESTAMP used to process TIMESTAMP fields, defaults to DISABLED, but you can
easily replace it with a different behaviour
+SET_VALUE($value) set the value of the field to $value - DEPRECATED - use +SET_value
+SET_$foo($value) SET_$foo($value) set the $foo attribute of the field to $value
The 'basic' versions apply only their own modification. The 'shortcut' version also applies
the C<+VALUE> processor.
C<OPTIONS_FROM_DB> currently only supports MySQL ENUM or SET columns. You probably won't need to use
this explicitly, as it's already used internally.
The C<+ADD_FIELD> processor is only necessary if you need to add a new field to a form, but don't want to
use any of the other processors on it.
=item Reference to a subroutine, or anonymous coderef
The coderef will be passed the L<Class::DBI::FormBuilder> class or subclass, the CDBI class or
object, the L<CGI::FormBuilder> form object, and the field name as arguments, and should build the
named field.
=item Package name
Name of a package with a suitable C<field> subroutine. Gets called with the same arguments as
the coderef.
=item Arrayref of the above
Applies each processor in order.
( run in 0.974 second using v1.01-cache-2.11-cpan-364913b4093 )