File Coverage

blib/lib/Catalyst/Controller/FormBuilder/MultiForm.pm
Criterion Covered Total %
statement 18 18 100.0
branch 1 2 50.0
condition 4 5 80.0
subroutine 4 4 100.0
pod n/a
total 27 29 93.1


line stmt bran cond sub pod time code
1             package Catalyst::Controller::FormBuilder::MultiForm;
2              
3             our $VERSION = '0.03';
4              
5 5     5   9675065 use strict;
  5         13  
  5         123  
6 5     5   25 use warnings;
  5         8  
  5         158  
7              
8 5     5   24 use base qw| Catalyst::Controller::FormBuilder |;
  5         12  
  5         4104  
9              
10             my %DEFAULTS =
11             (
12             stash_name => 'forms',
13             template_type => 'TT',
14             action => undef,
15             );
16              
17             sub __setup
18             {
19 8     8   290489 my $self = shift;
20 8         21 my $class = ref $self;
21 8   100     34 my $config = $self->config->{'Controller::FormBuilder::MultiForm'} || {};
22            
23             # Add config options to our accesor
24 8         577 foreach my $option ( keys %DEFAULTS )
25             {
26 24         6288 __PACKAGE__->mk_accessors( "_$option" );
27 24   66     56433 $self->set( "_$option", $config->{$option} || $DEFAULTS{$option} );
28             }
29            
30             # Set the action class based on our package name and template type unless
31             # one was already set already
32 8 50       3022 $self->_action( __PACKAGE__ . '::Action::' . $self->_template_type ) unless defined $self->_action;
33            
34             # Call the parent's setup method
35 8         3882 $self->SUPER::__setup();
36            
37             # Override the parent's action class, so that it goes to our multiform action instead
38 8         16370 $self->_fb_setup->{action} = $self->_action;
39             }
40              
41             1;
42              
43             __END__
44              
45             =head1 NAME
46              
47             Catalyst::Controller::FormBuilder::MultiForm - Multiple forms per template with Catalyst::Controller::FormBuilder
48              
49             =head1 SYNOPSIS
50              
51             In your controller:
52              
53             use base 'Catalyst::Controller::FormBuilder::MultiForm';
54            
55             sub foo : Local Form {
56             my ($self, $c) = @_;
57            
58             # Get a local copy of the "foo" form
59             my $foo_form = $self->formbuilder;
60            
61             # Forward to the "bar" action to include the "bar" form, and get a copy of it
62             my $bar_form = $c->forward('bar');
63            
64             # Do stuff with the "foo" or "bar" form results
65             # ...
66             }
67            
68             sub bar : Local Form {
69             my ($self, $c) = @_;
70             return $self->formbuilder;
71             }
72              
73             In your C<foo.fb> FormBuilder configuration file:
74              
75             name: my_foo_form
76              
77             In your C<bar.fb> FormBuilder configuration file:
78              
79             name: my_bar_form
80              
81             In your template for the C<foo> action (Template Toolkit):
82              
83             <!-- Display the "foo" form -->
84             [% forms.my_foo_form.FormBuilder.render %]
85            
86             <!-- Display the "bar" form -->
87             [% forms.my_bar_form.FormBuilder.render %]
88              
89             =head1 DESCRIPTION
90              
91             This module allows you to access multiple FormBuilder objects per template when
92             using Catalyst::Controller::FormBuilder (see L<Catalyst::Controller::FormBuilder>
93             for more information).
94              
95             By default, Catalyst::Controller::FormBuilder provides a set of variables in the
96             stash that you can use to access your form (default: C<$c-E<gt>stash-E<gt>{FormBuilder}>
97             and C<$c-E<gt>stash-E<gt>{formbuilder}>).
98              
99             If you forward to another C<:Form> action, that action's FormBuilder object will
100             replace the FormBuilder object in your calling action. This allows you to forward to
101             other actions for building form details yet keep your form handling in the calling action,
102             and is quite handy.
103              
104             However, it prevents you from forwarding to other C<:Form> actions for the purpose
105             of building multiple FormBuilder objects for use in a single page.
106              
107             This module allows you to keep a copy of the FormBuilder object for each C<:Form> action
108             you forward to in the stash, so that you can access multiple forms inside one template.
109             Each form is kept in a stash variable (default: C<$c-E<gt>{forms}>) and can be accessed
110             by the name of the form (as set in your form configuration).
111              
112             For example, if you named your form C<foo_edit> in your form configuration,
113             you could access this form by name with the following stash variables:
114              
115             # Access the formbuilder object for the "foo_edit" form
116             $c->stash->{forms}->{foo_edit}->{FormBuilder}
117            
118             # Access the formbuilder data for the "foo_edit" form
119             $c->stash->{forms}->{foo_edit}->{formbuilder}
120              
121             If you wish to use the default behavior, just use the regular FormBuilder stash values:
122              
123             $c->stash->{FormBuilder}
124             $c->stash->{formbuilder}
125              
126             Since you can use both behaviors, it is safe to use this module as your base controller
127             without having to modify your existing single form FormBuilder code and templates. Just
128             don't access the form by name, and you won't get the multiform behavior.
129              
130             =head1 TEMPLATES
131              
132             For a description of templating systems supported, see
133             L<Catalyst::Controller::FormBuilder/"TEMPLATES">.
134              
135             =head2 Template::Toolkit
136              
137             L<Template::Toolkit|Template::Toolkit> and L<HTML::Mason|HTML::Mason> are
138             pretty straightforward, and work as described above by just accessing the stash.
139              
140             Example of rendering a form named C<foo> in L<Template::Toolkit|Template::Toolkit>:
141              
142             [% forms.foo.FormBuilder.render %]
143              
144             =head2 HTML::Mason
145              
146             Example of rendering a form named C<foo> in L<HTML::Mason|HTML::Mason>:
147              
148             <% $forms->{foo}->{FormBuilder}->render %>
149              
150             =head2 HTML::Template
151              
152             If you wish to access a form by name with L<HTML::Template|HTML::Template>, you can
153             do so by prefixing the usual FormBuilder HTML::Template variables with the name
154             of your form, like C<[form name]-[formbuilder template variable]>.
155              
156             See L<CGI::FormBuilder::Template::HTML> for information about FormBuilder
157             template variables in HTML::Template..
158              
159             Example of rendering a form named C<foo> in L<HTML::Template>:
160              
161             <tmpl_var foo-form-start>
162             <tmpl_var foo-form-statetags>
163             <tmpl_var foo-label-username> <tmpl_var foo-field-username>
164             <tmpl_var foo-label-password> <tmpl_var foo-field-password>
165             <tmpl_var foo-form-submit>
166             <tmpl_var foo-form-end>
167              
168             =head1 CONFIGURATION
169              
170             For a details on how to set configuration options for FormBuilder, see
171             L<Catalyst::Controller::FormBuilder/"CONFIGURATION">.
172              
173             If you wish to set any of the configuration options specific to MultiForm,
174             you would do so as follows:
175              
176             MyApp->config
177             (
178             # Define config options specific to MultiForm
179             'Controller::FormBuilder::MultiForm' =>
180             {
181             stash_name => 'lots_of_forms_in_here',
182             template_type => 'TT',
183             }
184             # Define any regular FormBuilder config options
185             'Controller::FormBuilder' =>
186             {
187             # ..
188             }
189             );
190              
191             The following configuration options are available for MultiForm:
192              
193             =over
194              
195             =item C<stash_name>
196              
197             Defines the name of the stash variable to use for holding all of your forms.
198              
199             Not applicable for HTML::Template view.
200              
201             Please note that this option does not effect FormBuilder's stash_name option in any way. You are safe to set each option as you please in the appropriate configuration section.
202              
203             Default: C<forms>
204              
205             =back
206              
207             =over
208              
209             =item C<template_type>
210              
211             Defines the Catalyst View that the stash will be prepared for.
212              
213             Possible values are: C<HTML::Template>, C<Mason> or C<TT>.
214              
215             Default: C<TT>
216              
217             =back
218              
219             =head1 CAVEATS
220              
221             =head2 Form Name is Required
222              
223             You must provide a form name in your form configuration for this to work.
224             If your form is not named, then it will not be included in the list of
225             forms.
226              
227             =head2 Form Name Uniqueness
228              
229             Each form name must be unique. If you forward to more than one form with
230             the same name, the form data will be overwritten.
231              
232             =head2 Field Name Uniqueness
233              
234             Be careful with field names when using the module. Clashing field names
235             will result in data from one form bleeding in to an other. This is just
236             the nature of POST / GET.
237              
238             To get around this, FormBuilder itself would have to prefix the form name
239             on each field id natively in its rendering methods, which it currently
240             does not.
241              
242             =head2 Multiple Form on the Fly
243              
244             It would be handy to be able to generate multiple forms on the fly with
245             this module. For example, you could make an AJAX call to generate a series
246             of "create" forms on the fly.
247              
248             However, because L<CGI::FormBuilder> does not yet support
249             unique field names on the fly, this functionality will not be available in
250             MultiForm.
251              
252             =head1 SEE ALSO
253              
254             =over
255              
256             =item L<Catalyst::Controller::FormBuilder>
257              
258             =item L<CGI::FormBuilder>
259              
260             =item L<Catalyst::Manual>
261              
262             =back
263              
264             =head1 CREDITS
265              
266             Thanks to Juan Camacho for his help with this, and for his great L<Catalyst::Controller::FormBuilder> module.
267              
268             =head1 AUTHOR
269              
270             Danny Warren <danny@dannywarren.com>
271              
272             =head1 COPYRIGHT
273              
274             Copyright (c) 2015, L</"AUTHOR">.
275              
276             =head1 LICENSE
277              
278             This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself.
279              
280             =cut