1HTML::FormFu::Manual::CUosoekrboCookn(t3r)ibuted Perl DoHcTuMmLe:n:tFaotrimoFnu::Manual::Cookbook(3)
2
3
4

NAME

6       HTML::FormFu::Manual::Cookbook - Cooking with HTML::FormFu
7

DESCRIPTION

9       Miscellaneous useful recipes for use with HTML::FormFu
10

GETTING STARTED

12       Some useful info for beginners.
13
14   Default search paths for config files
15       The current working directory ("cwd") (see "load_config_file" in
16       HTML::FormFu).
17
18       If you're using the "FormConfig" action attribute from
19       Catalyst::Controller::HTML::FormFu, forms should be saved in
20       "root/forms".  See "SYNOPSIS" in Catalyst::Controller::HTML::FormFu and
21       "config_file_path" in Catalyst::Controller::HTML::FormFu for further
22       details.
23
24   YAML
25       Most examples given in the HTML::FormFu documentation use YAML syntax.
26       You can use any configuration file type supported by Config::Any, but
27       this author's preferred format is YAML.
28
29       A form can be populated by a config file by calling "load_config_file"
30       in HTML::FormFu with the filename as an argument. The config file is
31       converted to a perl data-structure, and then passed to "populate" in
32       HTML::FormFu.
33
34       The config file must contain a hash-ref, with the keys corresponding to
35       form method-names, and the values being the method arguments. For
36       example, the following are equivalent:
37
38           ---
39           auto_fieldset: 1
40           elements:
41             - name: foo
42             - name: bar
43
44           # the above YAML is equivalent to the following perl code
45
46           $form->auto_fieldset(1);
47
48           $form->elements([
49               { name => 'foo' },
50               { name => 'bar' },
51           ]);
52
53       When writing your config file, remember that perl hashes are unordered
54       and cannot have multiple keys with the same name.
55
56       See "load_config_file" in HTML::FormFu and "populate" in HTML::FormFu
57       for more details.
58
59       See <http://www.yaml.org/spec/> for the YAML specification.
60

BUILDING A FORM

62   Quick single-file prototypes
63       You can run the following script to quickly view a form's markup -
64       replace the contents of the "__DATA__" section with your own YAML
65       config.
66
67           #!/usr/bin/perl
68           use strict;
69           use warnings;
70           use HTML::FormFu;
71           use YAML::XS qw( Load );
72
73           my $form = HTML::FormFu->new;
74           my $yaml = do { local $/; <DATA> };
75           my $data = Load($yaml);
76
77           $form->populate($data);
78
79           print $form;
80
81           __DATA__
82           ---
83           auto_fieldset: 1
84           elements:
85             - type: Text
86               name: foo
87
88   Unsupported HTML tags
89       You can use the HTML::FormFu::Element::Block element, and set the tag
90       to create any arbitrary pair of tags.
91
92           ---
93           elements:
94             - type: Block
95               tag: span
96               content_xml: "<b>Hi!</b>"
97
98       You can use "content" in HTML::FormFu::Element::Block, "content_xml" in
99       HTML::FormFu::Element::Block or "content_loc" in
100       HTML::FormFu::Element::Block to add any content you wish, or use
101       "element" in HTML::FormFu::Element::Block to add elements.
102

Application-wide default values

104       You can automatically set defaults using "default_args" in
105       HTML::FormFu, and if you set this in a Catalyst application config
106       file, it'll take effect throughout your entire application, for
107       example:
108
109           myapp.yml
110           ---
111           'Controller::HTML::FormFu':
112             constructor:
113               default_args:
114                 elements:
115                   Checkbox:
116                     reverse_multi: 1
117                   Radio:
118                     reverse_multi: 1
119

MODIFYING A FORM

121   Insert a new field before existing form fields
122       See "insert_before" in HTML::FormFu and "insert_after" in HTML::FormFu.
123
124           my $fieldset = $form->get_element({ type => 'Fieldset' });
125
126           $fieldset->insert_before(
127               $form->element(\%specs),
128               $form->get_field($name)
129           );
130
131       Another way to approach the problem is to use multiple config files,
132       and decide which to load at runtime:
133
134           # user_edit.yml
135           ---
136           elements:
137             - type: Text
138               name: email
139
140           # user_username.yml
141           ---
142           elements:
143             - type: Text
144               name: username
145
146            # user_register.yml
147            ---
148            load_config_file:
149             - user_username.yml
150             - user_edit.yml
151
152           # create a user edit form, with only the email field
153
154           $form->load_config_file( 'user_edit.yml' );
155
156           # create a user registration form with username and email fields
157
158           $form->load_config_file( 'user_register.yml' );
159
160   From and Field attributes
161       You can add any arbitrary attributes to a form with "attributes" in
162       HTML::FormFu, or to any element with "attributes" in
163       HTML::FormFu::Element.
164
165           ---
166           attributes_xml:
167             onsubmit: "js_function()"
168           elements:
169             - type: Text
170               name: foo
171               attributes_xml:
172                 onchange: "js_function()"
173

