File Coverage

blib/lib/Rose/HTML/Form.pm
Criterion Covered Total %
statement 714 833 85.7
branch 325 494 65.7
condition 56 100 56.0
subroutine 103 118 87.2
pod 64 88 72.7
total 1262 1633 77.2


line stmt bran cond sub pod time code
1             package Rose::HTML::Form;
2              
3 8     8   430951 use strict;
  8         57  
  8         256  
4              
5 8     8   44 use Carp;
  8         16  
  8         472  
6              
7 8     8   2297 use Clone::PP;
  8         4106  
  8         60  
8 8     8   4992 use Rose::URI;
  8         164404  
  8         289  
9 8     8   65 use Scalar::Util();
  8         19  
  8         158  
10 8     8   39 use URI::Escape qw(uri_escape);
  8         18  
  8         419  
11              
12 8     8   2419 use Rose::HTML::Util();
  8         19  
  8         204  
13 8     8   2366 use Rose::HTML::Object::Errors qw(:form);
  8         21  
  8         67  
14              
15             our @ISA = qw(Rose::HTML::Object::WithWrapAroundChildren
16             Rose::HTML::Form::Field Rose::HTML::Form::Field::Collection);
17              
18             our $VERSION = '0.624';
19              
20             # Avoid problems caused by circular dependencies by loading these
21             # modules at runtime. XXX: This whole hierarchy needs an overhaul.
22             require Rose::HTML::Form::Field;
23             require Rose::HTML::Form::Field::Collection;
24             require Rose::HTML::Object::WithWrapAroundChildren;
25              
26             # Multiple inheritence never quite works out the way I want it to...
27             Rose::HTML::Form::Field::Collection->import_methods
28             (
29             'xhtml',
30             'html',
31             'prepare',
32             'hidden_field',
33             'hidden_fields',
34             'html_hidden_field',
35             'xhtml_hidden_field',
36             'html_hidden_fields',
37             'xhtml_hidden_fields',
38             );
39              
40             __PACKAGE__->add_valid_html_attrs
41             (
42             'action', # %URI; #REQUIRED -- server-side form handler --
43             'method', # (GET|POST) GET -- HTTP method used to submit the form--
44             'enctype', # %ContentType; "application/x-www-form-urlencoded"
45             'accept', # %ContentTypes; #IMPLIED -- list of MIME types for file upload --
46             'name', # CDATA #IMPLIED -- name of form for scripting --
47             'onsubmit', # %Script; #IMPLIED -- the form was submitted --
48             'onreset', # %Script; #IMPLIED -- the form was reset --
49             'accept-charset', # %Charsets; #IMPLIED -- list of supported charsets --
50             'target', # http://www.w3.org/TR/xhtml-modularization/abstract_modules.html#s_targetmodule
51             'novalidate',
52             );
53              
54             __PACKAGE__->add_required_html_attrs(
55             {
56             action => '',
57             method => 'get',
58             enctype => 'application/x-www-form-urlencoded',
59             });
60              
61 8     8   71 use constant UNSAFE_URI_CHARS => '^\w\d?\057=.:-';
  8         15  
  8         597  
62              
63 8     8   2964 use Rose::HTML::Form::Constants qw(FF_SEPARATOR);
  8         22  
  8         1097  
64              
65             # Variable for use in regexes
66             our $FF_SEPARATOR_RE = quotemeta FF_SEPARATOR;
67              
68             our $Debug = 0;
69              
70             use Rose::Object::MakeMethods::Generic
71             (
72 8         92 scalar =>
73             [
74             'uri_base',
75             'rank',
76             ],
77              
78             'scalar --get_set_init' =>
79             [
80             'uri_separator',
81             'form_rank_counter',
82             'recursive_init_fields',
83             ],
84              
85             boolean =>
86             [
87             'coalesce_query_string_params' => { default => 1 },
88             'build_on_init' => { default => 1 },
89             ],
90 8     8   67 );
  8         15  
91              
92             #
93             # Class data
94             #
95              
96             use Rose::Class::MakeMethods::Generic
97             (
98 8         61 inheritable_scalar =>
99             [
100             '_delegate_to_subforms',
101             ],
102              
103             inheritable_boolean =>
104             [
105             'default_recursive_init_fields',
106             'default_trim_xy_params',
107             ],
108 8     8   8283 );
  8         23  
109              
110             __PACKAGE__->delegate_to_subforms('compile');
111             __PACKAGE__->default_recursive_init_fields(0);
112             __PACKAGE__->default_trim_xy_params(1);
113              
114             #
115             # Class methods
116             #
117              
118             sub new
119             {
120 90     90 1 28854 my($class) = shift;
121              
122 90         486 my $self =
123             {
124             params => {},
125             fields => {},
126             validate_field_html_attrs => 1,
127             };
128              
129 90         233 bless $self, $class;
130              
131 90         449 $self->init(@_);
132              
133 90         2044 return $self;
134             }
135              
136 70     70 0 748 sub init_recursive_init_fields { shift->default_recursive_init_fields }
137              
138             sub trim_xy_params
139             {
140 161     161 1 282 my($self) = shift;
141              
142 161 100       385 if(@_)
143             {
144 4 50       11 my $val = $self->{'trim_xy_params'} = $_[0] ? 1 : 0;
145              
146 4         11 foreach my $form ($self->forms)
147             {
148 2         8 $form->trim_xy_params($val);
149             }
150              
151 4         9 return $val;
152             }
153              
154             return defined $self->{'trim_xy_params'} ?
155 157 100       751 $self->{'trim_xy_params'} : ref($self)->default_trim_xy_params;
156             }
157              
158             sub delegate_to_subforms
159             {
160 11     11 1 27 my($class) = shift;
161              
162 11 50       41 $class = ref $class if(ref $class);
163              
164 11 100       43 if(@_)
165             {
166 8         26 my $value = shift;
167              
168             # Dumb regex to avoid non-numeric comparison warning
169 8 50 33     66 $value = 'runtime' if($value =~ /\d/ && $value == 1);
170              
171 8 50 33     76 unless(!$value || $value eq 'compile' || $value eq 'runtime')
      33        
172             {
173 0         0 croak "Invalid delegate_to_subforms() value: '$value'";
174             }
175              
176 8         47 return $class->_delegate_to_subforms($value);
177             }
178              
179 3         16 return $class->_delegate_to_subforms;
180             }
181              
182             #
183             # Object methods
184             #
185              
186 1     1 0 14 sub init_uri_separator { '&' }
187              
188             sub init
189             {
190 90     90 1 172 my($self) = shift;
191              
192 90         448 $self->SUPER::init(@_);
193              
194 90 100       762 $self->build_form() if($self->build_on_init);
195             }
196              
197 13     13 1 70 sub html_element { 'form' }
198 2     2 1 19 sub xhtml_element { 'form' }
199              
200 1     1 0 924 sub action { shift->html_attr('action', @_) }
201 1     1 0 7 sub method { shift->html_attr('method', @_) }
202              
203       49 1   sub build_form { }
204              
205             sub name
206             {
207 44     44 1 81 my($self) = shift;
208              
209 44 100       95 if(@_)
210             {
211 2         8 return $self->html_attr('name', shift);
212             }
213             else
214             {
215 42 100       103 unless(defined $self->html_attr('name'))
216             {
217 2         12 return $self->form_name;
218             }
219              
220 40         101 return $self->html_attr('name');
221             }
222             }
223              
224             sub validate_field_html_attrs
225             {
226 0     0 1 0 my($self) = shift;
227              
228 0 0       0 if(@_)
229             {
230 0         0 foreach my $field ($self->fields)
231             {
232 0         0 $field->validate_html_attrs(@_);
233             }
234              
235 0 0       0 return $self->{'validate_field_html_attrs'} = $_[0] ? 1 : 0;
236             }
237              
238 0         0 return $self->{'validate_field_html_attrs'};
239             }
240              
241             # Override inherited, non-public methods with fast-returning
242             # "don't care" versions.
243 0     0   0 sub _is_full { 0 }
244       0     sub _set_input_value { }
245 0     0 1 0 sub is_full { 0 }
246              
247 0 0 0 0 1 0 sub is_repeatable { $_[0]->is_repeatable_form || $_[0]->is_repeatable_field ? 1 : 0 }
248 3     3 0 7 sub is_repeatable_field { 0 }
249 0     0 0 0 sub is_repeatable_form { 0 }
250              
251             sub is_empty
252             {
253 98     98 1 196 my($self) = shift;
254              
255 98         212 foreach my $field ($self->fields)
256             {
257 172 100       831 return 0 unless($field->is_empty);
258             }
259              
260 33         245 foreach my $form ($self->forms)
261             {
262 11 50       42 return 0 unless($form->is_empty);
263             }
264              
265 33         151 return 1;
266             }
267              
268             sub empty_is_ok
269             {
270 95     95 1 171 my($self) = shift;
271              
272 95 100       245 if(@_)
273             {
274 8         33 foreach my $form ($self->forms)
275             {
276 2         12 $form->empty_is_ok(@_);
277             }
278              
279 8         34 return $self->SUPER::empty_is_ok(@_);
280             }
281              
282 87         337 my $ok = $self->SUPER::empty_is_ok(@_);
283 87 100       857 return $ok unless($ok);
284              
285 10         31 foreach my $form ($self->forms)
286             {
287 2 50       6 return 0 unless($form->empty_is_ok);
288             }
289              
290 10         54 return $ok;
291             }
292              
293             # Empty contents instead of replacing ref
294 2     2 1 20 sub delete_params { %{shift->{'params'}} = () }
  2         9  
295              
296             sub params_from_cgi
297             {
298 3     3 1 34474 my($self, $cgi) = @_;
299              
300 3 50       13 croak "Missing CGI argument to params_from_cgi" unless(@_ > 1);
301              
302 3 50 66     32 unless(UNIVERSAL::isa($cgi, 'CGI') || UNIVERSAL::can($cgi, 'param'))
303             {
304 0         0 croak "Argument to params_from_cgi() is not a CGI object and ",
305             "does not have a param() method";
306             }
307              
308 3         8 my %params;
309              
310 3         7 local $CGI::LIST_CONTEXT_WARN = 0;
311              
312 3         9 foreach my $param ($cgi->param)
313             {
314 7         54 my @values = $cgi->param($param);
315 7 100       108 $params{$param} = @values > 1 ? \@values : $values[0];
316             }
317              
318 3         17 $self->params(\%params);
319             }
320              
321             # IIn a reasonably modern perl, the optimizer will eliminate the
322             # blocks of code that are conditional upon these constants when the
323             # value is zero.
324             use constant MP2 => exists $ENV{'MOD_PERL_API_VERSION'} &&
325 8 50 33 8   12429 $ENV{'MOD_PERL_API_VERSION'} > 1 ? 1 : 0;
  8         19  
  8         832  
326              
327             use constant MP1 => # Special environment variable for the test suite
328             ($ENV{'MOD_PERL'} || $ENV{'RHTMLO_TEST_MOD_PERL'}) &&
329 8 100 66     722 (!exists $ENV{'MOD_PERL_API_VERSION'} || $ENV{'MOD_PERL_API_VERSION'} == 1) ?
330 8     8   58 1 : 0;
  8         25  
331              
332 8 50   8   57 use constant MP0 => $ENV{'MOD_PERL'} ? 0 : 1;
  8         41  
  8         5407  
333              
334             my $Loaded_APR1 = 0;
335             my $Loaded_APR2 = 0;
336              
337             sub params_from_apache
338             {
339 2     2 1 527 my($self, $apr) = @_;
340              
341 2 50       11 croak "Missing apache request argument to params_from_apache" unless(@_ > 1);
342              
343 2         6 if(MP0)
344             {
345 2 50       12 unless(UNIVERSAL::can($apr, 'param'))
346             {
347 0         0 croak "Argument to params_from_apache() does not have a param() method";
348             }
349             }
350             elsif(MP1)
351             {
352             if(UNIVERSAL::isa($apr, 'Apache'))
353             {
354             unless($Loaded_APR1) # cheaper than require (really!)
355             {
356             require Apache::Request;
357             $Loaded_APR1 = 1;
358             }
359              
360             $apr = Apache::Request->instance($apr);
361             }
362             elsif(!UNIVERSAL::isa($apr, 'Apache::Request') &&
363             !UNIVERSAL::can($apr, 'param'))
364             {
365             croak "Argument to params_from_apache() is not an Apache or ",
366             "Apache::Request object and does not have a param() method";
367             }
368             }
369             elsif(MP2)
370             {
371             if(UNIVERSAL::isa($apr, 'Apache2::RequestRec'))
372             {
373             unless($Loaded_APR2) # cheaper than require (really!)
374             {
375             require Apache2::Request;
376             $Loaded_APR2 = 1;
377             }
378              
379             $apr = Apache2::Request->new($apr);
380             }
381             elsif(!UNIVERSAL::isa($apr, 'Apache2::Request') &&
382             !UNIVERSAL::can($apr, 'param'))
383             {
384             croak "Argument to params_from_apache() is not an Apache2::RequestRec ",
385             "or Apache2::Request object and does not have a param() method";
386             }
387             }
388              
389 2         3 my %params;
390              
391 2         7 foreach my $param ($apr->param)
392             {
393 5         33 my @values = $apr->param($param);
394 5 100       50 $params{$param} = @values > 1 ? \@values : $values[0];
395             }
396              
397 2         8 $self->params(\%params);
398             }
399              
400             sub params
401             {
402 191     191 1 9331 my($self) = shift;
403              
404 191 100       462 if(@_)
405             {
406 157 100 66     716 if(@_ == 1 && ref $_[0] eq 'HASH')
    50          
407             {
408 140         361 $self->{'params'} = $_[0];
409             }
410             elsif(@_ % 2 == 0)
411             {
412 17         127 $self->{'params'} = Clone::PP::clone({ @_ });
413             }
414             else
415             {
416 0         0 croak(ref($self), '::params() - got odd number of arguments: ');
417             }
418              
419 157 100       2022 if($self->trim_xy_params)
420             {
421 153         3025 foreach my $param (keys %{$self->{'params'}})
  153         537  
422             {
423 704 100       2070 if($param =~ /^(.+)\.[xy]$/)
424             {
425 1         3 delete $self->{'params'}{$param};
426 1         5 $self->{'params'}{$1} = 1;
427             }
428             }
429             }
430              
431 157         439 foreach my $form ($self->forms)
432             {
433 87         293 $form->params($self->{'params'});
434             }
435             }
436              
437 191         350 my $want = wantarray;
438 191 100       496 return unless(defined $want);
439              
440 34 100       185 return ($want) ? %{ Clone::PP::clone($self->{'params'}) } : $self->{'params'};
  1         7  
441             }
442              
443             sub param_exists
444             {
445 1641     1641 1 3168 my($self, $param) = @_;
446              
447 8     8   73 no warnings;
  8         18  
  8         9896  
448              
449 1641         3654 return exists $self->{'params'}{$param};
450             }
451              
452 0 0   0 1 0 sub params_exist { (keys %{$_[0]->{'params'}}) ? 1 : 0 }
  0         0  
