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 )