FORM VALIDATION

175   Check valid dates
176       Use HTML::FormFu::Inflator::DateTime. When the inflator is processed,
177       it will try to create a DateTime object. An error will be returned if
178       the supplied values do not make a valid date.
179
180   Check valid URI / URLs
181       HTML::FormFu::Constraint::Regex supports Regexp::Common regular
182       expressions:
183
184           ---
185           elements:
186               - type: Text
187                 name: uri
188                 constraints:
189                   - type: Regex
190                     common: [ URI, HTTP, { '-scheme': 'ftp|https?' ]
191
192   Implement a custom constraint / validator
193       If HTML::FormFu::Constraint::Callback or
194       HTML::FormFu::Validator::Callback isn't sufficient for your needs, you
195       can create your own class that inherits from HTML::FormFu::Constraint
196       or HTML::FormFu::Validator, respectively.
197
198       It should implement a "validate_value" method, which returns true is
199       the value is valid, or false otherwise.
200
201           package My::Custom::Validator;
202           use strict;
203           use base 'HTML::FormFu::Validator';
204
205           sub validate_value {
206             my ( $self, $value, $params ) = @_;
207
208             return 1 if value_is_valid( $value );
209
210             return;
211           }
212
213           1;
214
215       Then add your custom validator to the form:
216
217           ---
218           elements:
219             - type: Text
220               name: foo
221               validators:
222                 - '+My::Custom::Validator'
223
224   Constrain one form field based on the value of another
225       For example, you have a radiogroup and several text fields, with
226       different text fields being required depending on the value of the
227       radiogroup.
228
229       This is achieved using the "when" attribute of a constraint:
230
231           constraints:
232             - type: Length
233               min: 8
234               when:
235                 field: bar
236                 values: [ 1, 3, 5 ]
237
238       In the above example, the Length constraint is only processed when the
239       form field named "bar" has a value of either 1, 3 or 5.
240
241       You can also test for a negative condition using the "not" attribute:
242
243           constraints:
244             - type: Length
245               min: 8
246               when:
247                 field: bar
248                 values: [ 1, 3, 5 ]
249                 not: 1
250
251       Now the constraint will be processed only if the value of field "bar"
252       is NOT 1, 3 or 5.
253
254       Note: if you rely on the value of a checkbox for a when-restricted
255       contraint, you might want to consider setting "default_empty_value" for
256       that checkbox. Take a look at HTML::FormFu::Element::_Field to learn
257       more.
258
259       Please read HTML::FormFu::Constraint for futher information.
260
261   Constrain one form field based on the return value of a callback
262       You can use the "when" attribute of a constraint also to decide using a
263       callback if the constraint should be applied.
264
265       For instance, the following (code) example shows a constraint being
266       applied only if the value of another field contains a pattern
267
268           my $apply_if_pattern = sub {
269               my $params = shift;
270               return 1 if $params->{other_field} =~ m/\A ice_cream \z/xms;
271               return 0;
272           }
273
274           $field->{constraints} = {
275               type    => 'Required',
276               when    => {
277                   callback    => $apply_if_pattern,
278               }
279           }
280
281       Please read HTML::FormFu::Constraint for futher information.
282

HTML MARKUP

284   Indented HTML
285       Use HTML::FormFu::OutputProcessor::Indent:
286
287           ---
288           output_processors:
289             - Indent
290
291   Add a blank div (e.g. for AJAX purposes)
292       Simply add a Block element in the relevant place, it defaults to a
293       "DIV" tag.
294
295           ---
296           elements:
297             - type: Text
298               name: user
299
300             - type: Block
301               id: foo
302
303             - type: Text
304               name: email
305

DISPLAY

307   Custom error messages
308       If you want to display an error message due to an error in your own
309       code, such as a database check; something which isn't implemented as a
310       Constraint or Validator; you can use a Callback Constraint.
311
312       If you don't provide your own callback routine, the default callback
313       will always pass, regardless of user input.
314
315       You can take advantage of this by setting force_errors, to display its
316       error message when needed.
317
318       Example config:
319
320           ---
321           elements:
322             - type: Text
323             - name: email
324             - constraints:
325               type: Callback
326               message: 'Email address already in use'
327
328       Example usage:
329
330           if ( $@ =~ m/duplicate entry for key 'email'/i ) {
331
332               $form->get_field('email')
333                    ->get_constraint({ type => 'Callback' })
334                    ->force_errors(1);
335
336               $form->process;
337               # then redisplay the form as normal
338           }
339
340   Highlight required fields (or fields with certain types of constraint)
341       This can be achieved using the form's "auto_constraint_class" method:
342
343           $form->auto_constraint_class( 'constraint_%t' );
344
345       The container divs around any form field with a constraint will then
346       have extra CSS classes added, which indicate the type of constraint and
347       allow you to apply appropriate styling with CSS:
348
349           /* change background of labels for fields with a Required constraint */
350           fieldset .constraint_required label {
351               background: #f00;
352           }
353
354       This technique can also be used to add content before or after the
355       fields in question (note this will not work in older browsers with more
356       limited CSS support such as IE6):
357
358           /* add an asterisk at the end of the label for required fields */
359           fieldset .constraint_required label:after {
360               content: '*'
361           }
362
363   Add a popup hint to a field
364       Some visual browsers (including IE6/7, Firefox, Opera 9) display a
365       tooltip when a user hovers their mouse pointer over an HTML element
366       with a "title" tag. Aural browsers may try to turn the content into
367       speech. You can take advantage of this behaviour to provide a hint to
368       the user about how to complete a form field.
369
370           elements:
371             - type: Text
372               name: country_name
373               label: Country Name
374               attributes:
375                 title: Name of country
376
377       The above will provide a hint when the "country_name" field receives
378       focus.  Or you could provide the hint for the container tag around both
379       field and label:
380
381           elements:
382             - type: Text
383               name: country_name
384               label: Country Name
385               container_attributes:
386                 title: Name of country
387
388   Display filtered values
389       If you have a Filter on a field, such as
390       HTML::FormFu::Filter::Whitespace to strip leading / trailing
391       whitespace, then if you redisplay the form the field is normally
392       populated with the value the user originally entered.
393
394       If you would like the field to contain the filtered value, use
395       "render_processed_value" in HTML::FormFu.
396

ADVANCED CUSTOMISATION

398   Installing the TT templates
399       It only makes sense to use the template files if you plan on
400       customising them, as the default "string" render-method is faster.
401
402       If you're using the Catalyst web framework, install
403       Catalyst::Controller::HTML::FormFu and run the following command:
404
405           $ script/myapp_create.pl HTML::FormFu
406
407       This will create a directory, "root/formfu", containing the
408       HTML::FormFu template files.
409
410       If you use Catalyst::Controller::HTML::FormFu as a base class and you
411       don't set HTML::FormFu's INCLUDE_PATH yourself, it will automatically
412       be set to "root/formfu" if that directory exists.
413
414       If you're not using Catalyst, you can create the template files by
415       running the following command:
416
417             $ html_formfu_deploy.pl <target-directory>
418
419       Take note that if you choose to customise your own copy of
420       HTML::FormFu's template files, you'll need to keep track of the
421       "Changes" file, when updating HTML::FormFu, so that you can update your
422       own templates if the core templates are updated.
423

PERFORMANCE

425   Catalyst::Plugin::StackTrace
426       If you're using Catalyst::Plugin::StackTrace, make sure you're using at
427       least version 0.09 - earlier versions had performance problems with
428       "HTML::FormFu".
429
430   Template::Alloy
431       You can also use Template::Alloy instead of Template::Toolkit, it's
432       mostly compatible, and in many cases provides a reasonable speed
433       increase. You can do this either by setting the
434       "HTML_FORMFU_TEMPLATE_ALLOY" environment variable to a true value, or
435       by passing "TEMPLATE_ALLOY" to "tt_args" in HTML::FormFu:
436
437           tt_args:
438             TEMPLATE_ALLOY: 1
439             COMPILE_DIR: /tmp
440             COMPILE_PERL: 1
441
442       Template::Alloy's caching is off by default. Switch it on by setting
443       either "COMPILE_EXT" or "COMPILE_DIR". If you're running under a
444       persistent environment such as modperl or fastcgi, you should also set
445       "COMPILE_PERL" to compile the cached templates down to perl code.
446
447       Of cource, if you wish you can still use Template::Toolkit to process
448       your own application templates, letting Template::Alloy process just
449       the HTML::FormFu templates.
450
451   HTML:FormFu::Preload
452       To reduce the runtime for each form that uses a previously unused
453       element or processor - at the expense of greater memory usage - you can
454       preload all FormFu modules - this is only recommended for persistent
455       environments such as modperl or fastcgi:
456
457           use HTML::FormFu::Preload;
458

FAQs

460   Force an element to always have a certain value
461       See the following:
462
463       "retain_default" in HTML::FormFu::Element::_Field, "force_default" in
464       HTML::FormFu::Element::_Field
465

AUTHORS

467       Will Hawes "wdhawes@gmail.com"
468
469       Carl Franks "cfranks@cpan.org"
470
472       This document is free, you can redistribute it and/or modify it under
473       the same terms as Perl itself.
474
475
476
477perl v5.12.1                      2010-05-16 HTML::FormFu::Manual::Cookbook(3)
Impressum