453              
454             sub param_exists_for_field
455             {
456 36     36 1 106 my($self, $name) = @_;
457              
458 36 100       222 $name = $name->name if(UNIVERSAL::isa($name, 'Rose::HTML::Form::Field'));
459              
460 36 100       99 return 0 unless($self->field($name));
461              
462 34         72 my $nibble = $name;
463 34         78 my $found_form = 0;
464              
465 34         87 while(length $nibble)
466             {
467 62 100 66     123 if($self->form($nibble) && !$self->field($nibble))
468             {
469 11         20 $found_form = 1;
470 11         19 last;
471             }
472              
473 51 100       112 return 1 if($self->param_exists($nibble));
474 40 100       201 $nibble =~ s/\.[^.]+$// || last;
475             }
476              
477 23 100       69 foreach my $field ($found_form ? $self->form($nibble)->fields :
478             $self->field($name))
479             {
480 23 100       88 if($field->can('subfield_names'))
481             {
482 20         66 foreach my $subname ($field->subfield_names)
483             {
484             # Skip unrelated subfields
485 102 100 100     384 next unless(index($name, $subname) == 0 ||
486             index($subname, $name) == 0);
487              
488 83 100       162 return 1 if($self->param_exists($subname));
489             }
490             }
491             }
492              
493 13         130 return 0;
494             }
495              
496             sub param_value_exists
497             {
498 3     3 1 10 my($self, $param, $value) = @_;
499              
500 3 50       10 croak(ref($self), '::param_value_exists() requires a param name plus a value')
501             unless(@_ == 3);
502              
503 3         9 $param = $self->param($param);
504              
505 3 50       13 return 0 unless($param);
506              
507 3 50       12 foreach my $existing_value ((ref $param) ? @$param : $param)
508             {
509 9 100       28 return 1 if($existing_value eq $value);
510             }
511              
512 1         5 return 0;
513             }
514              
515             sub param
516             {
517 250     250 1 1212 my($self, $param, $value) = @_;
518              
519 250 100       541 if(@_ == 2)
    50          
520             {
521 249 100       550 if(exists $self->{'params'}{$param})
522             {
523 246 100       503 if(wantarray)
524             {
525 214 100       463 if(ref $self->{'params'}{$param})
526             {
527 9         14 return @{$self->{'params'}{$param}};
  9         57  
528             }
529              
530 205         756 return ($self->{'params'}{$param});
531             }
532              
533 32         174 return $self->{'params'}{$param};
534             }
535              
536 3         14 return;
537             }
538             elsif(@_ == 3)
539             {
540 1         5 return $self->{'params'}{$param} = $value;
541             }
542              
543 0         0 croak(ref($self), '::param() requires a param name plus an optional value');
544             }
545              
546             sub delete_param
547             {
548 4     4 1 961 my($self, $param, @values) = @_;
549              
550 4 50       17 croak(ref($self), '::delete_param() requires a param name')
551             unless(@_ >= 2);
552              
553 4 100 100     26 @values = @{$values[0]} if(@values == 1 && ref $values[0] eq 'ARRAY');
  1         5  
554              
555 4 100       13 if(@values)
556             {
557 3         7 my %values = map { $_ => 1 } @values;
  4         16  
558              
559 3         15 my $current = $self->{'params'}{$param};
560              
561 3 100       13 if(ref $current)
    50          
562             {
563 2         4 my @new;
564              
565 2         6 foreach my $val (@$current)
566             {
567 7 100       22 push(@new, $val) unless(exists $values{$val});
568             }
569              
570 2 50       13 if(@new)
571             {
572 2 100       12 $self->{'params'}{$param} = @new > 1 ? \@new : $new[0];
573             }
574             else
575             {
576 0         0 delete $self->{'params'}{$param};
577             }
578             }
579             elsif(exists $values{$self->{'params'}{$param}})
580             {
581 1         7 delete $self->{'params'}{$param};
582             }
583             }
584             else
585             {
586 1         4 delete $self->{'params'}{$param};
587             }
588             }
589              
590             sub add_param_value
591             {
592 1     1 1 5 my($self, $param, $value) = @_;
593              
594 1 50       5 croak(ref($self), '::add_param() requires a param name plus a value')
595             unless(@_ == 3);
596              
597 1         3 my $current = $self->{'params'}{$param};
598              
599 1 50       4 if(ref $current)
    0          
600             {
601 1 50       5 push(@$current, ((ref $value) ? @$value : $value));
602             }
603             elsif(defined $current)
604             {
605 0 0       0 $current = [ $current, ((ref $value) ? @$value : $value) ];
606             }
607             else
608             {
609 0 0       0 $current = [ ((ref $value) ? @$value : $value) ];
610             }
611              
612 1         3 $self->{'params'}{$param} = $current;
613             }
614              
615             sub self_uri
616             {
617 1     1 1 9 my($self) = shift;
618              
619 1         5 my $uri_root = $self->uri_base . $self->html_attr('action');
620              
621 1         4 my $self_uri = $uri_root;
622              
623 1 50       2 if(keys %{$self->{'params'}})
  1         5  
624             {
625 0 0       0 $self_uri .= '?' unless($self_uri =~ /\?$/);
626 0         0 $self_uri .= $self->query_string;
627             }
628              
629 1         11 return Rose::URI->new($self_uri);
630             }
631              
632             # XXX: To document or not to document, that is the question...
633 0     0 0 0 sub query_hash { Rose::URI->new(query => shift->query_string)->query_hash }
634              
635             sub query_string
636             {
637 4     4 1 11 my($self) = shift;
638              
639 4         13 my $coalesce = $self->coalesce_query_string_params;
640              
641 4         28 my %params;
642              
643 4         11 my @fields = $self->fields;
644              
645 4         15 while(my $field = shift(@fields))
646             {
647 19 100       38 unless($coalesce)
648             {
649 9 100       45 if($field->isa('Rose::HTML::Form::Field::Compound'))
650             {
651 1         8 unshift(@fields, $field->fields);
652 1         4 next;
653             }
654             }
655              
656 18         59 my $value = $field->output_value;
657 18 100       49 next unless(defined $value);
658 16 100       23 push(@{$params{$field->name}}, ref $value ? @$value : $value);
  16         45  
659             }
660              
661 4         20 my $qs = '';
662 4         20 my $sep = $self->uri_separator;
663              
664 8     8   75 no warnings;
  8         36  
  8         7772  
665              
666 4         37 foreach my $param (sort keys(%params))
667             {
668 16         751 my $values = $params{$param};
669              
670 16 100       33 $qs .= $sep if($qs);
671 16         33 $qs .= join($sep, map { $param . '=' . uri_escape($_, UNSAFE_URI_CHARS) } @$values);
  20         160  
672             }
673              
674 4         115 return $qs;
675             }
676              
677             sub validate
678             {
679 55     55 1 256 my($self, %args) = @_;
680              
681 55 100       176 $args{'cascade'} = 1 unless(exists $args{'cascade'});
682              
683 55         106 my $fail = 0;
684              
685 55         107 my $cascade = $args{'cascade'};
686              
687 55 100       130 if($cascade)
688             {
689 51         119 foreach my $form ($self->forms)
690             {
691 32 100 100     123 next if($form->is_empty && $form->empty_is_ok);
692              
693 30 50       88 $Debug && warn "Validating sub-form ", $form->form_name, "\n";
694              
695 30 100       129 unless($form->validate(%args))
696             {
697 5 100       34 $self->add_error($form->error) if($form->error);
698 5         14 $fail++;
699             }
700             }
701             }
702              
703 55 100       195 unless($args{'form_only'})
704             {
705 52 100 100     163 return 1 if($self->is_empty && $self->empty_is_ok);
706              
707 50         140 foreach my $field ($self->fields)
708             {
709 254 100       651 if($field->parent_form ne $self)
710             {
711 136 50       325 $Debug && warn "Skipping validation of field ", $field->name, " in child form\n";
712             }
713             else
714             {
715 118 50       280 $Debug && warn "Validating ", $field->name, "\n";
716 118 100       484 $fail++ unless($field->validate);
717             }
718             }
719             }
720              
721 53 100       187 if($fail)
722             {
723 13 100       129 unless($self->has_errors)
724             {
725 9         88 $self->add_error_id(FORM_HAS_ERRORS);
726             }
727              
728 13         80 return 0;
729             }
730              
731 40         166 return 1;
732             }
733              
734             sub init_fields_with_cgi
735             {
736 1     1 1 4 my($self) = shift;
737              
738 1         5 $self->params_from_cgi(shift);
739 1         6 $self->init_fields(@_);
740             }
741              
742             sub init_fields_with_apache
743             {
744 1     1 1 5 my($self) = shift;
745              
746 1         4 $self->params_from_apache(shift);
747 1         112 $self->init_fields(@_);
748             }
749              
750             sub init_fields
751             {
752 116     116 1 354 my($self, %args) = @_;
753              
754 116 100       539 $self->clear() unless($args{'no_clear'});
755              
756 116 50       499 if(exists $args{'recursive'} ? $args{'recursive'} : $self->recursive_init_fields)
    100          
757             {
758 56         509 foreach my $field ($self->local_fields)
759             {
760 111         249 $self->_init_field($field);
761             }
762              
763 56         132 foreach my $form ($self->forms)
764             {
765 60         233 $form->init_fields;
766             }
767             }
768             else
769             {
770 60         597 foreach my $field ($self->fields)
771             {
772 246         573 $self->_init_field($field);
773             }
774             }
775             }
776              
777             sub _init_field
778             {
779 501     501   921 my($self, $field) = @_;
780              
781 501         1840 my $on_off = $field->isa('Rose::HTML::Form::Field::OnOff');
782              
783 501         1319 my $name = $field->name;
784 501         1422 my $moniker = $field->moniker;
785 501         1197 my $name_attr = $field->html_attr('name');
786              
787 501 50       1040 $Debug && warn "INIT FIELD $name ($name_attr)\n";
788              
789 501         1130 my $name_exists = $self->param_exists($name);
790 501         912 my $moniker_exists = $self->param_exists($moniker);
791 501         897 my $name_attr_exists = $self->param_exists($name_attr);
792              
793 501 100 100     1949 if(!$name_exists && $field->isa('Rose::HTML::Form::Field::Compound'))
794             {
795 48         192 foreach my $moniker ($field->field_monikers)
796             {
797 144         386 $self->_init_field($field->field($moniker));
798             }
799             }
800             else
801             {
802 453 100 66     1988 return unless($name_exists || $name_attr_exists || $moniker_exists || $on_off);
      100        
      66        
803              
804 214 100       814 if($field->isa('Rose::HTML::Form::Field::Group'))
805             {
806 41 50       123 if($name_exists)
    0          
807             {
808 41 50       128 $Debug && warn "$field->input_value(", $self->param($name), ")\n";
809 41         107 $field->input_value($self->param($name));
810             }
811             elsif($moniker_exists)
812             {
813 0 0       0 $Debug && warn "$field->input_value(", $self->param($moniker), ")\n";
814 0         0 $field->input_value($self->param($moniker));
815             }
816             else
817             {
818 0 0       0 $Debug && warn "$field->input_value(", $self->param($name_attr), ")\n";
819 0         0 $field->input_value($self->param($name_attr));
820             }
821             }
822             else
823             {
824             # Must handle lone checkboxes and radio buttons here
825 173 50       341 if($on_off)
826             {
827 8     8   74 no warnings 'uninitialized';
  8         18  
  8         20732  
828 0 0 0     0 if($name_exists && $self->param($name) eq $field->html_attr('value'))
829             {
830 0 0       0 $Debug && warn "$self->param($name) = checked\n";
831 0         0 $field->checked(1);
832             }
833             else
834             {
835 0 0       0 if($self->params_exist)
836             {
837 0         0 $field->checked(0);
838             }
839             else
840             {
841             # Didn't set anything, so avoid doing pareant un-clearing below
842 0         0 return;
843             }
844             }
845             }
846             else
847             {
848 173 100       280 if($name_exists)
    50          
849             {
850 172 50       414 $Debug && warn "$field->input_value(", $self->param($name), ")\n";
851 172         493 $field->input_value($self->param($name));
852             }
853             elsif($moniker_exists)
854             {
855 1 50       4 $Debug && warn "$field->input_value(", $self->param($moniker), ")\n";
856 1         4 $field->input_value($self->param($moniker));
857             }
858             else
859             {
860 0 0       0 $Debug && warn "$field->input_value(", $self->param($name_attr), ")\n";
861 0         0 $field->input_value($self->param($name_attr));
862             }
863             }
864             }
865             }
866              
867 262         688 my $parent = $field->parent_field;
868              
869             # Ensure that setting the value of a child field makes all its
870             # parent fields "not cleared"
871 262         969 while($parent)
872             {
873 54         163 $parent->is_cleared(0);
874 54         255 $parent = $parent->parent_field;
875             }
876             }
877              
878             sub was_submitted
879             {
880 0     0 1 0 my($self) = shift;
881              
882 0         0 foreach my $field ($self->fields)
883             {
884 0 0       0 return 1 if($self->param_exists_for_field($field->name));
885             }
886              
887 0         0 return 0;
888             }
889              
890             sub start_html
891             {
892 11     11 1 25 my($self) = shift;
893 11         40 return '<' . ref($self)->html_element . $self->html_attrs_string() . '>';
894             }
895              
896             *start_xhtml = \&start_html;
897              
898             sub start_multipart_html
899             {
900 2     2 1 7 my($self) = shift;
901 2         14 $self->html_attr(enctype => 'multipart/form-data');
902 2         6 return $self->start_html;
903             }
904              
905             *start_multipart_xhtml = \&start_multipart_html;
906              
907 8     8 1 81 sub end_html { '</form>' }
908 2     2 1 13 sub end_multipart_html { '</form>' }
909              
910             *end_xhtml = \&end_html;
911             *end_multipart_xhtml = \&end_multipart_html;
912              
913             sub object_from_form
914             {
915 19     19 1 10843 my($self) = shift;
916              
917 19         40 my($class, $object);
918              
919 19 100       79 if(@_ == 1)
    50          
920             {
921 16         38 $class = shift;
922              
923 16 100       49 if(ref $class)
924             {
925 2         5 $object = $class;
926 2         6 $class = ref $object;
927             }
928             }
929             elsif(@_)
930             {
931 3         13 my %args = @_;
932              
933 3         11 $class = $args{'class'};
934 3         11 $object = $args{'object'};
935             }
936             else
937             {
938 0         0 croak "Missing required object class argument";
939             }
940              
941 19   66     211 $object ||= $class->new();
942              
943             # Special handling of boolean columns for RDBO
944 19 50       374 if($object->isa('Rose::DB::Object'))
945             {
946 0         0 my $meta = $object->meta;
947              
948 0         0 FIELD: foreach my $field ($self->fields)
949             {
950 0         0 my $name = $field->local_name;
951              
952             # When more than one field has the same local_name(), fields closer
953             # to the parent form take precedence.
954 0         0 my $check_name = $field->name;
955              
956             # Remove the form name context, if any
957 0 0       0 if(defined(my $form_name_context = $self->form_name_context))
958             {
959 0         0 $check_name =~ s/^$form_name_context//;
960             }
961              
962 0 0       0 if($check_name ne $name)
963             {
964 0         0 while($check_name =~ s/(^.+$FF_SEPARATOR_RE|^)[^$FF_SEPARATOR_RE]+$FF_SEPARATOR_RE([^$FF_SEPARATOR_RE]+)$/$1$2/)
965             {
966 0 0       0 next FIELD if($self->field($check_name));
967             }
968             }
969              
970 0 0       0 if($object->can($name))
971             {
972             # Checkboxes setting boolean columns
973 0 0 0     0 if($field->isa('Rose::HTML::Form::Field::Checkbox') &&
      0        
974             $meta->column($name) && $meta->column($name)->type eq 'boolean')
975             {
976             #$Debug && warn "$class object $name(", $field->is_on, ")";
977 0         0 $object->$name($field->is_on);
978             }
979             else # everything else
980             {
981             #$Debug && warn "$class object $name(", $field->internal_value, ")";
982 0         0 $object->$name($field->internal_value);
983             }
984             }
985             }
986             }
987             else
988             {
989 19         61 FIELD: foreach my $field ($self->fields)
990             {
991 126         454 my $name = $field->local_name;
992              
993             # When more than one field has the same local_name(), fields closer
994             # to the parent form take precedence.
995 126         388 my $check_name = $field->name;
996              
997             # Remove the form name context, if any
998 126 100       342 if(defined(my $form_name_context = $self->form_name_context))
999             {
1000 18         182 $check_name =~ s/^$form_name_context//;
1001             }
1002              
1003 126 100       287 if($check_name ne $name)
1004             {
1005 63         782 while($check_name =~ s/(^.+$FF_SEPARATOR_RE|^)[^$FF_SEPARATOR_RE]+$FF_SEPARATOR_RE([^$FF_SEPARATOR_RE]+)$/$1$2/)
1006             {
1007 126 100       322 next FIELD if($self->field($check_name));
1008             }
1009             }
1010              
1011 123 100       609 if($object->can($name))
1012             {
1013             #$Debug && warn "$class object $name(", $field->internal_value, ")";
1014 69         205 $object->$name($field->internal_value);
1015             }
1016             }
1017             }
1018              
1019 19         148 return $object;
1020             }
1021              
1022             *init_object_with_form = \&object_from_form;
1023              
1024             sub init_with_object
1025             {
1026 4     4 1 1673 my($self, $object) = @_;
1027              
1028 4 50       17 croak "Missing required object argument" unless($object);
1029              
1030 4         18 $self->clear();
1031              
1032 4         15 foreach my $field ($self->fields)
1033             {
1034 15         48 my $name = $field->local_name;
1035              
1036 15 100       92 if($object->can($name))
1037             {
1038             #$Debug && warn "field($name) = $object->$name = ", $object->$name();
1039 5         38 $field->input_value(scalar $object->$name());
1040             }
1041             }
1042             }
1043              
1044             sub clear
1045             {
1046 307     307 1 520 my($self) = shift;
1047 307         1027 $self->clear_fields;
1048 307         2034 $self->clear_forms;
1049 307         862 $self->error(undef);
1050             }
1051              
1052             sub reset
1053             {
1054 4     4 1 3609 my($self) = shift;
1055 4         23 $self->reset_fields;
1056 4         20 $self->reset_forms;
1057 4         11 $self->error(undef);
1058             }
1059              
1060 34     34 0 433 sub init_form_rank_counter { 1 }
1061              
1062             sub next_form_rank
1063             {
1064 71     71 0 166 my($self) = shift;
1065              
1066 71         116 my $rank = 1;
1067              
1068 71         201 foreach my $form ($self->forms)
1069             {
1070 44 50       213 $rank = $form->rank + 1 if($form->rank >= $rank);
1071             }
1072              
1073 71         152 return $rank;
1074             }
1075              
1076             # XXX: Remove when form_rank_counter is removed
1077             sub increment_form_rank_counter
1078             {
1079 40     40 0 86 my($self) = shift;
1080 40         144 my $rank = $self->form_rank_counter;
1081 40         221 $self->form_rank_counter($rank + 1);
1082 40         165 return $rank;
1083             }
1084              
1085             sub repeatable_form
1086             {
1087 8     8 1 3075 my($self) = shift;
1088              
1089             # Set form
1090 8 100       44 if(@_ > 1)
1091             {
1092 1         11 my($name, $form) = (shift, shift);
1093 1         11 $self->delete_repeatable_form($name);
1094 1         7 return $self->add_repeatable_form($name => $form);
1095             }
1096              
1097 7 50       26 my $form = $self->form(@_) or return undef;
1098 7 50       42 return undef unless($form->is_repeatable);
1099 7         36 return $form;
1100             }
1101              
1102             sub repeatable_forms
1103             {
1104 0     0 1 0 my($self) = shift;
1105              
1106 0 0       0 if(@_)
1107             {
1108 0         0 $self->delete_repeatable_forms;
1109 0         0 $self->add_repeatable_forms(@_);
1110 0 0       0 return unless(defined wantarray);
1111             }
1112              
1113             return wantarray ?
1114 0         0 (grep { $_->is_repeatable_form } $self->forms(@_)) :
1115 0 0       0 [ grep { $_->is_repeatable_form } $self->forms(@_) ];
  0         0  
1116             }
1117              
1118             sub add_repeatable_forms
1119             {
1120 6     6 1 14 my($self) = shift;
1121              
1122 6         12 my @form_args;
1123              
1124 6         18 while(@_)
1125             {
1126 6         12 my $arg = shift;
1127              
1128 6 50       42 if(UNIVERSAL::isa($arg, 'Rose::HTML::Form'))
    50          
1129             {
1130 0         0 push(@form_args,
1131             $arg->form_name =>
1132             {
1133             form => $arg,
1134             repeatable => undef,
1135             });
1136             }
1137             elsif(!ref $arg)
1138             {
1139 6 100       37 if(UNIVERSAL::isa($_[0], 'Rose::HTML::Form'))
    50          
1140             {
1141 4         22 my $form = shift;
1142              
1143 4         30 push(@form_args,
1144             $arg =>
1145             {
1146             form => $form,
1147             repeatable => undef,
1148             });
1149             }
1150             elsif(ref $_[0] eq 'HASH')
1151             {
1152 2         6 my $spec = shift;
1153 2 50       12 $spec->{'repeatable'} = undef unless(exists $spec->{'repeatable'});
1154 2         9 push(@form_args, $arg => $spec);
1155             }
1156             else
1157             {
1158 0         0 croak "Invalid argument pair passed to add_repeatable_forms() - $arg, $_[0]";
1159             }
1160             }
1161             else
1162             {
1163 0         0 croak "Invalid argument passed to add_repeatable_forms() - $arg";
1164             }
1165             }
1166              
1167 6         30 return $self->add_forms(@form_args);
1168             }
1169              
1170 6     6 1 58 sub add_repeatable_form { shift->add_repeatable_forms(@_) }
1171              
1172             sub form_depth
1173             {
1174 8266     8266 0 11694 my($self) = shift;
1175              
1176 8266 100       14130 if(@_)
1177             {
1178 72         177 return $self->{'form_depth'} = shift;
1179             }
1180              
1181 8194 100       31005 return $self->{'form_depth'} if(defined $self->{'form_depth'});
1182              
1183 111         208 my $depth = 0;
1184 111         184 my $form = $self;
1185 111         307 $depth++ while($form = $form->parent_form);
1186              
1187 111         363 return $self->{'form_depth'} = $depth;
1188             }
1189              
1190             sub add_forms
1191             {
1192 68     68 1 807 my($self) = shift;
1193              
1194 68         126 my @added_forms;
1195              
1196 68         239 my $next_rank = $self->next_form_rank;
1197              
1198 68         220 while(@_)
1199             {
1200 74         144 my $arg = shift;
1201              
1202 74         135 my($name, $form);
1203              
1204 74 100       363 if(UNIVERSAL::isa($arg, 'Rose::HTML::Form'))
1205             {
1206 1         3 $form = $arg;
1207              
1208 1 50       8 if(Scalar::Util::refaddr($form) eq Scalar::Util::refaddr($self))
1209             {
1210 1         241 croak "Cannot nest a form within itself";
1211             }
1212              
1213 0         0 $name = $form->form_name;
1214              
1215 0 0       0 croak "Cannot add form $form without a name" unless(defined $name);
1216 0 0       0 croak "Cannot add form with the same name as an existing field: $name"
1217             if($self->field($name));
1218              
1219 0 0       0 unless(defined $form->rank)
1220             {
1221 0         0 $self->increment_form_rank_counter; # XXX: Remove when form_rank_counter is removed
1222 0         0 $form->rank($next_rank++);
1223             }
1224             }
1225             else
1226             {
1227 73         145 $name = $arg;
1228 73         116 $form = shift;
1229              
1230 73 50       187 croak "Cannot add form with the same name as an existing field: $name"
1231             if($self->field($name));
1232              
1233 73 100       309 if(UNIVERSAL::isa($form, 'Rose::HTML::Form'))
    50          
1234             {
1235 59 100       325 if(Scalar::Util::refaddr($form) eq Scalar::Util::refaddr($self))
1236             {
1237 1         128 croak "Cannot nest a form within itself";
1238             }
1239              
1240             # Manually propagate the empty_is_ok attribute to sub-forms, but only if it's set
1241 58 100       202 $form->empty_is_ok(1) if($self->empty_is_ok);
1242             }
1243             elsif(ref $form eq 'HASH')
1244             {
1245 14 50       43 unless(exists $form->{'repeatable'})
1246             {
1247 0         0 croak "Missing key 'repeatable' in hash reference specification for form named '$name'";
1248             }
1249              
1250 14         29 my $repeat_spec = $form;
1251              
1252 14 100       34 if(ref $form->{'repeatable'})
1253             {
1254 1         3 @$repeat_spec{keys %{$form->{'repeatable'}}} = values %{$form->{'repeatable'}};
  1         4  
  1         4  
1255             }
1256             else
1257             {
1258             $repeat_spec->{'default_count'} = $form->{'repeatable'}
1259 13 100       39 unless(exists $repeat_spec->{'default_count'});
1260             }
1261              
1262 14         42 delete $form->{'repeatable'};
1263              
1264             $repeat_spec->{'prototype_form_spec'} = delete $repeat_spec->{'spec'}
1265 14 50       32 if($repeat_spec->{'spec'});
1266              
1267             $repeat_spec->{'prototype_form_spec'} = delete $repeat_spec->{'form_spec'}
1268 14 100       33 if($repeat_spec->{'form_spec'});
1269              
1270             $repeat_spec->{'prototype_form_class'} = delete $repeat_spec->{'class'}
1271 14 50       33 if($repeat_spec->{'class'});
1272              
1273             $repeat_spec->{'prototype_form_class'} = delete $repeat_spec->{'form_class'}
1274 14 100       36 if($repeat_spec->{'form_class'});
1275              
1276             $repeat_spec->{'prototype_form'} = delete $repeat_spec->{'form'}
1277 14 100       55 if($repeat_spec->{'form'});
1278              
1279 14         84 $form = ref($self)->object_type_class_loaded('repeatable form')->new(%$repeat_spec);
1280              
1281             # Manually propagate the empty_is_ok attribute to sub-forms, but only if it's set
1282 14 100 66     89 if($repeat_spec->{'empty_is_ok'} || $self->empty_is_ok)
1283             {
1284 1         5 $form->empty_is_ok(1);
1285             }
1286             }
1287             else
1288             {
1289 0         0 Carp::croak "Not a Rose::HTML::Form object: $form";
1290             }
1291              
1292 72         269 $form->form_name($name);
1293              
1294 72 100       248 unless(defined $form->rank)
1295             {
1296 37         161 $self->increment_form_rank_counter; # XXX: Remove when form_rank_counter is removed
1297 37         159 $form->rank($next_rank++);
1298             }
1299             }
1300              
1301 72 100       280 if(index($name, FF_SEPARATOR) >= 0)
1302             {
1303 2         35 my($parent_form, $local_name) = $self->choose_parent_form($name);
1304 2         8 $form->form_name($local_name);
1305 2         12 $form->parent_form($parent_form);
1306 2         16 $parent_form->add_form($local_name => $form);
1307             }
1308             else
1309             {
1310 70         203 $form->parent_form($self);
1311 70         191 $self->{'forms'}{$name} = $form;
1312             }
1313              
1314 72         259 push(@added_forms, $form);
1315             }
1316              
1317 66         203 my $depth = $self->form_depth + 1;
1318              
1319 66         197 foreach my $form (@added_forms)
1320             {
1321 72 100 100     237 if($form->recursive_init_fields || $form->isa('Rose::HTML::Form::Repeatable'))
1322             {
1323 42         1136 $self->recursive_init_fields(1);
1324             }
1325              
1326 72         1221 $form->form_depth($depth);
1327 72         186 $form->resync_field_names;
1328             }
1329              
1330 66         304 $self->_clear_form_generated_values;
1331 66         294 $self->resync_fields_by_name;
1332              
1333 66 50       348 return unless(defined wantarray);
1334 0         0 return @added_forms;
1335             }
1336              
1337             *add_form = \&add_forms;
1338              
1339             sub resync_field_names
1340             {
1341 224     224 0 471 my($self) = shift;
1342              
1343 224         631 foreach my $field ($self->fields)
1344             {
1345 1245         3761 $field->resync_name;
1346             }
1347              
1348 224         853 foreach my $form ($self->forms)
1349             {
1350 39         131 $form->resync_field_names;
1351             }
1352             }
1353              
1354             sub resync_fields_by_name
1355             {
1356 66     66 0 181 my($self) = shift;
1357              
1358 66         211 $self->{'fields_by_name'} = {};
1359              
1360 66         197 foreach my $field ($self->fields)
1361             {
1362 362         1039 $self->{'fields_by_name'}{$field->name} = $field;
1363             }
1364             }
1365              
1366             sub compare_forms
1367             {
1368 4064     4064 1 6768 my($self, $one, $two) = @_;
1369 8     8   82 no warnings 'uninitialized';
  8         44  
  8         9761  
1370 4064   100     7232 return $one->form_depth <=> $two->form_depth || $one->rank <=> $two->rank;
1371             }
1372              
1373             sub forms
1374             {
1375 1670     1670 1 2608 my($self) = shift;
1376              
1377 1670 50       3298 if(@_)
1378             {
1379 0         0 $self->delete_forms;
1380 0         0 $self->add_forms(@_);
1381 0 0       0 return unless(defined wantarray);
1382             }
1383              
1384 1670 100       3629 if(my $forms = $self->{'form_list'})
1385             {
1386 1490 100       4606 return wantarray ? @$forms : $forms;
1387             }
1388              
1389 180         331 my $forms = $self->{'forms'};
1390              
1391 180         534 $self->{'form_list'} = [ grep { defined } map { $forms->{$_} } $self->form_names ];
  119         282  
  119         234  
1392              
1393 180 50       401 return wantarray ? @{$self->{'form_list'}} : $self->{'form_list'};
  180         531  
1394             }
1395              
1396             sub form_names
1397             {
1398 182     182 1 354 my($self) = shift;
1399              
1400 182 100       441 if(my $names = $self->{'form_names'})
1401             {
1402 2 50       15 return wantarray ? @$names : $names;
1403             }
1404              
1405 180         248 my @info;
1406              
1407 180         358 while(my($name, $form) = each %{$self->{'forms'}})
  299         946  
1408             {
1409 119         380 push(@info, [ $name, $form ]);
1410             }
1411              
1412             $self->{'form_names'} =
1413 180         617 [ map { $_->[0] } sort { $self->compare_forms($a->[1], $b->[1]) } @info ];
  119         347  
  50         142  
1414              
1415 180 50       454 return wantarray ? @{$self->{'form_names'}} : $self->{'form_names'};
  180         593  
1416             }
1417              
1418             sub delete_repeatable_forms
1419             {
1420 0     0 1 0 my($self) = shift;
1421              
1422 0         0 foreach my $form (grep { $_->is_repeatable_form } $self->forms)
  0         0  
1423             {
1424 0         0 delete $self->{'forms'}{$form->form_name};
1425             }
1426              
1427 0         0 $self->_clear_form_generated_values;
1428              
1429 0         0 return;
1430             }
1431              
1432             sub delete_repeatable_form
1433             {
1434 4     4 1 2069 my($self, $name) = @_;
1435              
1436 4 50       26 $name = $name->form_name if(UNIVERSAL::isa($name, 'Rose::HTML::Form'));
1437              
1438 4 50 33     44 if(exists $self->{'forms'}{$name} && $self->{'forms'}{$name}->is_repeatable_form)
1439             {
1440 4         11 my $form = delete $self->{'forms'}{$name};
1441              
1442 4         13 $self->_clear_form_generated_values;
1443              
1444 4         83 return $form;
1445             }
1446              
1447 0         0 return undef;
1448             }
1449              
1450             sub delete_repeatable_fields
1451             {
1452 8     8 0 18 my($self) = shift;
1453              
1454 8         24 foreach my $form (grep { $_->is_repeatable_field } $self->forms)
  0         0  
1455             {
1456 0         0 delete $self->{'forms'}{$form->form_name};
1457             }
1458              
1459 8         34 $self->_clear_form_generated_values;
1460              
1461 8         16 return;
1462             }
1463              
1464             sub delete_repeatable_field
1465             {
1466 0     0 0 0 my($self, $name) = @_;
1467              
1468 0 0       0 $name = $name->form_name if(UNIVERSAL::isa($name, 'Rose::HTML::Form'));
1469              
1470 0 0 0     0 if(exists $self->{'forms'}{$name} && $self->{'forms'}{$name}->is_repeatable_field)
1471             {
1472 0         0 $self->_clear_form_generated_values;
1473 0         0 return delete $self->{'forms'}{$name};
1474             }
1475              
1476 0         0 return undef;
1477             }
1478              
1479             sub delete_forms
1480             {
1481 2     2 1 21 my($self) = shift;
1482              
1483             # Leave the repeatable fields which are implemented as a special case of repeatable forms
1484 2         19 foreach my $form (grep { !$_->is_repeatable_field } $self->forms)
  3         14  
1485             {
1486 3         8 delete $self->{'forms'}{$form->form_name};
1487             }
1488              
1489 2         15 $self->form_rank_counter(undef); # XXX: Remove when form_rank_counter is removed
1490 2         15 $self->_clear_form_generated_values;
1491 2         11 return;
1492             }
1493              
1494             sub delete_form
1495             {
1496 15     15 1 724 my($self, $name) = @_;
1497              
1498 15 50       85 $name = $name->form_name if(UNIVERSAL::isa($name, 'Rose::HTML::Form'));
1499              
1500 15 100       53 if(exists $self->{'forms'}{$name})
1501             {
1502 14         37 my $form = delete $self->{'forms'}{$name};
1503              
1504 14         45 $self->_clear_form_generated_values;
1505              
1506 14         68 return $form;
1507             }
1508              
1509 1         3 return undef;
1510             }
1511              
1512             sub clear_forms
1513             {
1514 307     307 0 498 my($self) = shift;
1515              
1516 307         609 foreach my $form ($self->forms)
1517             {
1518 186         459 $form->clear();
1519             }
1520             }
1521              
1522             sub reset_forms
1523             {
1524 4     4 0 8 my($self) = shift;
1525              
1526 4         11 foreach my $form ($self->forms)
1527             {
1528 0         0 $form->reset();
1529             }
1530             }
1531              
1532             sub _clear_form_generated_values
1533             {
1534 94     94   204 my($self) = shift;
1535 94         235 $self->{'form_list'} = undef;
1536 94         218 $self->{'form_names'} = undef;
1537 94         185 $self->{'form_depth'} = undef;
1538 94         351 $self->_clear_field_generated_values;
1539             }
1540              
1541             sub form_name
1542             {
1543 8327     8327 1 20552 my($self) = shift;
1544              
1545 8327 100       25467 return $self->{'form_name'} unless(@_);
1546 77         169 my $old_name = $self->{'form_name'};
1547 77         245 my $name = $self->{'form_name'} = shift;
1548 77         151 my %forms;
1549              
1550 77 100       236 if(my $parent_form = $self->parent_form)
1551             {
1552 6 100 33     49 if(defined $old_name && defined $name && $name ne $old_name)
      66        
1553             {
1554 2         46 $parent_form->delete_form($old_name);
1555 2         11 $parent_form->add_form($name => $self);
1556             }
1557             }
1558              
1559 77         187 return $name;
1560             }
1561              
1562             sub local_field
1563             {
1564 1608     1608 1 2789 my($self, $name) = (shift, shift);
1565              
1566 1608 100       3205 if(my $field = shift)
1567             {
1568 257         879 $field = $self->make_field($name, $field);
1569              
1570 257         972 $field->parent_form($self);
1571 8     8   66 no warnings 'uninitialized';
  8         17  
  8         25684  
1572 257 100       849 $field->name($name) unless(length $field->name);
1573 257         1235 $field->moniker($name);
1574 257         835 $self->{'fields_by_name'}{$field->name} = $field;
1575 257         1404 return $self->{'fields'}{$name} = $field;
1576             }
1577              
1578 1351   66     7028 return $self->{'fields'}{$name} || $self->{'fields_by_name'}{$name};
1579             }
1580              
1581             sub local_fields
1582             {
1583 113     113 1 186 my($self) = shift;
1584 113 50       189 return values %{ $self->{'fields'} || {} };
  113         468  
1585             }
1586              
1587             sub delete_fields
1588             {
1589 8     8 1 1544 my($self) = shift;
1590 8         39 $self->_clear_field_generated_values;
1591 8         35 $self->{'fields'} = {};
1592 8         263 $self->{'fields_by_name'} = {};
1593 8         41 $self->delete_repeatable_fields;
1594 8         34 $self->field_rank_counter(undef);
1595 8         40 return;
1596             }
1597              
1598             sub delete_field
1599             {
1600 2     2 1 9 my($self, $name) = @_;
1601              
1602 2 50       16 $name = $name->name if(UNIVERSAL::isa($name, 'Rose::HTML::Form::Field'));
1603              
1604 2         10 $self->_clear_field_generated_values;
1605              
1606 2         8 my $field1 = delete $self->{'fields'}{$name};
1607 2         10 my $field2 = delete $self->{'fields_by_name'}{$name};
1608 2   33     13 return $field1 || $field2;
1609             }
1610              
1611             sub field
1612             {
1613 3084     3084 1 17368 my($self, $name) = (shift, shift);
1614              
1615 3084 100       8985 return $self->{'field_cache'}{$name} if($self->{'field_cache'}{$name});
1616              
1617 2455         3182 my $sep_pos;
1618              
1619             # Non-hierarchical name
1620 2455 100       5224 if(($sep_pos = index($name, FF_SEPARATOR)) < 0)
1621             {
1622 1557         3368 return $self->{'field_cache'}{$name} = $self->local_field($name, @_);
1623             }
1624              
1625             # First check if it's a local compound field
1626 898         1626 my $prefix = substr($name, 0, $sep_pos);
1627 898         1560 my $rest = substr($name, $sep_pos + 1);
1628 898         1576 my $field = $self->field($prefix);
1629              
1630 898 100       2217 if(UNIVERSAL::isa($field, 'Rose::HTML::Form::Field::Compound'))
1631             {
1632 17         70 $field = $field->field($rest);
1633 17 50       143 return ($self->{'field_cache'}{$name} = $field) if($field);
1634             }
1635              
1636 881         1704 my($parent_form, $local_name) = $self->find_parent_form($name);
1637              
1638 881 50       1793 return undef unless($parent_form);
1639              
1640 881         1779 return $self->{'field_cache'}{$name} = $parent_form->field($local_name, @_);
1641             }
1642              
1643             sub fields
1644             {
1645 928     928 1 2478 my($self) = shift;
1646              
1647 928 100       1844 if(@_)
1648             {
1649 2         9 $self->delete_fields;
1650 2         9 $self->add_fields(@_);
1651             }
1652              
1653 928 100       2131 if(my $fields = $self->{'field_list'})
1654             {
1655 682 100       2224 return wantarray ? @$fields : $fields;
1656             }
1657              
1658 246         462 my $fields = $self->{'fields'};
1659 246         391 my $fields_by_name = $self->{'fields_by_name'};
1660              
1661             $self->{'field_list'} =
1662             [
1663 1605         2879 grep { defined }
1664             map
1665             {
1666 246 100       764 if(/$FF_SEPARATOR_RE([^$FF_SEPARATOR_RE]+)/o)
  1605         4510  
1667             {
1668 610 0 33     1290 $self->field($_) || $fields->{$1} || $fields_by_name->{$1};
1669             }
1670             else
1671             {
1672 995 50 66     2446 $fields->{$_} || $fields_by_name->{$_} || $self->field($_);
1673             }
1674             }
1675             $self->field_monikers
1676             ];
1677              
1678 246 50       685 return wantarray ? @{$self->{'field_list'}} : $self->{'field_list'};
  246         844  
1679             }
1680              
1681             sub fields_depth_first
1682             {
1683 52     52 1 138 my($self) = shift;
1684              
1685 52         110 my @fields = sort { $a->rank <=> $b->rank } $self->local_fields;
  17         95  
1686              
1687 52         107 foreach my $form ($self->forms)
1688             {
1689 42         132 push(@fields, $form->fields_depth_first);
1690             }
1691              
1692 52 50       135 return wantarray ? @fields : \@fields;
1693             }
1694              
1695             sub field_monikers
1696             {
1697 267     267 1 1838 my($self) = shift;
1698              
1699 267 100       673 if(my $names = $self->{'field_monikers'})
1700             {
1701 25 100       196 return wantarray ? @$names : $names;
1702             }
1703              
1704 242         426 my @info;
1705              
1706 242         790 $self->_find_field_info($self, \@info);
1707              
1708             $self->{'field_monikers'} =
1709 242 50       1074 [ map { $_->[2] } sort { $self->compare_forms($a->[0], $b->[0]) || $self->compare_fields($a->[1], $b->[1]) } @info ];
  1598         3702  
  4014         8959  
1710              
1711 242 50       735 return wantarray ? @{$self->{'field_monikers'}} : $self->{'field_monikers'};
  242         1239  
1712             }
1713              
1714 13     13 1 82 sub field_names { shift->field_monikers(@_) }
1715              
1716             sub _find_field_info
1717             {
1718 547     547   1031 my($self, $form, $list) = @_;
1719              
1720 547         796 while(my($name, $field) = each %{$form->{'fields'}})
  2145         6512  
1721             {
1722 1598         4056 push(@$list, [ $form, $field, $field->fq_moniker ]);
1723             }
1724              
1725 547         1307 foreach my $sub_form ($form->forms)
1726             {
1727 305         766 $form->_find_field_info($sub_form, $list);
1728             }
1729             }
1730              
1731             sub find_parent_form
1732             {
1733 1241     1241 0 2230 my($self, $name) = @_;
1734              
1735             # Non-hierarchical name
1736 1241 100       2883 if(index($name, FF_SEPARATOR) < 0)
1737             {
1738 277 50       565 return $self->local_form($name) ? ($self, $name) : undef;
1739             }
1740              
1741 964         1332 my $parent_form;
1742              
1743 964         4330 while($name =~ s/^([^$FF_SEPARATOR_RE]+)$FF_SEPARATOR_RE//o)
1744             {
1745 1335         2923 my $parent_name = $1;
1746 1335 100       2827 last if($parent_form = $self->local_form($parent_name));
1747             }
1748              
1749 964 100       2032 unless(defined $parent_form)
1750             {
1751             # Maybe this form ($self) is the parent?
1752 51 100       139 return ($self, $name) if($self->local_field($name));
1753 21         50 return undef;
1754             }
1755              
1756 913 50       2563 return wantarray ? ($parent_form, $name) : $parent_form;
1757             }
1758              
1759             sub choose_parent_form
1760             {
1761 2     2 0 9 my($self, $name) = @_;
1762              
1763             # Non-hierarchical name
1764 2 50       12 if(index($name, FF_SEPARATOR) < 0)
1765             {
1766 0 0       0 return wantarray ? ($self, $name) : $self;
1767             }
1768              
1769 2         6 my($parent_form, $local_name);
1770              
1771 2         58 while($name =~ s/^(.+)$FF_SEPARATOR_RE([^$FF_SEPARATOR_RE]+)$//o)
1772             {
1773 2         9 $local_name = $2;
1774 2 50       10 last if($parent_form = $self->form($1));
1775             }
1776              
1777 2 50       14 return wantarray ? ($parent_form, $local_name) : $parent_form;
1778             }
1779              
1780             sub fq_form_name
1781             {
1782 6250     6250 0 9242 my($self) = shift;
1783              
1784 6250 100       11786 return $self->form_name unless($self->parent_form);
1785              
1786 2167         3202 my @parts;
1787 2167         2895 my $form = $self;
1788              
1789 2167         4294 while(my $parent_form = $form->parent_form)
1790             {
1791 4044         7112 unshift(@parts, $form->form_name);
1792 4044         9361 $form = $parent_form;
1793             }
1794              
1795 2167 50       8999 return @parts ? join(FF_SEPARATOR, @parts) : '';
1796             }
1797              
1798             sub form_name_context
1799             {
1800 126     126 0 194 my($self) = shift;
1801              
1802 126 100       278 return undef unless($self->parent_form);
1803              
1804 18         31 my @context;
1805 18         25 my $form = $self;
1806              
1807 18         30 for(;;)
1808             {
1809 45 100       87 last unless($form->parent_form);
1810 27         66 unshift(@context, $form->form_name);
1811 27         65 $form = $form->parent_form;
1812             }
1813              
1814 18         98 return join(FF_SEPARATOR, @context) . FF_SEPARATOR;
1815             }
1816              
1817             sub local_form
1818             {
1819 2172     2172 1 3770 my($self, $name) = @_;
1820 2172 100       6129 return $self->{'forms'}{$name} if(exists $self->{'forms'}{$name});
1821 1059         3670 return undef;
1822             }
1823              
1824             sub form
1825             {
1826 561     561 1 8088 my($self, $name) = (shift, shift);
1827              
1828             # Set form
1829 561 100       1292 if(@_)
1830             {
1831 1         5 my $form = shift;
1832 1         5 $self->delete_form($name);
1833 1         6 return $self->add_form($name => $form);
1834             }
1835              
1836             # Local form?
1837 560 100       1295 if(my $form = $self->local_form($name))
1838             {
1839 200         1071 return $form;
1840             }
1841              
1842             # Look up nested form
1843 360         1014 my($parent_form, $local_name) = $self->find_parent_form($name);
1844 360 100       1659 return undef unless(defined $parent_form);
1845 62         191 return $parent_form->form($local_name);
1846             }
1847              
1848             sub _html_table
1849             {
1850 5     5   15 my($self, %args) = @_;
1851              
1852 5 50       17 my $xhtml = delete $args{'_xhtml'} ? 'xhtml' : 'html';
1853 5         13 my $xhtml_field = "${xhtml}_field";
1854 5         10 my $xhtml_label = "${xhtml}_label";
1855              
1856             my $max_button_depth =
1857 5 50       13 exists $args{'max_button_depth'} ? $args{'max_button_depth'} : 1;
1858              
1859 5 50       13 $args{'class'} = defined $args{'class'} ?
1860             "$args{'class'} form" : 'form';
1861              
1862 5   50     33 $args{'tr'} ||= {};
1863 5   50     23 $args{'td'} ||= {};
1864              
1865             $args{'table'}{'class'} = defined $args{'table'}{'class'} ?
1866             "$args{'table'}{'class'} form" :
1867 5 50       23 defined $args{'class'} ? $args{'class'} : undef;
    50          
1868              
1869 5 50       19 $args{'tr'}{'class'} = defined $args{'tr'}{'class'} ?
1870             "$args{'tr'}{'class'} field" : 'field';
1871              
1872 5         39 my $html = join('', map { $_->$xhtml() } $self->pre_children);
  2         11  
1873              
1874 0         0 $html .= join("\n", map { $_->$xhtml_field() }
1875 5         16 grep { $_->isa('Rose::HTML::Form::Field::Hidden') } $self->fields);
  10         54  
1876              
1877 5 100       14 $html .= "\n\n" if($html);
1878              
1879 5         22 $html .= '<table' . Rose::HTML::Util::html_attrs_string($args{'table'}) . ">\n";
1880              
1881 5         253 my $form_start = "start_$xhtml";
1882 5         12 my $form_end = "end_$xhtml";
1883              
1884 5         8 my $i = 1;
1885              
1886 5         7 my @buttons;
1887              
1888 5         16 foreach my $field (grep { !$_->isa('Rose::HTML::Form::Field::Hidden') } $self->fields_depth_first)
  10         43  
1889             {
1890 10 50       35 if($field->is_button)
1891             {
1892 0 0       0 next if($field->field_depth > $max_button_depth);
1893              
1894 0 0       0 if($field->field_depth == 1)
1895             {
1896 0         0 push(@buttons, $field);
1897 0         0 next;
1898             }
1899             }
1900              
1901 10 50       61 if($field->isa('Rose::HTML::Form::Field::File'))
1902             {
1903 0         0 $form_start = "start_multipart_$xhtml";
1904             }
1905              
1906 10 100       31 my $odd_even = $i++ % 2 ? 'odd' : 'even';
1907              
1908 10         28 local $args{'tr'}{'class'} = "field-$odd_even";
1909 10 50       34 local $args{'td'}{'class'} = $args{'td'}{'class'} ? "$args{'td'}{'class'} label" : 'label';
1910              
1911 10         32 my $label = $field->$xhtml_label();
1912              
1913 10 50       25 unless($label)
1914             {
1915 10         30 my $name = $field->name;
1916              
1917 10         21 for($name)
1918             {
1919 10         24 tr[_.][ ];
1920 10         98 s/\b(\w)/\u$1/g;
1921             }
1922              
1923 10         38 $label = Rose::HTML::Label->new(contents => Rose::HTML::Util::escape_html($name));
1924              
1925 10 50       36 if($field->html_attr_exists('id'))
1926             {
1927 0         0 $label->for($field->html_attr('id'));
1928             }
1929              
1930 10         32 $label = $label->$xhtml();
1931             }
1932              
1933 10 50       61 if($field->is_button)
1934             {
1935 0         0 local $args{'td'}{'colspan'} = 2;
1936             $html .= '<tr' . Rose::HTML::Util::html_attrs_string($args{'tr'}) . ">\n" .
1937 0         0 '<td' . Rose::HTML::Util::html_attrs_string($args{'td'}) . '>' .
1938             $field->$xhtml_field . "</td>\n</tr>\n";
1939             }
1940             else
1941             {
1942             $html .= '<tr' . Rose::HTML::Util::html_attrs_string($args{'tr'}) . ">\n" .
1943 10         37 '<td' . Rose::HTML::Util::html_attrs_string($args{'td'}) . ">$label</td>\n";
1944              
1945 10         426 $args{'td'}{'class'} =~ s/(?:^| )label$//;
1946 10 50       29 $args{'td'}{'class'} = $args{'td'}{'class'} ? "$args{'td'}{'class'} field" : 'field';
1947              
1948 10         30 $html .= '<td' . Rose::HTML::Util::html_attrs_string($args{'td'}) . '>' .
1949             $field->$xhtml() .
1950             "</td>\n</tr>\n";
1951             }
1952             }
1953              
1954 5 50       16 if(@buttons)
1955             {
1956 0 0       0 my $odd_even = $i++ % 2 ? 'odd' : 'even';
1957              
1958 0         0 local $args{'tr'}{'class'} = "field-$odd_even buttons";
1959 0 0       0 local $args{'td'}{'class'} = $args{'td'}{'class'} ? "$args{'td'}{'class'} label" : 'label';
1960              
1961 0         0 local $args{'td'}{'colspan'} = 2;
1962              
1963             $html .= '<tr' . Rose::HTML::Util::html_attrs_string($args{'tr'}) . ">\n" .
1964             '<td' . Rose::HTML::Util::html_attrs_string($args{'td'}) . '>' .
1965 0         0 join(' ', map { $_->$xhtml_field() } @buttons) .
  0         0  
1966             "</td>\n</tr>\n";
1967             }
1968              
1969 5         24 $html .= "</table>\n\n" . join('', map { $_->$xhtml() } $self->post_children);
  2         9  
1970              
1971 5 100       27 $html .= "\n\n" unless($html =~ /\n\n\z/);
1972              
1973 5         18 return $self->$form_start() . "\n\n$html" . $self->$form_end();
1974             }
1975              
1976 0     0 0 0 sub html_table { shift->_html_table(@_) }
1977 5     5 0 22 sub xhtml_table { shift->_html_table(@_, _xhtml => 1) }
1978              
1979             sub app
1980             {
1981 0     0 1 0 my($self) = shift;
1982 0 0       0 Scalar::Util::weaken($self->{'app'} = shift) if(@_);
1983 0         0 return $self->{'app'};
1984             }
1985              
1986             sub app_form
1987             {
1988 0     0 0 0 my($self) = shift;
1989 0 0       0 Scalar::Util::weaken($self->{'app_form'} = shift) if(@_);
1990 0         0 return $self->{'app_form'};
1991             }
1992              
1993             our $AUTOLOAD;
1994              
1995             sub AUTOLOAD
1996             {
1997 3     3   3988 my($self) = $_[0];
1998              
1999 3 50       16 my $class = ref($self) or croak "$self is not an object";
2000              
2001 3         22 my $delegate = $class->delegate_to_subforms;
2002              
2003 3 50       80 unless($delegate)
2004             {
2005 0         0 goto &Rose::HTML::Object::AUTOLOAD;
2006             }
2007              
2008 3         8 my $method = $AUTOLOAD;
2009 3         23 $method =~ s/.*://;
2010              
2011 3         21 my $to_form;
2012              
2013 3         15 foreach my $form ($self->forms)
2014             {
2015 3 100       134 if($form->can($method))
2016             {
2017 2         13 $to_form = $form;
2018 2         11 last;
2019             }
2020             }
2021              
2022 3 100       17 unless($to_form)
2023             {
2024 1         6 $Rose::HTML::Object::AUTOLOAD = $AUTOLOAD;
2025 1         24 goto &Rose::HTML::Object::AUTOLOAD;
2026             }
2027              
2028 2 50       8 if($delegate eq 'compile')
    0          
2029             {
2030 2         7 my $form_name = $to_form->form_name;
2031              
2032 8     8   67 no strict 'refs';
  8         18  
  8         1332  
2033 2     2   18 *$AUTOLOAD = sub { shift->form($form_name)->$method(@_) };
  2         16  
2034 2         6 ${$class . '::__AUTODELEGATED'}{$method} = 1;
  2         12  
2035 2         15 goto &$AUTOLOAD;
2036             }
2037             elsif($delegate eq 'runtime')
2038             {
2039 0           $to_form->$method(@_);
2040             }
2041              
2042 0           $Rose::HTML::Object::AUTOLOAD = $AUTOLOAD;
2043 0           goto &Rose::HTML::Object::AUTOLOAD;
2044             }
2045              
2046             if(__PACKAGE__->localizer->auto_load_messages)
2047             {
2048             __PACKAGE__->localizer->load_all_messages;
2049             }
2050              
2051 8     8   3335 use utf8; # The __DATA__ section contains UTF-8 text
  8         90  
  8         52  
2052              
2053             1;
2054              
2055             __DATA__
2056             [% LOCALE en %]
2057              
2058             FORM_HAS_ERRORS = "One or more fields have errors."
2059              
2060             [% LOCALE de %]
2061              
2062             # oder "Es sind Fehler aufgetreten."
2063             FORM_HAS_ERRORS = "Ein oder mehrere Felder sind fehlerhaft."
2064              
2065             [% LOCALE fr %]
2066              
2067             FORM_HAS_ERRORS = "Erreurs dans un ou plusieurs champs."
2068              
2069             [% LOCALE bg %]
2070              
2071             FORM_HAS_ERRORS = "Има грешка в поне едно поле."
2072              
2073             __END__
2074              
2075             =head1 NAME
2076              
2077             Rose::HTML::Form - HTML form base class.
2078              
2079             =head1 SYNOPSIS
2080              
2081             package PersonForm;
2082              
2083             use base 'Rose::HTML::Form';
2084              
2085             use Person;
2086              
2087             sub build_form
2088             {
2089             my($self) = shift;
2090              
2091             $self->add_fields
2092             (
2093             name => { type => 'text', size => 25, required => 1 },
2094             email => { type => 'email', size => 50, required => 1 },
2095             phone => { type => 'phone' },
2096             );
2097             }
2098              
2099             sub validate
2100             {
2101             my($self) = shift;
2102              
2103             # Base class will validate individual fields in isolation,
2104             # confirming that all required fields are filled in, and that
2105             # the email address and phone number are formatted correctly.
2106             my $ok = $self->SUPER::validate(@_);
2107             return $ok unless($ok);
2108              
2109             # Inter-field validation goes here
2110             if($self->field_value('name') ne 'John Doe' &&
2111             $self->field_value('phone') =~ /^555/)
2112             {
2113             $self->error('Only John Doe can have a 555 phone number.');
2114             return 0;
2115             }
2116              
2117             return 1;
2118             }
2119              
2120             sub init_with_person # give a friendlier name to a base-class method
2121             {
2122             my($self, $person) = @_;
2123             $self->init_with_object($person);
2124             }
2125              
2126             sub person_from_form
2127             {
2128             my($self) = shift;
2129              
2130             # Base class method does most of the work
2131             my $person = $self->object_from_form(class => 'Person');
2132              
2133             # Now fill in the non-obvious details...
2134             # e.g., set alt phone to be the same as the regular phone
2135             $person->alt_phone($self->field_value('phone'));
2136              
2137             return $person;
2138             }
2139              
2140             ...
2141              
2142             #
2143             # Sample usage in a hypothetical web application
2144             #
2145              
2146             $form = PersonForm->new;
2147              
2148             if(...)
2149             {
2150             # Get query parameters in a hash ref and pass to the form
2151             my $params = MyWebServer->get_query_params();
2152             $form->params($params);
2153              
2154             # ...or initialize form params from a CGI object
2155             # $form->params_from_cgi($cgi); # $cgi "isa" CGI
2156              
2157             # ...or initialize params from an Apache request object
2158             # (mod_perl 1 and 2 both supported)
2159             # $form->params_from_apache($r);
2160              
2161             # Initialize the fields based on params
2162             $form->init_fields();
2163              
2164             unless($form->validate)
2165             {
2166             return error_page(error => $form->error);
2167             }
2168              
2169             $person = $form->person_from_form; # $person is a Person object
2170              
2171             do_something_with($person);
2172             ...
2173             }
2174             else
2175             {
2176             $person = ...; # Get or create a Person object somehow
2177              
2178             # Initialize the form with the Person object
2179             $form->init_with_person($person);
2180              
2181             # Pass the initialized form object to the template
2182             display_page(form => $form);
2183             }
2184             ...
2185              
2186             =head1 DESCRIPTION
2187              
2188             L<Rose::HTML::Form> is more than just an object representation of the E<lt>formE<gt> HTML tag. It is meant to be a base class for custom form classes that can be initialized with and return "rich" values such as objects, or collections of objects.
2189              
2190             Building up a reusable library of form classes is extremely helpful when building large web applications with forms that may appear in many different places. Similar forms can inherit from a common subclass, and forms may be nested.
2191              
2192             This class inherits from, and follows the conventions of, L<Rose::HTML::Object>. Inherited methods that are not overridden will not be documented a second time here. See the L<Rose::HTML::Object> documentation for more information.
2193              
2194             =head1 OVERVIEW
2195              
2196             L<Rose::HTML::Form> objects are meant to encapsulate an entire HTML form, including all fields within the form. While individual fields may be queried and manipulated, the intended purpose of this class is to treat the form as a "black box" as much as possible.
2197              
2198             For example, instead of asking a form object for the values of the "name", "email", and "phone" fields, the user would ask the form object to return a new "Person" object that encapsulates those values.
2199              
2200             Form objects should also accept initialization through the same kinds of objects that they return. Subclasses are encouraged to create methods such as (to use the example described above) C<init_with_person()> and C<person_from_form()> in order to do this. The generic methods L<init_with_object()|/init_with_object> and L<object_from_form()|/object_from_form> are meant to ease the implementation of such custom methods.
2201              
2202             Form objects can also take input through a hash. Each hash key correspond to a field (or subfield) name, and each value is either a scalar or a reference to an array of scalars (for multiple-value fields). This hash of parameters can be queried and manipulated before finally calling L<init_fields()|/init_fields> in order to initialize the fields based on the current state of the parameters.
2203              
2204             Compound fields (fields consisting of more than one HTML field, such as a month/day/year date field with separate text fields for each element of the date) may be "addressed" by hash arguments using both top-level names (e.g., "birthday") or by subfield names (e.g., "birthday.month", "birthday.day", "birthday.year"). If the top-level name exists in the hash, then subfield names are ignored. See L<Rose::HTML::Form::Field::Compound> for more information on compound fields.
2205              
2206             Each form has a list of field objects. Each field object is stored under a name, which may or may not be the same as the field name, which may or may not be the same as the "name" HTML attribute for any of the HTML tags that make up that field.
2207              
2208             Forms are validated by calling L<validate()|Rose::HTML::Form::Field/validate> on each field object. If any individual field does not validate, then the form is invalid. Inter-field validation is the responsibility of the form object.
2209              
2210             =head1 HIERARCHY
2211              
2212             Though L<Rose::HTML::Form> objects may have L<children|Rose::HTML::Object/children> just like any other L<Rose::HTML::Object>-derived object, the L<fields|/fields> that make up the form are treated like "immutable children" in that they can never be removed using the standard child-related APIs. Instead, the fields exist in the middle of any other children.
2213              
2214             L<Pushing|Rose::HTML::Object/push_children> a child adds it after the list of fields. L<Unshifting|Rose::HTML::Object/unshift_children> a child adds it before the list of fields. L<Popping|Rose::HTML::Object/pop_children> or L<shifting|Rose::HTML::Object/shift_children> children will pull children through, past the fields, to exit the list of children at either end. In other words, children manipulated using the child object APIs will "flow around" the list of fields.
2215              
2216             If a particular field is a group of sibling HTML elements with no real parent HTML element (e.g., a L<radio button group|Rose::HTML::Form::Field::RadioButtonGroup>), then the individual sibling items will be flattened out into the list returned by the L<children|Rose::HTML::Object/children> method.
2217              
2218             If, on the other hand, a field has a true parent/child relationship (e.g., a L<select box|Rose::HTML::Form::Field::SelectBox> which contains zero or more L<options|Rose::HTML::Form::Field::Option>) then the items it contains are not flattened by the L<children|Rose::HTML::Object/children> method.
2219              
2220             For example, if a form has three fields, a text field, a checkbox group with three checkboxes, and a select box with three options, then the L<children|Rose::HTML::Object/children> method will return five objects: the L<text field|Rose::HTML::Form::Field::Text> object, the three L<checkboxes|Rose::HTML::Form::Field::Checkbox> objects, and a L<select box|Rose::HTML::Form::Field::SelectBox> object.
2221              
2222             See the L<hierarchy section|Rose::HTML::Form::Field/HIERARCHY> of the L<Rose::HTML::Form::Field> documentation for more information about how fields made up of multiple HTML tags are treated with respect to parent/child relationships.
2223              
2224             Finally, note that L<nested forms|/"NESTED FORMS"> do not affect the parent/child hierarchy presented by the child-related methods inherited from L<Rose::HTML::Object> since the fields contained in nested forms are flattened out into the field list of parent form, as described in the next section.
2225              
2226             =head1 NESTED FORMS
2227              
2228             Each form can have zero or more fields as well as zero or more sub-forms. Since E<lt>formE<gt> HTML tags cannot be nested, this nesting of form objects appears "flattened" in the external interfaces such as HTML generation or field addressing.
2229              
2230             Here's a simple example of a nested form made up of a C<PersonForm> and an C<AddressForm>. (Assume C<PersonForm> is constructed as per the L<synopsis|/SYNOPSIS> above, and C<AddressForm> is similar, with street, city, state, and zip code fields.)
2231              
2232             package PersonAddressForm;
2233              
2234             use PersonForm;
2235             use AddressForm;
2236              
2237             sub build_form
2238             {
2239             my($self) = shift;
2240              
2241             $self->add_forms
2242             (
2243             person => PersonForm->new,
2244             address => AddressForm->new,
2245             );
2246             }
2247              
2248             Each sub-form is given a name. Sub-field addressing incorporates that name in much the same way as L<compound field|Rose::HTML::Form::Field::Compound> addressing, with dots (".") used to delimit the hierarchy. Here are two different ways to get at the person's email field.
2249              
2250             $form = PersonAddressForm->new;
2251              
2252             # These are equivalent
2253             $email_field = $form->field('person.email');
2254             $email_field = $form->form('person')->field('email');
2255              
2256             Methods on the sub-forms maybe accessed in a similar manner.
2257              
2258             $person = $form->form('person')->person_from_form();
2259              
2260             By default, methods are delegated to sub-forms automatically, so this works too.
2261              
2262             $person = $form->person_from_form();
2263              
2264             (See the L<delegate_to_subforms()|/delegate_to_subforms> method to learn how to alter this behavior.)
2265              
2266             Nested forms may have their own fields as well, and the nesting may continue to an arbitrary depth. Here's a form that contains a C<PersonAddressForm> as well as two fields of its own.
2267              
2268             package PersonAddressPetsForm;
2269              
2270             use PersonAddressForm;
2271              
2272             sub build_form
2273             {
2274             my($self) = shift;
2275              
2276             $self->add_form(pa => PersonAddressForm->new);
2277              
2278             $self->add_fields
2279             (
2280             dog => { type => 'text', size => 30 },
2281             cat => { type => 'text', size => 30 },
2282             );
2283             }
2284              
2285             Sub-form and field addressing works as expected. Here are several equivalent ways to get at the person's email field.
2286              
2287             $form = PersonAddressPetsForm->new;
2288              
2289             # These are all equivalent
2290             $email_field = $form->field('pa.person.email');
2291             $email_field = $form->form('pa.person')->field('email');
2292             $email_field = $form->form('pa')->form('person')->field('email');
2293              
2294             Sub-form method calls and delegation also works as expected.
2295              
2296             # Call method on the PersonForm, two different ways
2297             $person = $form->form('pa')->form('person')->person_from_form();
2298             $person = $form->form('pa.person')->person_from_form();
2299              
2300             # Rely on delegation instead
2301             $person = $form->form('pa')->person_from_form();
2302             $person = $form->person_from_form();
2303              
2304             Nested forms are a great way to build on top of past work. When combined with traditional subclassing, form generation can be entirely cleansed of duplicated code.
2305              
2306             =head1 HTML ATTRIBUTES
2307              
2308             Valid attributes:
2309              
2310             accept
2311             accept-charset
2312             accesskey
2313             action
2314             class
2315             dir
2316             enctype
2317             id
2318             lang
2319             method
2320             name
2321             onblur
2322             onclick
2323             ondblclick
2324             onfocus
2325             onkeydown
2326             onkeypress
2327             onkeyup
2328             onmousedown
2329             onmousemove
2330             onmouseout
2331             onmouseover
2332             onmouseup
2333             onreset
2334             onsubmit
2335             style
2336             tabindex
2337             target
2338             title
2339             value
2340             xml:lang
2341              
2342             Required attributes (default values in parentheses):
2343              
2344             action
2345             enctype (application/x-www-form-urlencoded)
2346             method (get)
2347              
2348             =head1 CLASS METHODS
2349              
2350             =over 4
2351              
2352             =item B<default_recursive_init_fields [BOOL]>
2353              
2354             Get or set a boolean value that determines the default value of the L<recursive_init_fields|/recursive_init_fields> object attribute. The default value is false.
2355              
2356             =item B<delegate_to_subforms [SETTING]>
2357              
2358             Get or set the value that determines how (or if) forms of this class delegate unresolved method calls to L<sub-forms|/"NESTED FORMS">. If a method is called on a form of this class, and that method does not exist in this class or any other class in its inheritance hierarchy, then the method may optionally be delegated to a L<sub-forms|/"NESTED FORMS">. Valid values for SETTING are:
2359              
2360             =over 4
2361              
2362             =item "B<0>"
2363              
2364             A value of "0" (or undef or any other false value) means that no sub-form delegation will be attempted.
2365              
2366             =item "B<1>"
2367              
2368             A value of "1" means the same thing as a value of "runtime" (see below).
2369              
2370             =item "B<compile>"
2371              
2372             For each unresolved method call, each sub-form is is considered in the order that they are returned from the L<forms|/forms> method until one is found that L<can|perlobj/can> handle this method. If one is found, then a new proxy method is added to this class that calls the requested method on the sub-form, passing all arguments unmodified. That proxy method is then called.
2373              
2374             Subsequent invocations of this method will no longer trigger the search process. Instead, they will be handled by the newly-compiled proxy method. This is more efficient than repeating the sub-form search each time, but it also means that a change in the list of sub-forms could render the newly compiled method useless (e.g., if the sub-form it delegates to is removed).
2375              
2376             If no sub-form can handle the method, then a fatal "unknown method" error occurs.
2377              
2378             =item "B<runtime>"
2379              
2380             For each unresolved method call, each sub-form is is considered in the order that they are returned from the L<forms|/forms> method until one is found that L<can|perlobj/can> handle this method. If one is found, then the method is called on that sub-form, passing all arguments unmodified.
2381              
2382             Subsequent invocations of this method will trigger the same search process, again looking for a a sub-form that can handle it. This is less efficient than compiling a new proxy method as described in the documentation for the "compile" setting above, but it does mean that any changes in the list of sub-forms will be handled correctly.
2383              
2384             If no sub-form can handle the method, then a fatal "unknown method" error occurs.
2385              
2386             =back
2387              
2388             The default value for SETTING is B<compile>. See the L<nested forms|/"NESTED FORMS"> section for some examples of sub-form delegation.
2389              
2390             =item B<default_trim_xy_params [BOOL]>
2391              
2392             Get or set a boolean value that is used as the default value of the L<trim_xy_params|/trim_xy_params> object attribute. The default value is true.
2393              
2394             =back
2395              
2396             =head1 CONSTRUCTOR
2397              
2398             =over 4
2399              
2400             =item B<new PARAMS>
2401              
2402             Constructs a new L<Rose::HTML::Form> object based on PARAMS, where PARAMS are name/value pairs. Any object method is a valid parameter name.
2403              
2404             =back
2405              
2406             =head1 OBJECT METHODS
2407              
2408             =over 4
2409              
2410             =item B<add_field ARGS>
2411              
2412             Convenience alias for L<add_fields()|/add_fields>.
2413              
2414             =item B<add_fields ARGS>
2415              
2416             Add the fields specified by ARGS to the list of fields contained in this form. ARGS may be a list or a reference to an array. Valid formats for elements of ARGS are:
2417              
2418             =over 4
2419              
2420             =item B<Field objects>
2421              
2422             If an argument is "isa" L<Rose::HTML::Form::Field>, then it is added to the list of fields, stored under the name returned by the field's L<name|Rose::HTML::Form::Field/name> method.
2423              
2424             =item B<Field name/type pairs>
2425              
2426             A pair of simple scalars is taken as a field name and type. The class that corresponds to the specified field type is determined by calling the L<field_type_class|/field_type_class> method. Then a new object of that class is constructed and added to the form.
2427              
2428             =item B<Field name/hashref pairs>
2429              
2430             A simple scalar followed by a reference to a hash it taken as a field name and a collection of object attributes. The referenced hash must contain a value for the C<type> key. The field class that corresponds to the specified field type is determined by calling the L<field_type_class|/field_type_class> method. Then a new object of that class is constructed, with the remaining key/value pairs in the hash are passed to the constructor. The completed field object is then added to the form.
2431              
2432             =item B<Field name/object pairs>
2433              
2434             A simple scalar followed by an object that "isa" L<Rose::HTML::Form::Field> is stored as-is, under the specified name.
2435              
2436             =back
2437              
2438             Each field's L<parent_form|Rose::HTML::Form::Field/parent_form> is set to the form object. If the field's L<rank|Rose::HTML::Form::Field/rank> is undefined, it's set to the value of the form's L<field_rank_counter|/field_rank_counter> attribute and the rank counter is incremented.
2439              
2440             Adding a field with the same name as an existing L<sub-form|/"NESTED FORMS"> will cause a fatal error.
2441              
2442             Examples:
2443              
2444             # Name/hashref pairs
2445             $form->add_fields(name => { type => 'text', size => 20 },
2446             email => { type => 'email', size => 30 });
2447              
2448             # Name/type pairs
2449             $form->add_fields(name => 'text',
2450             email => 'email');
2451              
2452             $name_field =
2453             Rose::HTML::Form::Field::Text->new(name => 'name',
2454             size => 25);
2455              
2456             $email_field =
2457             Rose::HTML::Form::Field::Text->new(name => 'email',
2458             size => 50);
2459              
2460             # Object arguments
2461             $form->add_fields($name_field, $email_field);
2462              
2463             # Name/object pairs
2464             $form->add_fields(name => $name_field,
2465             email => $email_field);
2466              
2467             # Mixed
2468             $form->add_fields($name_field,
2469             email => $email_field,
2470             nick => { type => 'text', size => 15 },
2471             age => 'text');
2472              
2473             =item B<add_field_type_classes [MAP]>
2474              
2475             Add entries to the L<field_type_classes|/field_type_classes> hash that maps field type strings to the names of the L<Rose::HTML::Form::Field>-derived classes. Example:
2476              
2477             My::HTML::Form->add_field_type_classes
2478             (
2479             nick => 'My::HTML::Form::Field::Nickname',
2480             age => 'My::HTML::Form::Field::Age',
2481             ...
2482             );
2483              
2484             This method is an alias for the L<add_object_type_classes|Rose::HTML::Object/add_object_type_classes> method inherited from L<Rose::HTML::Object>. It is an L<inherited hash|Rose::Class::MakeMethods::Generic/inherited_hash> representing the union of the hashes of all superclasses, minus any keys that are explicitly L<deleted|/delete_field_type_class> in the current class.
2485              
2486             =item B<add_form ARGS>
2487              
2488             This is an alias for the L<add_forms()|/add_forms> method.
2489              
2490             =item B<add_forms ARGS>
2491              
2492             Add the forms specified by ARGS to the list of sub-forms contained in this form. See the L<nested forms|/"NESTED FORMS"> section for more information.
2493              
2494             Valid formats for elements of ARGS are:
2495              
2496             =over 4
2497              
2498             =item B<Form objects>
2499              
2500             If an argument is "isa" L<Rose::HTML::Form>, then it is added to the list of forms, stored under the name returned by the form's L<form_name|/form_name> method. Example:
2501              
2502             $a_form = Rose::HTML::Form->new(...);
2503             $b_form = Rose::HTML::Form->new(...);
2504              
2505             # Object arguments
2506             $form->add_forms($a_form, $b_form);
2507              
2508             =item B<Form name/object pairs>
2509              
2510             A simple scalar followed by an object that "isa" L<Rose::HTML::Form> has its L<form_name|/form_name> set to the specified name and then is stored under that name.
2511              
2512             If the name contains any dots (".") it will be taken as a hierarchical name and the form will be added to the specified sub-form under an unqualified name consisting of the final part of the name.
2513              
2514             Examples:
2515              
2516             $a_form = Rose::HTML::Form->new(...);
2517             $b_form = Rose::HTML::Form->new(...);
2518              
2519             # Name/object pairs
2520             $form->add_forms(a => $a_form, b => $b_form);
2521              
2522             # Mixed
2523             $form->add_forms($a_form, b => $b_form);
2524              
2525             # Set nested form from the top-level
2526             $w_form = Rose::HTML::Form->new(...);
2527             $x_form = Rose::HTML::Form->new(...);
2528             $y_form = Rose::HTML::Form->new(...);
2529             $z_form = Rose::HTML::Form->new(...);
2530              
2531             $w_form->add_form('x' => $x_form);
2532             $x_form->add_form('y' => $y_form);
2533              
2534             # Add $z_form to $w_form->form('x')->form('y') under the name 'z'
2535             $w_form->add_form('x.y.z' => $z_form);
2536              
2537             =item B<Form name/hashref pairs>
2538              
2539             A simple scalar followed by a reference to a hash containing a specification for a form. Currently, the only kind of form that can be specified this way is a L<repeatable form|Rose::HTML::Form::Repeatable>, in which case the hash reference is known as a "repeat spec". In order to be correctly detected as a repeat spec, the hash I<must> contain a key named C<repeatable>.
2540              
2541             The repeat spec is coerced into a set of name/value pairs that are passed to the L<Rose::HTML::Form::Repeatable> constructor call. The coercion exists to allow shorter, more friendly names to be used in the context of a repeat spec. These names are converted into the names of valid L<Rose::HTML::Form::Repeatable> object methods. The following coercion rules are applied to the repeat spec hash reference:
2542              
2543             =over 4
2544              
2545             =item * If the value of the C<repeatable> key is reference to a hash, the keys and values of that hash are folded into the repeat spec. Otherwise, if a key named C<default_count> does not exist in the repeat spec, then the value of the C<repeatable> key is used as the value of the L<default_count|Rose::HTML::Form::Repeatable/default_count> parameter.
2546              
2547             =item * The C<spec> and C<form_spec> parameters are aliases for the L<prototype_form_spec|Rose::HTML::Form::Repeatable/prototype_form_spec> parameter.
2548              
2549             =item * The C<class> and C<form_class> parameters are aliases for the L<prototype_form_class|Rose::HTML::Form::Repeatable/prototype_form_class> parameter.
2550              
2551             =item * The C<form> parameter is an alias for the L<prototype_form|Rose::HTML::Form::Repeatable/prototype_form> parameter.
2552              
2553             =back
2554              
2555             Here are some example name/hashref pairs suitable for passing as arguments to the L<add_forms|/add_forms> method:
2556              
2557             # Using a form class name
2558             emails =>
2559             {
2560             form_class => 'EmailForm',
2561             repeatable => 3, # Default count is 3.
2562             }
2563              
2564             # Using a form class name and form spec
2565             emails =>
2566             {
2567             form_class => 'EmailForm',
2568             form_spec => { empty_is_ok => 1 },
2569             repeatable => 3, # Default count is 3.
2570             }
2571              
2572             # Using a generic form class and form spec to specify the
2573             # contents of a repeated form "inline" in the repeat spec
2574             nicknames =>
2575             {
2576             form_class => 'My::HTML::Form',
2577             form_spec => { fields => [ nick => { type => 'text' } ] },
2578             repeatable => 3, # Default count is 3.
2579             }
2580              
2581             # Using a prototype object
2582             nicknames =>
2583             {
2584             form => NickNameForm->new,
2585             default_count => 0, # Explicitly set default count to 0.
2586             repeatable => 1, # This key must be present even though
2587             # the default count is set above.
2588             }
2589              
2590             =back
2591              
2592             Each form's L<parent_form|/parent_form> is set to the form object it was added to.
2593              
2594             Adding a form with the same name as an existing field will cause a fatal error.
2595              
2596             =item B<add_param_value NAME, VALUE>
2597              
2598             Add VALUE to the parameter named NAME. Example:
2599              
2600             $form->param(a => 1);
2601             print $form->param('a'); # 1
2602              
2603             $form->add_param_value(a => 2);
2604              
2605             print join(',', $form->param('a')); # 1,2
2606              
2607             =item B<app [OBJECT]>
2608              
2609             Get or set a L<weakened|Scalar::Util/weaken> reference to the application object that "owns" this form.
2610              
2611             =item B<add_repeatable_form ARGS>
2612              
2613             This method is an alias for the L<add_repeatable_forms()|/add_repeatable_forms> method.
2614              
2615             =item B<add_repeatable_forms ARGS>
2616              
2617             Add the repeatable forms specified by ARGS to the list of sub-forms contained in this form. This method takes arguments in the same format as the L<add_forms|/add_forms> method, except that all argument types are coerced into a form that will cause L<add_forms|/add_forms> to recognize it as a L<repeatable form|Rose::HTML::Form::Repeatable>. This is a convenient way to add repeatable forms without having to include the C<repeatable> key in your repeat spec. (See the documentation for the L<add_forms|/add_forms> method for more information.)
2618              
2619             Examples
2620              
2621             $form->add_repeatable_forms
2622             (
2623             # Object argument
2624             EmailForm->new(...),
2625              
2626             # Name/object pair
2627             colors => ColorForm->new(...),
2628              
2629             # Name/hashref pair. (Note: no "repeatable" key needed)
2630             nicknames =>
2631             {
2632             form => NickNameForm->new,
2633             default_count => 2,
2634             },
2635             );
2636              
2637             =item B<build_on_init [BOOL]>
2638              
2639             Get or set a boolean flag that indicates whether or not L<build_form()|/build_form> should be called from within the L<init()|Rose::Object/init> method. See L<build_form()|/build_form> for more information.
2640              
2641             =item B<build_form>
2642              
2643             This default implementation of this method is a no-op. It is meant to be overridden by subclasses. It is called at the end of the L<init()|Rose::Object/init> method if L<build_on_init()|/build_on_init> is true. (Remember that this class inherits from L<Rose::HTML::Object>, which inherits from L<Rose::Object>, which defines the L<init()|Rose::Object/init> method, which is called from the constructor. See the L<Rose::Object> documentation for more information.)
2644              
2645             If L<build_on_init()|/build_on_init> is false, then you must remember to call L<build_form()|/build_form> manually.
2646              
2647             Subclasses should populate the field list in their overridden versions of L<build_form()|/build_form>. Example:
2648              
2649             sub build_form
2650             {
2651             my($self) = shift;
2652              
2653             $self->add_fields
2654             (
2655             name => { type => 'text', size => 25, required => 1 },
2656             email => { type => 'email', size => 50, required => 1 },
2657             phone => { type => 'phone' },
2658             );
2659             }
2660              
2661             =item B<clear>
2662              
2663             Call L<clear()|Rose::HTML::Form::Field/clear> on each field object and set L<error()|Rose::HTML::Object/error> to undef.
2664              
2665             =item B<clear_fields>
2666              
2667             Call L<clear()|Rose::HTML::Form::Field/clear> on each field object.
2668              
2669             =item B<coalesce_hidden_fields [BOOL]>
2670              
2671             Get or set the boolean flag that controls how compound field values are encoded in hidden fields. If this flag is true, then each compound field is encoded as a single hidden field. If the flag is false (the default), then each subfield of a compound field will have its own hidden field.
2672              
2673             =item B<coalesce_query_string_params [BOOL]>
2674              
2675             Get or set the boolean flag that controls how compound field values are encoded in the query string. If this flag is true (the default), then compound fields are represented by a single query parameter. Otherwise, the subfields of each compound field appear as separate query parameters.
2676              
2677             =item B<compare_fields [FIELD1, FIELD2]>
2678              
2679             Compare two fields, returning 1 if FIELD1 should come before FIELD2, -1 if FIELD2 should come before FIELD1, or 0 if neither field should come before the other. This method is called from within the L<field_names|/field_names> method to determine the order of the fields in this form.
2680              
2681             The default implementation performs a string comparison on the L<name|Rose::HTML::Form::Field/name>s of the fields.
2682              
2683             =item B<compare_forms [FORM1, FORM2]>
2684              
2685             Compare two forms, returning 1 if FORM1 should come before FORM2, -1 if FORM2 should come before FORM1, or 0 if neither form should come before the other. This method is called from within the L<form_names|/form_names> and L<field_monikers|/field_monikers> methods to determine the order of the sub-forms nested within this form.
2686              
2687             The default implementation compares the L<rank|/rank> of the forms in numeric context.
2688              
2689             =item B<delete_field NAME>
2690              
2691             Delete the form stored under the name NAME. If NAME "isa" L<Rose::HTML::Form::Field>, then the L<name|Rose::HTML::Form::Field/name> method is called on it and the return value is used as NAME.
2692              
2693             =item B<delete_fields>
2694              
2695             Delete all fields, leaving the list of fields empty. The L<field_rank_counter|/field_rank_counter> is also reset to 1.
2696              
2697             =item B<delete_field_type_class TYPE>
2698              
2699             Delete the type/class L<mapping|/field_type_classes> entry for the field type TYPE.
2700              
2701             =item B<delete_form NAME>
2702              
2703             Delete the form stored under the name NAME. If NAME "isa" L<Rose::HTML::Form>, then the L<form_name|/form_name> method is called on it and the return value is used as NAME.
2704              
2705             =item B<delete_forms>
2706              
2707             Delete all sub-forms, leaving the list of sub-forms empty.
2708              
2709             =item B<delete_param NAME [, VALUES]>
2710              
2711             If just the NAME argument is passed, the parameter named NAME is deleted.
2712              
2713             If VALUES are also passed, then VALUES are deleted from the set of values held by the parameter name NAME. If only one value remains, then it is the new value for the NAME parameter (i.e., the value is no longer an array reference, but a scalar instead). If every value is deleted, then the NAME parameter is deleted as well. Example:
2714              
2715             $form->param(a => [ 1, 2, 3, 4 ]);
2716              
2717             $form->delete_param(a => 1);
2718             $vals = $form->param('a'); # [ 2, 3, 4 ]
2719              
2720             $form->delete_param(a => [ 2, 3 ]);
2721             $vals = $form->param('a'); # 4
2722              
2723             $form->delete_param(a => 4);
2724             $vals = $form->param('a'); # undef
2725             $form->param_exists('a'); # false
2726              
2727             =item B<delete_params>
2728              
2729             Delete all parameters.
2730              
2731             =item B<delete_repeatable_form NAME>
2732              
2733             Delete the repeatable form stored under the name NAME. If NAME "isa" L<Rose::HTML::Form>, then the L<form_name|/form_name> method is called on it and the return value is used as NAME.
2734              
2735             =item B<delete_repeatable_forms>
2736              
2737             Delete all repeatable sub-forms.
2738              
2739             =item B<empty_is_ok [BOOL]>
2740              
2741             Get or set a boolean value that indicates whether or not L<validate|/validate> will be allowed to return true if every L<field|/fields> in the form is empty, even if some of them are L<required|Rose::HTML::Form::Field/required>. The default value is false.
2742              
2743             =item B<end_html>
2744              
2745             Returns the HTML required to end the form.
2746              
2747             =item B<end_xhtml>
2748              
2749             Returns the XHTML required to end the form.
2750              
2751             =item B<end_multipart_html>
2752              
2753             Returns the HTML required to end a multipart form.
2754              
2755             =item B<end_multipart_xhtml>
2756              
2757             Returns the XHTML required to end a multipart form.
2758              
2759             =item B<field NAME [, VALUE]>
2760              
2761             Get or set the field specified by NAME. If only a NAME argument is passed, then the field stored under the name NAME is returned. If no field exists under that name exists, then undef is returned.
2762              
2763             If both NAME and VALUE arguments are passed, then the VALUE must be a L<Rose::HTML::Form::Field> or a reference to a hash whose contents are as described in the documentation for the L<add_fields|/add_fields> method.
2764              
2765             =item B<fields [FIELDS]>
2766              
2767             If FIELDS are passed, this method L<deletes all existing fields|/delete_fields> and then calls L<add_fields|/add_fields>, passing all arguments.
2768              
2769             The return value is an ordered list of this form's field objects in list context, or a reference to this list in scalar context. The order of the fields matches the order of the field names returned by the L<field_monikers|/field_monikers> method.
2770              
2771             =item B<fields_depth_first>
2772              
2773             Returns a list (in list context) or reference to an array (in scalar context) of this form's field objects ordered according to a depth-first traversal of all L<sub-forms|/"NESTED FORMS">. Fields within a given form are ordered by L<rank|Rose::HTML::Form::Field/rank>, and all fields at a given level precede any sub-forms nested under that level.
2774              
2775             =item B<field_monikers>
2776              
2777             Returns an ordered list of field monikers in list context, or a reference to this list in scalar context. A "moniker" is a fully qualified name, including any sub-form or sub-field prefixes (e.g., "pa.person.email" as seen in the L<nested forms|/"NESTED FORMS"> section above).
2778              
2779             The order is determined by the L<compare_forms|/compare_forms> and L<compare_fields|/compare_fields> methods. The L<compare_forms|/compare_forms> method is passed the parent form of each field. If it returns a true value, then that value is used to sort the two fields being compared. If it returns false, then the L<compare_fields|/compare_fields> method is called with the two field objects as arguments and its return value is used to determine the order. See the documentation for the L<compare_forms|/compare_forms> and L<compare_fields|/compare_fields> methods for more information.
2780              
2781             =item B<field_names>
2782              
2783             This method simply calls L<field_monikers|/field_monikers>.
2784              
2785             =item B<field_rank_counter [INT]>
2786              
2787             Get or set the value of the counter used to set the L<rank|Rose::HTML::Form::Field/rank> of fields as they're L<added|/add_fields> to the form. The counter starts at 1 by default.
2788              
2789             =item B<field_type_class TYPE [, CLASS]>
2790              
2791             Given the field type string TYPE, return the name of the L<Rose::HTML::Object>-derived class mapped to that name. If a CLASS is passed, the field type TYPE is mapped to CLASS.
2792              
2793             This method is an alias for the L<object_type_class|Rose::HTML::Object/object_type_class> method inherited from L<Rose::HTML::Object>. It is an L<inherited hash|Rose::Class::MakeMethods::Generic/inherited_hash> representing the union of the hashes of all superclasses, minus any keys that are explicitly L<deleted|/delete_field_type_class> in the current class.
2794              
2795             =item B<field_type_classes [MAP]>
2796              
2797             Get or set the hash that maps object type strings to the names of the L<Rose::HTML::Object>-derived classes. This map
2798              
2799             If passed MAP (a list of type/class pairs or a reference to a hash of the same) then MAP replaces the current field type mapping. Returns a list of type/class pairs (in list context) or a reference to a hash of type/class mappings (in scalar context).
2800              
2801             This method is an alias for the L<object_type_classes|Rose::HTML::Object/object_type_classes> method inherited from L<Rose::HTML::Object>. It is an L<inherited hash|Rose::Class::MakeMethods::Generic/inherited_hash> representing the union of the hashes of all superclasses, minus any keys that are explicitly L<deleted|/delete_field_type_class> in the current class.
2802              
2803             The default mapping of type names to classes is shown in the L<Rose::HTML::Object|Rose::HTML::Object/object_type_classes> documentation.
2804              
2805             =item B<field_value NAME [, VALUE]>
2806              
2807             If passed NAME and VALUE arguments, then the L<input_value|Rose::HTML::Form::Field/input_value> of the field named NAME is set to VALUE. If passed only a NAME, then the L<internal_value|Rose::HTML::Form::Field/internal_value> of the field named NAME is returned. In other words, this:
2808              
2809             $form->field_value(zip_code => '11787');
2810              
2811             is equivalent to this:
2812              
2813             $form->field('zip_code')->input_value('11787');
2814              
2815             and this:
2816              
2817             $val = $form->field_value('zip_code');
2818              
2819             is equivalent to this:
2820              
2821             $val = $form->field('zip_code')->internal_value;
2822              
2823             If no field named NAME exists, a fatal error will occur.
2824              
2825             =item B<form NAME [, OBJECT]>
2826              
2827             Get or set the sub-form named NAME. If just NAME is passed, the specified sub-form object is returned. If no such sub-form exists, undef is returnend.
2828              
2829             If both NAME and OBJECT are passed, a new sub-form is added under NAME.
2830              
2831             NAME is a fully-qualified sub-form name. Components of the hierarchy are separated by dots ("."). OBJECT must be an object that inherits from L<Rose::HTML::Form>.
2832              
2833             =item B<forms [FORMS]>
2834              
2835             If FORMS are passed, this method L<deletes all existing forms|/delete_forms> and then calls L<add_forms|/add_forms>, passing all arguments.
2836              
2837             The return value is an ordered list of this form's sub-form objects (if any) in list context, or a reference to this list in scalar context. The order of the forms matches the order of the form names returned by the L<form_names|/form_names> method.
2838              
2839             See the L<nested forms|/"NESTED FORMS"> section to learn more about nested forms.
2840              
2841             =item B<form_name [NAME]>
2842              
2843             Get or set the name of this form. This name may or may not have any connection with the value of the "name" HTML attribute on the E<lt>formE<gt> tag. See the documentation for the L<name|/name> method for details.
2844              
2845             =item B<form_names>
2846              
2847             Returns an ordered list of form names in list context, or a reference to this list in scalar context. The order is determined by the L<compare_forms|/compare_forms> method. Note that this only lists the forms that are direct children of the current form. Forms that are nested more than one level deep are not listed.
2848              
2849             =item B<form_rank_counter [INT]>
2850              
2851             This method is deprecated and will be removed in a future release.
2852              
2853             =item B<hidden_fields>
2854              
2855             Returns one or more L<Rose::HTML::Form::Field::Hidden> objects that represent the hidden fields needed to encode all of the field values in this form.
2856              
2857             If L<coalesce_hidden_fields()|/coalesce_hidden_fields> is true, then each compound field is encoded as a single hidden field. Otherwise, each subfield of a compound field will be have its own hidden field.
2858              
2859             =item B<html_hidden_fields>
2860              
2861             Returns the HTML serialization of the fields returned by L<hidden_fields()|/hidden_fields>, joined by newlines.
2862              
2863             =item B<init_fields [PARAMS]>
2864              
2865             Initialize the fields based on L<params()|/params>. In general, this works as you'd expect, but the details are a bit complicated.
2866              
2867             The intention of L<init_fields()|/init_fields> is to set field values based solely and entirely on L<params()|/params>. That means that default values for fields should not be considered unless they are explicitly part of L<params()|/params>.
2868              
2869             In general, default values for fields exist for the purpose of displaying the HTML form with certain items pre-selected or filled in. In a typical usage scenario, those default values will end up in the web browser form submission and, eventually, as as an explicit part of part L<params()|/params>, so they are not really ignored.
2870              
2871             But to preserve the intended functionality of L<init_fields()|/init_fields>, the first thing this method does is L<clear()|/clear> the form. (This is the default. See the C<no_clear> parameter below.)
2872              
2873             If a parameter name exactly matches a field's name (note: the field's L<name|Rose::HTML::Form::Field/name>, which is not necessarily the the same as the name that the field is stored under in the form), then the (list context) value of that parameter is passed as the L<input_value()|Rose::HTML::Form::Field/input_value> for that field.
2874              
2875             If a field "isa" L<Rose::HTML::Form::Field::Compound>, and if no parameter exactly matches the L<name|Rose::HTML::Form::Field/name> of the compound field, then each subfield may be initialized by a parameter name that matches the subfield's L<name|Rose::HTML::Form::Field/name>.
2876              
2877             If a field is an "on/off" type of field (e.g., a radio button or checkbox), then the field is turned "on" only if the value of the parameter that matches the field's L<name|Rose::HTML::Form::Field/name> exactly matches (string comparison) the "value" HTML attribute of the field. If not, and if L<params_exist()|/params_exist>, then the field is set to "off". Otherwise, the field is not modified at all.
2878              
2879             PARAMS are name/value pairs. Valid parameters are:
2880              
2881             =over 4
2882              
2883             =item B<no_clear BOOL>
2884              
2885             If true, the form is not L<clear()ed|/clear> before it is initialized.
2886              
2887             =item B<recursive BOOL>
2888              
2889             If true, this method is called recursively on any L<nested sub-forms|/"NESTED FORMS">. If false, the fields in all nested sub-forms are still initialized as expected, but this is done by iterating over the "flattened" L<fields|/fields> list rather than through recursion.
2890              
2891             If this parameter is not passed, its value defaults to the value of the L<recursive_init_fields|/recursive_init_fields> object attribute.
2892              
2893             =back
2894              
2895             Examples:
2896              
2897             package RegistrationForm;
2898             ...
2899             sub build_form
2900             {
2901             my($self) = shift;
2902              
2903             $self->add_fields
2904             (
2905             name => { type => 'text', size => 25 },
2906              
2907             gender =>
2908             {
2909             type => 'radio group',
2910             choices => { 'm' => 'Male', 'f' => 'Female' },
2911             default => 'm'
2912             },
2913              
2914             hobbies =>
2915             {
2916             type => 'checkbox group',
2917             name => 'hobbies',
2918             choices => [ 'Chess', 'Checkers', 'Knitting' ],
2919             default => 'Chess'
2920             },
2921              
2922             bday = => { type => 'date split mdy' }
2923             );
2924             }
2925              
2926             ...
2927              
2928             $form = RegistrationForm->new();
2929              
2930             $form->params(name => 'John',
2931             gender => 'm',
2932             hobbies => undef,
2933             bday => '1/24/1984');
2934              
2935             # John, Male, no hobbies, 1/24/1984
2936             $form->init_fields;
2937              
2938             $form->reset;
2939             $form->params(name => 'John',
2940             bday => '1/24/1984');
2941              
2942             # No name, Male, Chess, 1/24/1984
2943             $form->init_fields(no_clear => 1);
2944              
2945             $form->reset;
2946             # Set using subfield names for "bday" compound field
2947             $form->params('name' => 'John',
2948             'bday.month' => 1,
2949             'bday.day' => 24,
2950             'bday.year' => 1984);
2951              
2952             # John, Male, no hobbies, 1/24/1984
2953             $form->init_fields();
2954              
2955             $form->reset;
2956             $form->params('bday' => '1/24/1984',
2957             'bday.month' => 12,
2958             'bday.day' => 25,
2959             'bday.year' => 1975);
2960              
2961             # No name, no gender, no hobbies, but 1/24/1984 because
2962             # the "bday" param trumps any and all subfield params.
2963             $form->init_fields();
2964              
2965             $form->reset;
2966              
2967             # Explicitly set hobbies field to Knitting...
2968             $form->field('hobbies')->input_value('Knitting');
2969              
2970             # ...but then provide a hobbies param with no value
2971             $form->params('hobbies' => undef);
2972              
2973             # Fields are not cleared, but the existence of the hobbies
2974             # param with an empty value causes the hobbies list to be
2975             # empty, instead of the default Chess. Thus:
2976             #
2977             # No name, Male, no hobbies, no birthday
2978             $form->init_fields(no_clear => 1);
2979              
2980             =item B<init_fields_with_cgi CGI [, ARGS]>
2981              
2982             This method is a shortcut for initializing the form's L<params|/params> with a CGI object and then calling L<init_fields|/init_fields>. The CGI argument is passed to the L<params_from_cgi|/params_from_cgi> method and ARGS are passed to the L<init_fields|/init_fields> method.
2983              
2984             For example, this:
2985              
2986             $form->init_fields_with_cgi($cgi, no_clear => 1);
2987              
2988             Is equivalent to this:
2989              
2990             $form->params_from_cgi($cgi);
2991             $form->init_fields(no_clear => 1);
2992              
2993             See the documentation for the L<params_from_cgi|/params_from_cgi> and L<init_fields|/init_fields> methods for more information.
2994              
2995             =item B<init_fields_with_apache APR [, ARGS]>
2996              
2997             This method is a shortcut for initializing the form's L<params|/params> with an apache request object and then calling L<init_fields|/init_fields>. The APR argument is passed to the L<params_from_apache|/params_from_apache> method and ARGS are passed to the L<init_fields|/init_fields> method.
2998              
2999             For example, this:
3000              
3001             $form->init_fields_with_apache($r, no_clear => 1);
3002              
3003             Is equivalent to this:
3004              
3005             $form->params_from_apache($r);
3006             $form->init_fields(no_clear => 1);
3007              
3008             See the documentation for the L<params_from_apache|/params_from_apache> and L<init_fields|/init_fields> methods for more information.
3009              
3010             =item B<init_with_object OBJECT>
3011              
3012             Initialize the form based on OBJECT. First, the form is L<clear()|/clear>ed. Next, for each field L<name()|Rose::HTML::Form::Field/name>, if the object has a method with the same name, then the return value of that method (called in scalar context) is passed as the L<input_value()|Rose::HTML::Form::Field/input_value> for the form field of the same name.
3013              
3014             The actual code for the L<init_with_object()|/init_with_object> method may be more clear than the description above. Essentially, it does this:
3015              
3016             sub init_with_object
3017             {
3018             my($self, $object) = @_;
3019              
3020             $self->clear();
3021              
3022             foreach my $field ($self->fields)
3023             {
3024             my $name = $field->local_name;
3025              
3026             if($object->can($name))
3027             {
3028             $field->input_value(scalar $object->$name());
3029             }
3030             }
3031             }
3032              
3033             Use this method as a "helper" when writing your own methods such as C<init_with_person()>, as described in the example in the L<overview|/OVERVIEW>. L<init_with_object()|/init_with_object> should be called in the code for subclasses of L<Rose::HTML::Form>, but never by an end-user of such classes.
3034              
3035             The convention for naming such methods is "init_with_foo", where "foo" is a (lowercase, underscore-separated, please) description of the object (or objects) used to initialize the form. You are free to accept and handle any kind or number of arguments in your "init_with_foo()"-style methods (all which you'll carefully document, of course).
3036              
3037             The field names may not match up exactly with the object method names. In such cases, you can use L<init_with_object()|/init_with_object> to handle all the fields that do match up with method names, and then handle the others manually. Example:
3038              
3039             sub init_with_person
3040             {
3041             my($self, $person) = @_;
3042              
3043             # Handle field names that match method names
3044             $self->init_with_object($person);
3045              
3046             # Manually set the non-matching or other fields
3047             $self->field('phone2')->input_value($person->alt_phone);
3048             $self->field('is_new')->input_value(1);
3049             ...
3050             }
3051              
3052             =item B<is_empty>
3053              
3054             Returns true if each L<field|/fields> and L<nested form|/forms> in this form L<is_empty()|/is_empty>, false otherwise.
3055              
3056             =item B<is_repeatable>
3057              
3058             Returns true if this form is a L<repeatable form|Rose::HTML::Form::Repeatable>, false otherwise.
3059              
3060             =item B<local_field NAME [, VALUE]>
3061              
3062             Get or set a field that is an immediate child of the current form. That is, it does not belong to a L<nested form|/"NESTED FORMS">. If the field specified by NAME does not meet these criteria, then undef is returned. In all other respects, this method behaves like the L<field|/field> method.
3063              
3064             Note that NAME should be the name as seen from the perspective of the form object upon which this method is called. So a nested form can always address its local fields using their "short" (unqualified) names even if the form is actually nested within another form.
3065              
3066             =item B<local_fields>
3067              
3068             Returns a list of fields that are immediate children of the current form (i.e., fields that do not belong to a L<nested form|/"NESTED FORMS">).
3069              
3070             =item B<local_form NAME [, OBJECT]>
3071              
3072             Get or set a form that is an immediate child of the current form. That is, it does not belong to a L<nested form|/"NESTED FORMS">. If the form specified by NAME does not meet these criteria, then undef is returned. In all other respects, this method behaves like the L<form|/form> method.
3073              
3074             Note that NAME should be the name as seen from the perspective of the form object upon which this method is called. So a nested form can always address its local sub-forms using their "short" (unqualified) names even if the parent form itself is actually nested within another form.
3075              
3076             =item B<name [NAME]>
3077              
3078             If passed a NAME argument, then the "name" HTML attribute is set to NAME.
3079              
3080             If called without any arguments, and if the "name" HTML attribute is empty, then the "name" HTML attribute is set to the L<form_name|/form_name>.
3081              
3082             Returns the value of the "name" HTML attribute.
3083              
3084             =item B<object_from_form OBJECT | CLASS | PARAMS>
3085              
3086             Returns an object built based on the contents of the form.
3087              
3088             For each field L<name()|Rose::HTML::Form::Field/name>, if the object has a method with the same name, then the L<internal_value()|Rose::HTML::Form::Field/internal_value> of the field is passed to the object method of that name. The actual code is almost as simple as this:
3089              
3090             foreach my $field ($self->fields)
3091             {
3092             my $name = $field->local_name;
3093              
3094             if($object->can($name))
3095             {
3096             $object->$name($field->internal_value);
3097             }
3098             }
3099              
3100             The only wrinkle is the case where a sub-form and a parent form have fields with the same L<local_name|Rose::HTML::Form::Field/local_name>. In that case, the field "closer" to the "root" form (in terms of the parent/child relationship tree) takes precedence. For example, consider the following fields:
3101              
3102             name
3103             vendor.name
3104             vendor.country.name
3105              
3106             The L<local_name|Rose::HTML::Form::Field/local_name> for all of these fields is C<name>, but L<object_from_form|/object_from_form> will pass the value of the C<name> field to the C<name()> method of the object. See the L<nested forms|/"NESTED FORMS"> section of the documentation for more information on nested forms.
3107              
3108             In order to return an object based on a form, L<object_from_form|/object_from_form> needs an object. If passed an OBJECT argument, then that's the object that's used. If passed a CLASS name, then a new object is constructed by calling L<new()|/new> on that class. OBJECT or CLASS may alternately be passed as a name/value pair in PARAMS.
3109              
3110             Use this method as a "helper" when writing your own methods such as C<person_from_form()>, as described in the example in the L<overview|/OVERVIEW>. L<object_from_form()|/object_from_form> should be called in the code for subclasses of L<Rose::HTML::Form>, but never by an end-user of such classes.
3111              
3112             The convention for naming such methods is "foo_from_form", where "foo" is a (lowercase, underscore-separated, please) description of the object constructed based on the values in the form's fields.
3113              
3114             The field names may not match up exactly with the object method names. In such cases, you can use L<object_from_form()|/object_from_form> to handle all the fields that do match up with method names, and then handle the others manually. Example:
3115              
3116             sub person_from_form
3117             {
3118             my($self) = shift;
3119              
3120             my $person = $self->object_from_form(class => 'Person');
3121              
3122             $person->alt_phone($self->field('phone2')->internal_value);
3123             ...
3124             return $person;
3125             }
3126              
3127             It is the caller's responsibility to ensure that the object class (C<Person> in the example above) is loaded prior to calling this method.
3128              
3129             =item B<param NAME [, VALUE]>
3130              
3131             Get or set the value of a named parameter. If just NAME is passed, then the value of the parameter of that name is returned. If VALUE is also passed, then the parameter value is set and then returned.
3132              
3133             If a parameter has multiple values, the values are returned as a reference to an array in scalar context, or as a list in list context. Multiple values are set by passing a VALUE that is a reference to an array of scalars.
3134              
3135             Failure to pass at least a NAME argument results in a fatal error.
3136              
3137             =item B<params [PARAMS]>
3138              
3139             Get or set all parameters at once.
3140              
3141             PARAMS can be a reference to a hash or a list of name/value pairs. If a parameter has multiple values, those values should be provided in the form of a reference to an array of scalar values. If the list of name/value pairs has an odd number of items, a fatal error occurs.
3142              
3143             If PARAMS is a reference to a hash, then it is accepted as-is. That is, no copying of values is done; the actual hash references is stored. If PARAMS is a list of name/value pairs, then a deep copy is made during assignment.
3144              
3145             Regardless of the arguments, this method returns the complete set of parameters in the form of a hash (in list context) or a reference to a hash (in scalar context).
3146              
3147             In scalar context, the hash reference returned is a reference to the actual hash used to store parameter names and values in the object. It should be treated as read-only.
3148              
3149             The hash returned in list context is a deep copy of the actual hash used to store parameter names and values in the object. It may be treated as read/write.
3150              
3151             =item B<params_exist>
3152              
3153             Returns true if any parameters exist, false otherwise.
3154              
3155             =item B<param_exists NAME>
3156              
3157             Returns true if a parameter named NAME exists, false otherwise.
3158              
3159             =item B<param_exists_for_field [ NAME | FIELD ]>
3160              
3161             Returns true if a L<param|/param> exists that addresses the field named NAME or the L<Rose::HTML::Form::Field>-derived object FIELD, false otherwise.
3162              
3163             This method is useful for determining if any query parameters exist that address a compound field. For example, a compound field named C<a.b.c.d> could be addressed by any one of the following query parameters: C<a>, C<a.b>, C<a.b.c>, or C<a.b.c.d>. This method also works with fields inside L<sub-form|/"NESTED FORMS">. Examples:
3164              
3165             $form = Rose::HTML::Form->new;
3166             $form->add_field(when => { type => 'datetime split mdyhms' });
3167              
3168             $form->params({ 'when.date' => '2004-01-02' });
3169              
3170             $form->param_exists_for_field('when'); # true
3171             $form->param_exists_for_field('when.date'); # true
3172             $form->param_exists_for_field('when.date.month'); # true
3173             $form->param_exists_for_field('when.time.hour'); # false
3174              
3175             $subform = Rose::HTML::Form->new;
3176             $subform->add_field(subwhen => { type => 'datetime split mdyhms' });
3177             $form->add_form(subform => $subform);
3178              
3179             $form->params({ 'subform.subwhen.date' => '2004-01-02' });
3180              
3181             $form->param_exists_for_field('subform.subwhen'); # true
3182             $form->param_exists_for_field('subform.subwhen.date'); # true
3183             $form->param_exists_for_field('subform.subwhen.date.month'); # true
3184             $form->param_exists_for_field('subform.subwhen.time.hour'); # false
3185              
3186             $form->param_exists_for_field('when'); # false
3187             $form->param_exists_for_field('when.date'); # false
3188             $form->param_exists_for_field('when.date.month'); # false
3189             $form->param_exists_for_field('when.time.hour'); # false
3190              
3191             =item B<params_from_apache APR>
3192              
3193             Set L<params|/params> by extracting parameter names and values from an apache request object. Calling this method entirely replaces the previous L<params|/params>.
3194              
3195             If running under L<mod_perl> 1.x, the APR argument may be:
3196              
3197             =over 4
3198              
3199             =item * An L<Apache> object. In this case, the L<Apache::Request> module must also be installed.
3200              
3201             =item * An L<Apache::Request> object.
3202              
3203             =back
3204              
3205             If running under L<mod_perl> 2.x, the APR may be:
3206              
3207             =over 4
3208              
3209             =item * An L<Apache2::RequestRec> object. In this case, the L<Apache2::Request> module must also be installed.
3210              
3211             =item * An L<Apache2::Request> object.
3212              
3213             =back
3214              
3215             In all cases, APR may be an object that has a C<param()> method that behaves in the following way:
3216              
3217             =over 4
3218              
3219             =item * When called in list context with no arguments, it returns a list of parameter names.
3220              
3221             =item * When called in list context with a single parameter name argument, it returns a list of values for that parameter.
3222              
3223             =back
3224              
3225             =item B<params_from_cgi CGI>
3226              
3227             Set L<params|/params> by extracting parameter names and values from a L<CGI> object. Calling this method entirely replaces the previous L<params|/params>. The CGI argument must be either a L<CGI> object or must have a C<param()> method that behaves in the following way:
3228              
3229             =over 4
3230              
3231             =item * When called in list context with no arguments, it returns a list of parameter names.
3232              
3233             =item * When called in list context with a single parameter name argument, it returns a list of values for that parameter.
3234              
3235             =back
3236              
3237             =item B<param_value_exists NAME, VALUE>
3238              
3239             Determines if a parameter of a particular name exists and has a particular value. This method returns true if the parameter named NAME exists and also has a value that is equal to (string comparison) VALUE. Otherwise, it returns false.
3240              
3241             A fatal error occurs unless both NAME and VALUE arguments are passed.
3242              
3243             =item B<parent_form [FORM]>
3244              
3245             Get or set the parent form, if any. The reference to the parent form is "weakened" using L<Scalar::Util::weaken()|Scalar::Util/weaken> in order to avoid memory leaks caused by circular references.
3246              
3247             =item B<prepare [PARAMS]>
3248              
3249             Prepare the form by calling the L<prepare|Rose::HTML::Form::Field/prepare> method on each L<field|/fields>, passing all arguments. This same method is also called for each L<sub-form|/forms>, passing all arguments plus the C<form_only> parameter with a true value.
3250              
3251             PARAMS are name/value pairs. Valid parameters are:
3252              
3253             =over 4
3254              
3255             =item B<form_only BOOL>
3256              
3257             If true, the L<prepare|Rose::HTML::Form::Field/prepare> method is not called for each L<field|/fields>.
3258              
3259             =back
3260              
3261             =item B<query_string>
3262              
3263             Returns a URI-escaped (but I<not> HTML-escaped) query string that corresponds to the current state of the form. If L<coalesce_query_string_params()|/coalesce_query_string_params> is true (which is the default), then compound fields are represented by a single query parameter. Otherwise, the subfields of each compound field appear as separate query parameters.
3264              
3265             =item B<rank [INT]>
3266              
3267             Get or set the form's rank. This value can be used for any purpose that suits you, but by default it's used by the L<compare_forms|/compare_forms> method to sort sub-forms.
3268              
3269             =item B<recursive_init_fields [BOOL]>
3270              
3271             Get or set a boolean value indicating the default value of the <recursive> parameter to the L<init_fields|/init_fields> method. This attribute, in turn, defaults to the value returned by the L<default_recursive_init_fields|/default_recursive_init_fields> class method.
3272              
3273             =item B<repeatable_form NAME [, OBJECT]>
3274              
3275             Get or set the repeatable sub-form named NAME. If just NAME is passed, the specified repeatable sub-form object is returned. If no such repeatable sub-form exists, undef is returnend.
3276              
3277             If both NAME and OBJECT are passed, a new repeatable sub-form is added under NAME.
3278              
3279             NAME is a fully-qualified sub-form name. Components of the hierarchy are separated by dots ("."). OBJECT must be an object that inherits from L<Rose::HTML::Form::Repeatable>.
3280              
3281             =item B<repeatable_forms [FORMS]>
3282              
3283             If FORMS are passed, this method L<deletes all existing repeatable forms|/delete_repeatable_forms> and then calls L<add_repeatable_forms|/add_repeatable_forms>, passing all arguments.
3284              
3285             The return value is an ordered list of this form's repeatable sub-form objects (if any) in list context, or a reference to this list in scalar context. The order of the forms matches the order of the form names returned by the L<form_names|/form_names> method.
3286              
3287             See the L<nested forms|/"NESTED FORMS"> section to learn more about nested forms, and the L<Rose::HTML::Form::Repeatable> documentation to learn more about repeatable forms.
3288              
3289             =item B<reset>
3290              
3291             Call L<reset()|Rose::HTML::Form::Field/reset> on each field object and set L<error()|Rose::HTML::Object/error> to undef.
3292              
3293             =item B<reset_fields>
3294              
3295             Call L<reset()|/reset> on each field object.
3296              
3297             =item B<self_uri>
3298              
3299             Returns a L<Rose::URI> object corresponding to the current state of the form. If L<uri_base()|/uri_base> is set, then it is included in front of what would otherwise be the start of the URI (i.e., the value of the form's "action" HTML attribute).
3300              
3301             =item B<start_html>
3302              
3303             Returns the HTML that will begin the form tag.
3304              
3305             =item B<start_xhtml>
3306              
3307             Returns the XHTML that will begin the form tag.
3308              
3309             =item B<start_multipart_html>
3310              
3311             Sets the "enctype" HTML attribute to "multipart/form-data", then returns the HTML that will begin the form tag.
3312              
3313             =item B<start_multipart_xhtml>
3314              
3315             Sets the "enctype" HTML attribute to "multipart/form-data", then returns the XHTML that will begin the form tag.
3316              
3317             =item B<trim_xy_params [BOOL]>
3318              
3319             Get or set a boolean value that determines whether or not L<params|/params> that end in ".x" or ".y" have that suffix trimmed off. This is useful for handling query parameters created by some web browsers in response to clicks on image buttons and other image-based elements. Setting this attribute will propagate the value down to all L<sub-forms|/"NESTED FORMS">.
3320              
3321             The default value is the value returned by the L<default_trim_xy_params|/default_trim_xy_params> class method.
3322              
3323             =item B<uri_base [STRING]>
3324              
3325             Get or set the URI of the form, minus the value of the "action" HTML attribute. Although the form action can be a relative URI, I suggest that it be an absolute path at the very least, leaving the L<uri_base()|/uri_base> to be the initial part of the full URI returned by L<self_uri()|/self_uri>. Example:
3326              
3327             $form->action('/foo/bar');
3328             $form->uri_base('http://www.foo.com');
3329              
3330             # http://www.foo.com/foo/bar
3331             $uri = $form->self_uri;
3332              
3333             =item B<uri_separator [CHAR]>
3334              
3335             Get or set the character used to separate parameter name/value pairs in the return value of L<query_string()|/query_string> (which is in turn used to construct the return value of L<self_uri()|/self_uri>). The default is "&".
3336              
3337             =item B<validate [PARAMS]>
3338              
3339             Validate the form by calling L<validate()|Rose::HTML::Form::Field/validate> on each field and L<validate()|/validate> on each each L<sub-form|/"NESTED FORMS">. If any field or form returns false from its C<validate()> method call, then this method returns false. Otherwise, it returns true.
3340              
3341             If this method is about to return false and the L<error|Rose::HTML::Object/error> attribute of this form is not set, then it is set to a generic error message.
3342              
3343             PARAMS are name/value pairs. Valid parameters are:
3344              
3345             =over 4
3346              
3347             =item C<cascade BOOL>
3348              
3349             If true, then the L<validate()|/validate> method of each sub-form is called, passing PARAMS, with a C<form_only> parameter set to true. The default value of the C<cascade> parameter is true. Note that all fields in all nested forms are validated regardless of the value of this parameter.
3350              
3351             =item C<form_only BOOL>
3352              
3353             If true, then the L<validate|Rose::HTML::Form::Field/validate> method is not called on the fields of this form and its sub-forms. Defaults to false, but is set to true when calling L<validate()|/validate> on sub-forms in response to the C<cascade> parameter.
3354              
3355             =back
3356              
3357             Examples:
3358              
3359             $form = Rose::HTML::Form->new;
3360             $form->add_field(foo => { type => 'text' });
3361              
3362             $subform = Rose::HTML::Form->new;
3363             $subform->add_field(bar => { type => 'text' });
3364              
3365             $form->add_form(sub => $subform);
3366              
3367             # Call validate() on fields "foo" and "sub.bar" and
3368             # call validate(form_only => 1) on the sub-form "sub"
3369             $form->validate;
3370              
3371             # Same as above
3372             $form->validate(cascade => 1);
3373              
3374             # Call validate() on fields "foo" and "sub.bar"
3375             $form->validate(cascade => 0);
3376              
3377             # Call validate(form_only => 1) on the sub-form "sub"
3378             $form->validate(form_only => 1);
3379              
3380             # Don't call validate() on any fields or sub-forms
3381             $form->validate(form_only => 1, cascade => 0);
3382              
3383             =item B<validate_field_html_attrs [BOOL]>
3384              
3385             Get or set a boolean flag that indicates whether or not the fields of this form will validate their HTML attributes. If a BOOL argument is passed, then it is passed as the argument to a call to L<validate_html_attrs()|Rose::HTML::Object/validate_html_attrs> on each field. In either case, the current value of this flag is returned.
3386              
3387             =item B<was_submitted>
3388              
3389             Returns true id L<params exist|/param_exists_for_field> for any L<field|/fields>, false otherwise.
3390              
3391             =item B<xhtml_hidden_fields>
3392              
3393             Returns the XHTML serialization of the fields returned by L<hidden_fields()|/hidden_fields>, joined by newlines.
3394              
3395             =back
3396              
3397             =head1 SUPPORT
3398              
3399             Any L<Rose::HTML::Objects> questions or problems can be posted to the L<Rose::HTML::Objects> mailing list. To subscribe to the list or search the archives, go here:
3400              
3401             L<http://groups.google.com/group/rose-html-objects>
3402              
3403             Although the mailing list is the preferred support mechanism, you can also email the author (see below) or file bugs using the CPAN bug tracking system:
3404              
3405             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Rose-HTML-Objects>
3406              
3407             There's also a wiki and other resources linked from the Rose project home page:
3408              
3409             L<http://rosecode.org>
3410              
3411             =head1 AUTHOR
3412              
3413             John C. Siracusa (siracusa@gmail.com)
3414              
3415             =head1 LICENSE
3416              
3417             Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.