Class-DBI-FormBuilder

 view release on metacpan or  search on metacpan

lib/Class/DBI/FormBuilder.pm  view on Meta::CPAN


The extra keys are documented in various places in this file - I'll gather them together here 
over time. Extra keys include:

=over 4

=item options_sorters

A hashref, keyed by field name, with values being coderefs that will be used to sort the list 
of options generated for a C<has_a>, C<has_many>, or C<might_have> field. 

The coderef will be passed pairs of options arrayrefs, and should return the standard Perl sort 
codes (i.e. -1, 0, or 1). The first item in each arrayref is the value of the option, the second 
is the label.

Note that the coderef should be prototyped ($$):

    # sort by label, alphabetically
    $field_name => sub ($$) { $_[0]->[1] cmp $_[1]->[1] }

    # sort by value, numerically
    $field_name => sub ($$) { $_[0]->[0] <=> $_[1]->[0] }

=back

Note that parameter merging is likely to become more sophisticated in future releases 
(probably copying the argument merging code from L<CGI::FormBuilder|CGI::FormBuilder> 
itself).

=item search_form( %args )

Build a form with inputs that can be fed to search methods (e.g. C<search_where_from_form>). 
For instance, all selects are multiple, fields that normally would be required 
are not, and C<TEXT> columns are represented as C<text> fields rather than as C<textarea>s by default.

B<Automatic configuration of validation settings is not carried out on search forms>. You can 
still configure validation settings using the standard L<CGI::FormBuilder> settings. 

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. They are only relevant if processing 
via C<search_where_from_form>.

=over 4

=item 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'
    
=item search_opt_order_by

If true, will generate a widget to select (possibly multiple) columns to order the results by, 
with an C<ASC> and C<DESC> 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' ]
    
=back

=cut

sub as_form
{
    my ( $them, %args_in ) = @_;
    
    my $me = $them->__form_builder_subclass__;
    
    return scalar $me->_as_form( $them, %args_in );    
}

=begin notes

There seem to be several ways to approach this:

1. Modify the original args, so that CGI::FB builds a single form with multiple sets of inputs. 
    This seems difficult, but would result in a form that could be processed very easily.
    
2. Build multiple forms, and use a custom javascript submit button to gather all their inputs and 
    submit a single form. The js is tricky, and processing the input is not easy, because we don't 
    have a server form to handle it.
    
3. Use HTML::Tree to build a super-form from a standard form. Same problem with processing input as 
    for #2.
    
4. AJAX - instead of submitting all forms in one go (as in #2), submit each form individually. This 
    would solve the problem of processing the submission, but requires a different architecture.  

Seems to boil down to #1 or #3. 

The problem with #1 is that after building the CGI::FB form, it is then passed through all the form 
modifiers, including any registered field processors. All of this would have to cope with modifying 
field names. But maybe that could be done via a final field modifier?

The problem with #3 is processing submissions, since the final form is never represented by a CGI::FB
form. 

UPDATE: the solution is:

5. Build the individual forms, tweak their field names, then combine all the fields
    from all the forms into a single form. This works because most of the CGI::FB magic 
    does not happen during form construction, but during calls made on the completed form.



( run in 1.421 second using v1.01-cache-2.11-cpan-39bf76dae61 )