File Coverage

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


line stmt bran cond sub pod time code
1             package Rose::HTML::Form;
2              
3 8     8   707987 use strict;
  8         21  
  8         363  
4              
5 8     8   67 use Carp;
  8         21  
  8         695  
6              
7 8     8   2454 use Clone::PP;
  8         5053  
  8         63  
8 8     8   5400 use Rose::URI;
  8         190651  
  8         373  
9 8     8   71 use Scalar::Util();
  8         19  
  8         255  
10 8     8   33 use URI::Escape qw(uri_escape);
  8         14  
  8         574  
11              
12 8     8   2382 use Rose::HTML::Util();
  8         27  
  8         250  
13 8     8   2743 use Rose::HTML::Object::Errors qw(:form);
  8         41  
  8         75  
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   56 use constant UNSAFE_URI_CHARS => '^\w\d?\057=.:-';
  8         20  
  8         618  
62              
63 8     8   3851 use Rose::HTML::Form::Constants qw(FF_SEPARATOR);
  8         21  
  8         967  
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         162 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   49 );
  8         12  
91              
92             #
93             # Class data
94             #
95              
96             use Rose::Class::MakeMethods::Generic
97             (
98 8         62 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   7842 );
  8         19  
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 91     91 1 1307594 my($class) = shift;
121              
122 91         590 my $self =
123             {
124             params => {},
125             fields => {},
126             validate_field_html_attrs => 1,
127             };
128              
129 91         248 bless $self, $class;
130              
131 91         499 $self->init(@_);
132              
133 91         10659 return $self;
134             }
135              
136 74     74 0 865 sub init_recursive_init_fields { shift->default_recursive_init_fields }
137              
138             sub trim_xy_params
139             {
140 160     160 1 359 my($self) = shift;
141              
142 160 100       416 if(@_)
143             {
144 4 50       17 my $val = $self->{'trim_xy_params'} = $_[0] ? 1 : 0;
145              
146 4         10 foreach my $form ($self->forms)
147             {
148 2         9 $form->trim_xy_params($val);
149             }
150              
151 4         10 return $val;
152             }
153              
154             return defined $self->{'trim_xy_params'} ?
155 156 100       1027 $self->{'trim_xy_params'} : ref($self)->default_trim_xy_params;
156             }
157              
158             sub delegate_to_subforms
159             {
160 11     11 1 30 my($class) = shift;
161              
162 11 50       62 $class = ref $class if(ref $class);
163              
164 11 100       92 if(@_)
165             {
166 8         26 my $value = shift;
167              
168             # Dumb regex to avoid non-numeric comparison warning
169 8 50 33     85 $value = 'runtime' if($value =~ /\d/ && $value == 1);
170              
171 8 50 33     172 unless(!$value || $value eq 'compile' || $value eq 'runtime')
      33        
172             {
173 0         0 croak "Invalid delegate_to_subforms() value: '$value'";
174             }
175              
176 8         63 return $class->_delegate_to_subforms($value);
177             }
178              
179 3         18 return $class->_delegate_to_subforms;
180             }
181              
182             #
183             # Object methods
184             #
185              
186 1     1 0 15 sub init_uri_separator { '&' }
187              
188             sub init
189             {
190 91     91 1 212 my($self) = shift;
191              
192 91         601 $self->SUPER::init(@_);
193              
194 91 100       910 $self->build_form() if($self->build_on_init);
195             }
196              
197 13     13 1 92 sub html_element { 'form' }
198 2     2 1 32 sub xhtml_element { 'form' }
199              
200 1     1 0 1809 sub action { shift->html_attr('action', @_) }
201 1     1 0 8 sub method { shift->html_attr('method', @_) }
202              
203       49 1   sub build_form { }
204              
205             sub name
206             {
207 120     120 1 257 my($self) = shift;
208              
209 120 100       325 if(@_)
210             {
211 2         7 return $self->html_attr('name', shift);
212             }
213             else
214             {
215 118 100       416 unless(defined $self->html_attr('name'))
216             {
217 101         324 return $self->form_name;
218             }
219              
220 17         57 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 10 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 197 my($self) = shift;
254              
255 98         304 foreach my $field ($self->fields)
256             {
257 172 100       832 return 0 unless($field->is_empty);
258             }
259              
260 33         295 foreach my $form ($self->forms)
261             {
262 11 50       51 return 0 unless($form->is_empty);
263             }
264              
265 33         492 return 1;
266             }
267              
268             sub empty_is_ok
269             {
270 95     95 1 207 my($self) = shift;
271              
272 95 100       247 if(@_)
273             {
274 8         41 foreach my $form ($self->forms)
275             {
276 2         10 $form->empty_is_ok(@_);
277             }
278              
279 8         33 return $self->SUPER::empty_is_ok(@_);
280             }
281              
282 87         689 my $ok = $self->SUPER::empty_is_ok(@_);
283 87 100       961 return $ok unless($ok);
284              
285 10         22 foreach my $form ($self->forms)
286             {
287 2 50       4 return 0 unless($form->empty_is_ok);
288             }
289              
290 10         46 return $ok;
291             }
292              
293             # Empty contents instead of replacing ref
294 2     2 1 26 sub delete_params { %{shift->{'params'}} = () }
  2         13  
295              
296             sub params_from_cgi
297             {
298 2     2 1 14 my($self, $cgi) = @_;
299              
300 2 50       10 croak "Missing CGI argument to params_from_cgi" unless(@_ > 1);
301              
302 2 50 33     36 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 2         5 my %params;
309              
310 2         4 local $CGI::LIST_CONTEXT_WARN = 0;
311              
312 2         12 foreach my $param ($cgi->param)
313             {
314 5         40 my @values = $cgi->param($param);
315 5 100       51 $params{$param} = @values > 1 ? \@values : $values[0];
316             }
317              
318 2         10 $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   11689 $ENV{'MOD_PERL_API_VERSION'} > 1 ? 1 : 0;
  8         14  
  8         918  
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     601 (!exists $ENV{'MOD_PERL_API_VERSION'} || $ENV{'MOD_PERL_API_VERSION'} == 1) ?
330 8     8   70 1 : 0;
  8         15  
331              
332 8 50   8   41 use constant MP0 => $ENV{'MOD_PERL'} ? 0 : 1;
  8         23  
  8         6416  
333              
334             my $Loaded_APR1 = 0;
335             my $Loaded_APR2 = 0;
336              
337             sub params_from_apache
338             {
339 2     2 1 2074 my($self, $apr) = @_;
340              
341 2 50       11 croak "Missing apache request argument to params_from_apache" unless(@_ > 1);
342              
343 2         16 if(MP0)
344             {
345 2 50       17 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         4 my %params;
390              
391 2         8 foreach my $param ($apr->param)
392             {
393 5         27 my @values = $apr->param($param);
394 5 100       42 $params{$param} = @values > 1 ? \@values : $values[0];
395             }
396              
397 2         7 $self->params(\%params);
398             }
399              
400             sub params
401             {
402 190     190 1 10996 my($self) = shift;
403              
404 190 100       583 if(@_)
405             {
406 156 100 66     902 if(@_ == 1 && ref $_[0] eq 'HASH')
    50          
407             {
408 139         445 $self->{'params'} = $_[0];
409             }
410             elsif(@_ % 2 == 0)
411             {
412 17         293 $self->{'params'} = Clone::PP::clone({ @_ });
413             }
414             else
415             {
416 0         0 croak(ref($self), '::params() - got odd number of arguments: ');
417             }
418              
419 156 100       3129 if($self->trim_xy_params)
420             {
421 152         3728 foreach my $param (keys %{$self->{'params'}})
  152         592  
422             {
423 702 100       2344 if($param =~ /^(.+)\.[xy]$/)
424             {
425 1         4 delete $self->{'params'}{$param};
426 1         6 $self->{'params'}{$1} = 1;
427             }
428             }
429             }
430              
431 156         591 foreach my $form ($self->forms)
432             {
433 87         348 $form->params($self->{'params'});
434             }
435             }
436              
437 190         410 my $want = wantarray;
438 190 100       562 return unless(defined $want);
439              
440 34 100       259 return ($want) ? %{ Clone::PP::clone($self->{'params'}) } : $self->{'params'};
  1         9  
441             }
442              
443             sub param_exists
444             {
445 1641     1641 1 3480 my($self, $param) = @_;
446              
447 8     8   77 no warnings;
  8         18  
  8         10874  
448              
449 1641         4674 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 151 my($self, $name) = @_;
457              
458 36 100       274 $name = $name->name if(UNIVERSAL::isa($name, 'Rose::HTML::Form::Field'));
459              
460 36 100       132 return 0 unless($self->field($name));
461              
462 34         72 my $nibble = $name;
463 34         62 my $found_form = 0;
464              
465 34         102 while(length $nibble)
466             {
467 62 100 66     178 if($self->form($nibble) && !$self->field($nibble))
468             {
469 11         22 $found_form = 1;
470 11         22 last;
471             }
472              
473 51 100       134 return 1 if($self->param_exists($nibble));
474 40 100       221 $nibble =~ s/\.[^.]+$// || last;
475             }
476              
477 23 100       88 foreach my $field ($found_form ? $self->form($nibble)->fields :
478             $self->field($name))
479             {
480 23 100       115 if($field->can('subfield_names'))
481             {
482 20         87 foreach my $subname ($field->subfield_names)
483             {
484             # Skip unrelated subfields
485 102 100 100     396 next unless(index($name, $subname) == 0 ||
486             index($subname, $name) == 0);
487              
488 83 100       172 return 1 if($self->param_exists($subname));
489             }
490             }
491             }
492              
493 13         151 return 0;
494             }
495              
496             sub param_value_exists
497             {
498 3     3 1 6 my($self, $param, $value) = @_;
499              
500 3 50       11 croak(ref($self), '::param_value_exists() requires a param name plus a value')
501             unless(@_ == 3);
502              
503 3         44 $param = $self->param($param);
504              
505 3 50       6 return 0 unless($param);
506              
507 3 50       8 foreach my $existing_value ((ref $param) ? @$param : $param)
508             {
509 9 100       22 return 1 if($existing_value eq $value);
510             }
511              
512 1         4 return 0;
513             }
514              
515             sub param
516             {
517 244     244 1 715 my($self, $param, $value) = @_;
518              
519 244 100       580 if(@_ == 2)
    50          
520             {
521 243 100       672 if(exists $self->{'params'}{$param})
522             {
523 240 100       491 if(wantarray)
524             {
525 214 100       575 if(ref $self->{'params'}{$param})
526             {
527 9         15 return @{$self->{'params'}{$param}};
  9         74  
528             }
529              
530 205         921 return ($self->{'params'}{$param});
531             }
532              
533 26         134 return $self->{'params'}{$param};
534             }
535              
536 3         15 return;
537             }
538             elsif(@_ == 3)
539             {
540 1         8 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 1305 my($self, $param, @values) = @_;
549              
550 4 50       18 croak(ref($self), '::delete_param() requires a param name')
551             unless(@_ >= 2);
552              
553 4 100 100     32 @values = @{$values[0]} if(@values == 1 && ref $values[0] eq 'ARRAY');
  1         4  
554              
555 4 100       14 if(@values)
556             {
557 3         10 my %values = map { $_ => 1 } @values;
  4         22  
558              
559 3         13 my $current = $self->{'params'}{$param};
560              
561 3 100       16 if(ref $current)
    50          
562             {
563 2         4 my @new;
564              
565 2         8 foreach my $val (@$current)
566             {
567 7 100       24 push(@new, $val) unless(exists $values{$val});
568             }
569              
570 2 50       6 if(@new)
571             {
572 2 100       16 $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         6 delete $self->{'params'}{$param};
582             }
583             }
584             else
585             {
586 1         5 delete $self->{'params'}{$param};
587             }
588             }
589              
590             sub add_param_value
591             {
592 1     1 1 3 my($self, $param, $value) = @_;
593              
594 1 50       4 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       3 if(ref $current)
    0          
600             {
601 1 50       4 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 12 my($self) = shift;
618              
619 1         8 my $uri_root = $self->uri_base . $self->html_attr('action');
620              
621 1         5 my $self_uri = $uri_root;
622              
623 1 50       2 if(keys %{$self->{'params'}})
  1         7  
624             {
625 0 0       0 $self_uri .= '?' unless($self_uri =~ /\?$/);
626 0         0 $self_uri .= $self->query_string;
627             }
628              
629 1         14 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 12 my($self) = shift;
638              
639 4         17 my $coalesce = $self->coalesce_query_string_params;
640              
641 4         28 my %params;
642              
643 4         18 my @fields = $self->fields;
644              
645 4         14 while(my $field = shift(@fields))
646             {
647 19 100       33 unless($coalesce)
648             {
649 9 100       45 if($field->isa('Rose::HTML::Form::Field::Compound'))
650             {
651 1         13 unshift(@fields, $field->fields);
652 1         5 next;
653             }
654             }
655              
656 18         75 my $value = $field->output_value;
657 18 100       41 next unless(defined $value);
658 16 100       20 push(@{$params{$field->name}}, ref $value ? @$value : $value);
  16         40  
659             }
660              
661 4         10 my $qs = '';
662 4         15 my $sep = $self->uri_separator;
663              
664 8     8   84 no warnings;
  8         17  
  8         7649  
665              
666 4         38 foreach my $param (sort keys(%params))
667             {
668 16         469 my $values = $params{$param};
669              
670 16 100       28 $qs .= $sep if($qs);
671 16         21 $qs .= join($sep, map { $param . '=' . uri_escape($_, UNSAFE_URI_CHARS) } @$values);
  20         78  
672             }
673              
674 4         79 return $qs;
675             }
676              
677             sub validate
678             {
679 55     55 1 262 my($self, %args) = @_;
680              
681 55 100       241 $args{'cascade'} = 1 unless(exists $args{'cascade'});
682              
683 55         95 my $fail = 0;
684              
685 55         98 my $cascade = $args{'cascade'};
686              
687 55 100       218 if($cascade)
688             {
689 51         163 foreach my $form ($self->forms)
690             {
691 32 100 100     175 next if($form->is_empty && $form->empty_is_ok);
692              
693 30 50       116 $Debug && warn "Validating sub-form ", $form->form_name, "\n";
694              
695 30 100       136 unless($form->validate(%args))
696             {
697 5 100       19 $self->add_error($form->error) if($form->error);
698 5         12 $fail++;
699             }
700             }
701             }
702              
703 55 100       163 unless($args{'form_only'})
704             {
705 52 100 100     220 return 1 if($self->is_empty && $self->empty_is_ok);
706              
707 50         185 foreach my $field ($self->fields)
708             {
709 254 100       826 if($field->parent_form ne $self)
710             {
711 136 50       308 $Debug && warn "Skipping validation of field ", $field->name, " in child form\n";
712             }
713             else
714             {
715 118 50       271 $Debug && warn "Validating ", $field->name, "\n";
716 118 100       462 $fail++ unless($field->validate);
717             }
718             }
719             }
720              
721 53 100       166 if($fail)
722             {
723 13 100       111 unless($self->has_errors)
724             {
725 9         65 $self->add_error_id(FORM_HAS_ERRORS);
726             }
727              
728 13         86 return 0;
729             }
730              
731 40         228 return 1;
732             }
733              
734             sub init_fields_with_cgi
735             {
736 1     1 1 2 my($self) = shift;
737              
738 1         3361 $self->params_from_cgi(shift);
739 1         5 $self->init_fields(@_);
740             }
741              
742             sub init_fields_with_apache
743             {
744 1     1 1 4 my($self) = shift;
745              
746 1         7 $self->params_from_apache(shift);
747 1         3 $self->init_fields(@_);
748             }
749              
750             sub init_fields
751             {
752 99     99 1 381 my($self, %args) = @_;
753              
754 99 100       690 $self->clear() unless($args{'no_clear'});
755              
756 99 50       586 if(exists $args{'recursive'} ? $args{'recursive'} : $self->recursive_init_fields)
    100          
757             {
758 53         632 foreach my $field ($self->local_fields)
759             {
760 114         405 $self->_init_field($field);
761             }
762              
763 53         208 foreach my $form ($self->forms)
764             {
765 43         269 $form->init_fields;
766             }
767             }
768             else
769             {
770 46         660 foreach my $field ($self->fields)
771             {
772 243         682 $self->_init_field($field);
773             }
774             }
775             }
776              
777             sub _init_field
778             {
779 501     501   1006 my($self, $field) = @_;
780              
781 501         2590 my $on_off = $field->isa('Rose::HTML::Form::Field::OnOff');
782              
783 501         1752 my $name = $field->name;
784 501         1723 my $moniker = $field->moniker;
785 501         1480 my $name_attr = $field->html_attr('name');
786              
787 501 50       1242 $Debug && warn "INIT FIELD $name ($name_attr)\n";
788              
789 501         1736 my $name_exists = $self->param_exists($name);
790 501         1005 my $moniker_exists = $self->param_exists($moniker);
791 501         968 my $name_attr_exists = $self->param_exists($name_attr);
792              
793 501 100 100     2851 if(!$name_exists && $field->isa('Rose::HTML::Form::Field::Compound'))
794             {
795 48         270 foreach my $moniker ($field->field_monikers)
796             {
797 144         2277 $self->_init_field($field->field($moniker));
798             }
799             }
800             else
801             {
802 453 100 66     2848 return unless($name_exists || $name_attr_exists || $moniker_exists || $on_off);
      100        
      66        
803              
804 214 100       1092 if($field->isa('Rose::HTML::Form::Field::Group'))
805             {
806 41 50       108 if($name_exists)
    0          
807             {
808 41 50       152 $Debug && warn "$field->input_value(", $self->param($name), ")\n";
809 41         160 $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       507 if($on_off)
826             {
827 8     8   56 no warnings 'uninitialized';
  8         39  
  8         21331  
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       385 if($name_exists)
    50          
849             {
850 172 50       414 $Debug && warn "$field->input_value(", $self->param($name), ")\n";
851 172         641 $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         5 $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         858 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         1155 while($parent)
872             {
873 54         227 $parent->is_cleared(0);
874 54         280 $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 33 my($self) = shift;
893 11         96 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 8 my($self) = shift;
901 2         11 $self->html_attr(enctype => 'multipart/form-data');
902 2         10 return $self->start_html;
903             }
904              
905             *start_multipart_xhtml = \&start_multipart_html;
906              
907 8     8 1 105 sub end_html { '</form>' }
908 2     2 1 10 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 12255 my($self) = shift;
916              
917 19         42 my($class, $object);
918              
919 19 100       68 if(@_ == 1)
    50          
920             {
921 16         39 $class = shift;
922              
923 16 100       59 if(ref $class)
924             {
925 2         7 $object = $class;
926 2         5 $class = ref $object;
927             }
928             }
929             elsif(@_)
930             {
931 3         14 my %args = @_;
932              
933 3         7 $class = $args{'class'};
934 3         10 $object = $args{'object'};
935             }
936             else
937             {
938 0         0 croak "Missing required object class argument";
939             }
940              
941 19   66     171 $object ||= $class->new();
942              
943             # Special handling of boolean columns for RDBO
944 19 50       366 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         88 FIELD: foreach my $field ($self->fields)
990             {
991 126         461 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         401 my $check_name = $field->name;
996              
997             # Remove the form name context, if any
998 126 100       382 if(defined(my $form_name_context = $self->form_name_context))
999             {
1000 18         145 $check_name =~ s/^$form_name_context//;
1001             }
1002              
1003 126 100       294 if($check_name ne $name)
1004             {
1005 63         1035 while($check_name =~ s/(^.+$FF_SEPARATOR_RE|^)[^$FF_SEPARATOR_RE]+$FF_SEPARATOR_RE([^$FF_SEPARATOR_RE]+)$/$1$2/)
1006             {
1007 126 100       347 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         238 $object->$name($field->internal_value);
1015             }
1016             }
1017             }
1018              
1019 19         142 return $object;
1020             }
1021              
1022             *init_object_with_form = \&object_from_form;
1023              
1024             sub init_with_object
1025             {
1026 4     4 1 1876 my($self, $object) = @_;
1027              
1028 4 50       15 croak "Missing required object argument" unless($object);
1029              
1030 4         18 $self->clear();
1031              
1032 4         13 foreach my $field ($self->fields)
1033             {
1034 15         34 my $name = $field->local_name;
1035              
1036 15 100       75 if($object->can($name))
1037             {
1038             #$Debug && warn "field($name) = $object->$name = ", $object->$name();
1039 5         23 $field->input_value(scalar $object->$name());
1040             }
1041             }
1042             }
1043              
1044             sub clear
1045             {
1046 280     280 1 514 my($self) = shift;
1047 280         1438 $self->clear_fields;
1048 280         2627 $self->clear_forms;
1049 280         965 $self->error(undef);
1050             }
1051              
1052             sub reset
1053             {
1054 4     4 1 4648 my($self) = shift;
1055 4         59 $self->reset_fields;
1056 4         40 $self->reset_forms;
1057 4         16 $self->error(undef);
1058             }
1059              
1060 34     34 0 512 sub init_form_rank_counter { 1 }
1061              
1062             sub next_form_rank
1063             {
1064 71     71 0 185 my($self) = shift;
1065              
1066 71         131 my $rank = 1;
1067              
1068 71         200 foreach my $form ($self->forms)
1069             {
1070 44 50       274 $rank = $form->rank + 1 if($form->rank >= $rank);
1071             }
1072              
1073 71         173 return $rank;
1074             }
1075              
1076             # XXX: Remove when form_rank_counter is removed
1077             sub increment_form_rank_counter
1078             {
1079 40     40 0 105 my($self) = shift;
1080 40         190 my $rank = $self->form_rank_counter;
1081 40         203 $self->form_rank_counter($rank + 1);
1082 40         153 return $rank;
1083             }
1084              
1085             sub repeatable_form
1086             {
1087 8     8 1 2796 my($self) = shift;
1088              
1089             # Set form
1090 8 100       27 if(@_ > 1)
1091             {
1092 1         2 my($name, $form) = (shift, shift);
1093 1         6 $self->delete_repeatable_form($name);
1094 1         6 return $self->add_repeatable_form($name => $form);
1095             }
1096              
1097 7 50       22 my $form = $self->form(@_) or return undef;
1098 7 50       35 return undef unless($form->is_repeatable);
1099 7         31 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 11 my($self) = shift;
1121              
1122 6         11 my @form_args;
1123              
1124 6         17 while(@_)
1125             {
1126 6         14 my $arg = shift;
1127              
1128 6 50       41 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       34 if(UNIVERSAL::isa($_[0], 'Rose::HTML::Form'))
    50          
1140             {
1141 4         12 my $form = shift;
1142              
1143 4         29 push(@form_args,
1144             $arg =>
1145             {
1146             form => $form,
1147             repeatable => undef,
1148             });
1149             }
1150             elsif(ref $_[0] eq 'HASH')
1151             {
1152 2         3 my $spec = shift;
1153 2 50       24 $spec->{'repeatable'} = undef unless(exists $spec->{'repeatable'});
1154 2         11 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         28 return $self->add_forms(@form_args);
1168             }
1169              
1170 6     6 1 52 sub add_repeatable_form { shift->add_repeatable_forms(@_) }
1171              
1172             sub form_depth
1173             {
1174 8096     8096 0 13431 my($self) = shift;
1175              
1176 8096 100       16756 if(@_)
1177             {
1178 72         232 return $self->{'form_depth'} = shift;
1179             }
1180              
1181 8024 100       53270 return $self->{'form_depth'} if(defined $self->{'form_depth'});
1182              
1183 111         252 my $depth = 0;
1184 111         181 my $form = $self;
1185 111         382 $depth++ while($form = $form->parent_form);
1186              
1187 111         395 return $self->{'form_depth'} = $depth;
1188             }
1189              
1190             sub add_forms
1191             {
1192 68     68 1 1103 my($self) = shift;
1193              
1194 68         141 my @added_forms;
1195              
1196 68         337 my $next_rank = $self->next_form_rank;
1197              
1198 68         187 while(@_)
1199             {
1200 74         152 my $arg = shift;
1201              
1202 74         158 my($name, $form);
1203              
1204 74 100       435 if(UNIVERSAL::isa($arg, 'Rose::HTML::Form'))
1205             {
1206 1         3 $form = $arg;
1207              
1208 1 50       7 if(Scalar::Util::refaddr($form) eq Scalar::Util::refaddr($self))
1209             {
1210 1         348 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         133 $name = $arg;
1228 73         120 $form = shift;
1229              
1230 73 50       258 croak "Cannot add form with the same name as an existing field: $name"
1231             if($self->field($name));
1232              
1233 73 100       355 if(UNIVERSAL::isa($form, 'Rose::HTML::Form'))
    50          
1234             {
1235 59 100       224 if(Scalar::Util::refaddr($form) eq Scalar::Util::refaddr($self))
1236             {
1237 1         225 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       250 $form->empty_is_ok(1) if($self->empty_is_ok);
1242             }
1243             elsif(ref $form eq 'HASH')
1244             {
1245 14 50       35 unless(exists $form->{'repeatable'})
1246             {
1247 0         0 croak "Missing key 'repeatable' in hash reference specification for form named '$name'";
1248             }
1249              
1250 14         22 my $repeat_spec = $form;
1251              
1252 14 100       31 if(ref $form->{'repeatable'})
1253             {
1254 1         2 @$repeat_spec{keys %{$form->{'repeatable'}}} = values %{$form->{'repeatable'}};
  1         17  
  1         3  
1255             }
1256             else
1257             {
1258             $repeat_spec->{'default_count'} = $form->{'repeatable'}
1259 13 100       43 unless(exists $repeat_spec->{'default_count'});
1260             }
1261              
1262 14         27 delete $form->{'repeatable'};
1263              
1264             $repeat_spec->{'prototype_form_spec'} = delete $repeat_spec->{'spec'}
1265 14 50       40 if($repeat_spec->{'spec'});
1266              
1267             $repeat_spec->{'prototype_form_spec'} = delete $repeat_spec->{'form_spec'}
1268 14 100       44 if($repeat_spec->{'form_spec'});
1269              
1270             $repeat_spec->{'prototype_form_class'} = delete $repeat_spec->{'class'}
1271 14 50       60 if($repeat_spec->{'class'});
1272              
1273             $repeat_spec->{'prototype_form_class'} = delete $repeat_spec->{'form_class'}
1274 14 100       64 if($repeat_spec->{'form_class'});
1275              
1276             $repeat_spec->{'prototype_form'} = delete $repeat_spec->{'form'}
1277 14 100       58 if($repeat_spec->{'form'});
1278              
1279 14         101 $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     98 if($repeat_spec->{'empty_is_ok'} || $self->empty_is_ok)
1283             {
1284 1         4 $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         288 $form->form_name($name);
1293              
1294 72 100       299 unless(defined $form->rank)
1295             {
1296 37         166 $self->increment_form_rank_counter; # XXX: Remove when form_rank_counter is removed
1297 37         141 $form->rank($next_rank++);
1298             }
1299             }
1300              
1301 72 100       303 if(index($name, FF_SEPARATOR) >= 0)
1302             {
1303 2         16 my($parent_form, $local_name) = $self->choose_parent_form($name);
1304 2         8 $form->form_name($local_name);
1305 2         5 $form->parent_form($parent_form);
1306 2         9 $parent_form->add_form($local_name => $form);
1307             }
1308             else
1309             {
1310 70         293 $form->parent_form($self);
1311 70         224 $self->{'forms'}{$name} = $form;
1312             }
1313              
1314 72         324 push(@added_forms, $form);
1315             }
1316              
1317 66         234 my $depth = $self->form_depth + 1;
1318              
1319 66         168 foreach my $form (@added_forms)
1320             {
1321 72 100 100     310 if($form->recursive_init_fields || $form->isa('Rose::HTML::Form::Repeatable'))
1322             {
1323 22         714 $self->recursive_init_fields(1);
1324             }
1325              
1326 72         2147 $form->form_depth($depth);
1327 72         200 $form->resync_field_names;
1328             }
1329              
1330 66         314 $self->_clear_form_generated_values;
1331 66         271 $self->resync_fields_by_name;
1332              
1333 66 50       439 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 225     225 0 506 my($self) = shift;
1342              
1343 225         846 foreach my $field ($self->fields)
1344             {
1345 1224         4896 $field->resync_name;
1346             }
1347              
1348 225         924 foreach my $form ($self->forms)
1349             {
1350 39         157 $form->resync_field_names;
1351             }
1352             }
1353              
1354             sub resync_fields_by_name
1355             {
1356 66     66 0 129 my($self) = shift;
1357              
1358 66         230 $self->{'fields_by_name'} = {};
1359              
1360 66         222 foreach my $field ($self->fields)
1361             {
1362 362         1120 $self->{'fields_by_name'}{$field->name} = $field;
1363             }
1364             }
1365              
1366             sub compare_forms
1367             {
1368 3979     3979 1 8690 my($self, $one, $two) = @_;
1369 8     8   71 no warnings 'uninitialized';
  8         30  
  8         11590  
1370 3979   100     9699 return $one->form_depth <=> $two->form_depth || $one->rank <=> $two->rank;
1371             }
1372              
1373             sub forms
1374             {
1375 1641     1641 1 2807 my($self) = shift;
1376              
1377 1641 50       3640 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 1641 100       4148 if(my $forms = $self->{'form_list'})
1385             {
1386 1460 100       5146 return wantarray ? @$forms : $forms;
1387             }
1388              
1389 181         405 my $forms = $self->{'forms'};
1390              
1391 181         644 $self->{'form_list'} = [ grep { defined } map { $forms->{$_} } $self->form_names ];
  119         287  
  119         285  
1392              
1393 181 50       485 return wantarray ? @{$self->{'form_list'}} : $self->{'form_list'};
  181         628  
1394             }
1395              
1396             sub form_names
1397             {
1398 183     183 1 380 my($self) = shift;
1399              
1400 183 100       493 if(my $names = $self->{'form_names'})
1401             {
1402 2 50       19 return wantarray ? @$names : $names;
1403             }
1404              
1405 181         316 my @info;
1406              
1407 181         336 while(my($name, $form) = each %{$self->{'forms'}})
  300         1121  
1408             {
1409 119         516 push(@info, [ $name, $form ]);
1410             }
1411              
1412             $self->{'form_names'} =
1413 181         703 [ map { $_->[0] } sort { $self->compare_forms($a->[1], $b->[1]) } @info ];
  119         413  
  50         181  
1414              
1415 181 50       461 return wantarray ? @{$self->{'form_names'}} : $self->{'form_names'};
  181         732  
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 1819 my($self, $name) = @_;
1435              
1436 4 50       23 $name = $name->form_name if(UNIVERSAL::isa($name, 'Rose::HTML::Form'));
1437              
1438 4 50 33     38 if(exists $self->{'forms'}{$name} && $self->{'forms'}{$name}->is_repeatable_form)
1439             {
1440 4         8 my $form = delete $self->{'forms'}{$name};
1441              
1442 4         14 $self->_clear_form_generated_values;
1443              
1444 4         96 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         34 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         42 $self->_clear_form_generated_values;
1460              
1461 8         15 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 11 my($self) = shift;
1482              
1483             # Leave the repeatable fields which are implemented as a special case of repeatable forms
1484 2         10 foreach my $form (grep { !$_->is_repeatable_field } $self->forms)
  3         16  
1485             {
1486 3         83 delete $self->{'forms'}{$form->form_name};
1487             }
1488              
1489 2         14 $self->form_rank_counter(undef); # XXX: Remove when form_rank_counter is removed
1490 2         23 $self->_clear_form_generated_values;
1491 2         11 return;
1492             }
1493              
1494             sub delete_form
1495             {
1496 15     15 1 629 my($self, $name) = @_;
1497              
1498 15 50       160 $name = $name->form_name if(UNIVERSAL::isa($name, 'Rose::HTML::Form'));
1499              
1500 15 100       62 if(exists $self->{'forms'}{$name})
1501             {
1502 14         38 my $form = delete $self->{'forms'}{$name};
1503              
1504 14         53 $self->_clear_form_generated_values;
1505              
1506 14         59 return $form;
1507             }
1508              
1509 1         3 return undef;
1510             }
1511              
1512             sub clear_forms
1513             {
1514 280     280 0 525 my($self) = shift;
1515              
1516 280         916 foreach my $form ($self->forms)
1517             {
1518 176         628 $form->clear();
1519             }
1520             }
1521              
1522             sub reset_forms
1523             {
1524 4     4 0 8 my($self) = shift;
1525              
1526 4         25 foreach my $form ($self->forms)
1527             {
1528 0         0 $form->reset();
1529             }
1530             }
1531              
1532             sub _clear_form_generated_values
1533             {
1534 94     94   216 my($self) = shift;
1535 94         294 $self->{'form_list'} = undef;
1536 94         253 $self->{'form_names'} = undef;
1537 94         186 $self->{'form_depth'} = undef;
1538 94         478 $self->_clear_field_generated_values;
1539             }
1540              
1541             sub form_name
1542             {
1543 8287     8287 1 26592 my($self) = shift;
1544              
1545 8287 100       30787 return $self->{'form_name'} unless(@_);
1546 77         182 my $old_name = $self->{'form_name'};
1547 77         265 my $name = $self->{'form_name'} = shift;
1548 77         159 my %forms;
1549              
1550 77 100       316 if(my $parent_form = $self->parent_form)
1551             {
1552 6 100 33     45 if(defined $old_name && defined $name && $name ne $old_name)
      66        
1553             {
1554 2         28 $parent_form->delete_form($old_name);
1555 2         41 $parent_form->add_form($name => $self);
1556             }
1557             }
1558              
1559 77         221 return $name;
1560             }
1561              
1562             sub local_field
1563             {
1564 1631     1631 1 3080 my($self, $name) = (shift, shift);
1565              
1566 1631 100       3475 if(my $field = shift)
1567             {
1568 258         915 $field = $self->make_field($name, $field);
1569              
1570 258         1100 $field->parent_form($self);
1571 8     8   63 no warnings 'uninitialized';
  8         21  
  8         26416  
1572 258 100       1013 $field->name($name) unless(length $field->name);
1573 258         1196 $field->moniker($name);
1574 258         998 $self->{'fields_by_name'}{$field->name} = $field;
1575 258         1703 return $self->{'fields'}{$name} = $field;
1576             }
1577              
1578 1373   66     9287 return $self->{'fields'}{$name} || $self->{'fields_by_name'}{$name};
1579             }
1580              
1581             sub local_fields
1582             {
1583 110     110 1 201 my($self) = shift;
1584 110 50       155 return values %{ $self->{'fields'} || {} };
  110         556  
1585             }
1586              
1587             sub delete_fields
1588             {
1589 8     8 1 1267 my($self) = shift;
1590 8         50 $self->_clear_field_generated_values;
1591 8         43 $self->{'fields'} = {};
1592 8         505 $self->{'fields_by_name'} = {};
1593 8         56 $self->delete_repeatable_fields;
1594 8         42 $self->field_rank_counter(undef);
1595 8         50 return;
1596             }
1597              
1598             sub delete_field
1599             {
1600 2     2 1 7 my($self, $name) = @_;
1601              
1602 2 50       18 $name = $name->name if(UNIVERSAL::isa($name, 'Rose::HTML::Form::Field'));
1603              
1604 2         13 $self->_clear_field_generated_values;
1605              
1606 2         7 my $field1 = delete $self->{'fields'}{$name};
1607 2         6 my $field2 = delete $self->{'fields_by_name'}{$name};
1608 2   33     14 return $field1 || $field2;
1609             }
1610              
1611             sub field
1612             {
1613 3107     3107 1 20661 my($self, $name) = (shift, shift);
1614              
1615 3107 100       10802 return $self->{'field_cache'}{$name} if($self->{'field_cache'}{$name});
1616              
1617 2478         3568 my $sep_pos;
1618              
1619             # Non-hierarchical name
1620 2478 100       5544 if(($sep_pos = index($name, FF_SEPARATOR)) < 0)
1621             {
1622 1580         3943 return $self->{'field_cache'}{$name} = $self->local_field($name, @_);
1623             }
1624              
1625             # First check if it's a local compound field
1626 898         1794 my $prefix = substr($name, 0, $sep_pos);
1627 898         1739 my $rest = substr($name, $sep_pos + 1);
1628 898         1869 my $field = $self->field($prefix);
1629              
1630 898 100       2810 if(UNIVERSAL::isa($field, 'Rose::HTML::Form::Field::Compound'))
1631             {
1632 17         104 $field = $field->field($rest);
1633 17 50       144 return ($self->{'field_cache'}{$name} = $field) if($field);
1634             }
1635              
1636 881         1991 my($parent_form, $local_name) = $self->find_parent_form($name);
1637              
1638 881 50       1810 return undef unless($parent_form);
1639              
1640 881         2107 return $self->{'field_cache'}{$name} = $parent_form->field($local_name, @_);
1641             }
1642              
1643             sub fields
1644             {
1645 888     888 1 2971 my($self) = shift;
1646              
1647 888 100       2017 if(@_)
1648             {
1649 2         12 $self->delete_fields;
1650 2         10 $self->add_fields(@_);
1651             }
1652              
1653 888 100       2576 if(my $fields = $self->{'field_list'})
1654             {
1655 641 100       2571 return wantarray ? @$fields : $fields;
1656             }
1657              
1658 247         517 my $fields = $self->{'fields'};
1659 247         551 my $fields_by_name = $self->{'fields_by_name'};
1660              
1661             $self->{'field_list'} =
1662             [
1663 1606         3158 grep { defined }
1664             map
1665             {
1666 247 100       959 if(/$FF_SEPARATOR_RE([^$FF_SEPARATOR_RE]+)/o)
  1606         5100  
1667             {
1668 610 0 33     1371 $self->field($_) || $fields->{$1} || $fields_by_name->{$1};
1669             }
1670             else
1671             {
1672 996 50 66     3235 $fields->{$_} || $fields_by_name->{$_} || $self->field($_);
1673             }
1674             }
1675             $self->field_monikers
1676             ];
1677              
1678 247 50       825 return wantarray ? @{$self->{'field_list'}} : $self->{'field_list'};
  247         1070  
1679             }
1680              
1681             sub fields_depth_first
1682             {
1683 52     52 1 127 my($self) = shift;
1684              
1685 52         144 my @fields = sort { $a->rank <=> $b->rank } $self->local_fields;
  19         94  
1686              
1687 52         102 foreach my $form ($self->forms)
1688             {
1689 42         137 push(@fields, $form->fields_depth_first);
1690             }
1691              
1692 52 50       133 return wantarray ? @fields : \@fields;
1693             }
1694              
1695             sub field_monikers
1696             {
1697 268     268 1 1707 my($self) = shift;
1698              
1699 268 100       840 if(my $names = $self->{'field_monikers'})
1700             {
1701 25 100       265 return wantarray ? @$names : $names;
1702             }
1703              
1704 243         401 my @info;
1705              
1706 243         1122 $self->_find_field_info($self, \@info);
1707              
1708             $self->{'field_monikers'} =
1709 243 50       1232 [ map { $_->[2] } sort { $self->compare_forms($a->[0], $b->[0]) || $self->compare_fields($a->[1], $b->[1]) } @info ];
  1599         4371  
  3929         12951  
1710              
1711 243 50       837 return wantarray ? @{$self->{'field_monikers'}} : $self->{'field_monikers'};
  243         1796  
1712             }
1713              
1714 13     13 1 172 sub field_names { shift->field_monikers(@_) }
1715              
1716             sub _find_field_info
1717             {
1718 548     548   1232 my($self, $form, $list) = @_;
1719              
1720 548         910 while(my($name, $field) = each %{$form->{'fields'}})
  2147         7912  
1721             {
1722 1599         4881 push(@$list, [ $form, $field, $field->fq_moniker ]);
1723             }
1724              
1725 548         1753 foreach my $sub_form ($form->forms)
1726             {
1727 305         838 $form->_find_field_info($sub_form, $list);
1728             }
1729             }
1730              
1731             sub find_parent_form
1732             {
1733 1242     1242 0 2453 my($self, $name) = @_;
1734              
1735             # Non-hierarchical name
1736 1242 100       3061 if(index($name, FF_SEPARATOR) < 0)
1737             {
1738 278 50       673 return $self->local_form($name) ? ($self, $name) : undef;
1739             }
1740              
1741 964         1374 my $parent_form;
1742              
1743 964         4937 while($name =~ s/^([^$FF_SEPARATOR_RE]+)$FF_SEPARATOR_RE//o)
1744             {
1745 1335         3097 my $parent_name = $1;
1746 1335 100       2639 last if($parent_form = $self->local_form($parent_name));
1747             }
1748              
1749 964 100       2235 unless(defined $parent_form)
1750             {
1751             # Maybe this form ($self) is the parent?
1752 51 100       116 return ($self, $name) if($self->local_field($name));
1753 21         66 return undef;
1754             }
1755              
1756 913 50       2885 return wantarray ? ($parent_form, $name) : $parent_form;
1757             }
1758              
1759             sub choose_parent_form
1760             {
1761 2     2 0 5 my($self, $name) = @_;
1762              
1763             # Non-hierarchical name
1764 2 50       9 if(index($name, FF_SEPARATOR) < 0)
1765             {
1766 0 0       0 return wantarray ? ($self, $name) : $self;
1767             }
1768              
1769 2         5 my($parent_form, $local_name);
1770              
1771 2         53 while($name =~ s/^(.+)$FF_SEPARATOR_RE([^$FF_SEPARATOR_RE]+)$//o)
1772             {
1773 2         9 $local_name = $2;
1774 2 50       8 last if($parent_form = $self->form($1));
1775             }
1776              
1777 2 50       9 return wantarray ? ($parent_form, $local_name) : $parent_form;
1778             }
1779              
1780             sub fq_form_name
1781             {
1782 6080     6080 0 9677 my($self) = shift;
1783              
1784 6080 100       12763 return $self->form_name unless($self->parent_form);
1785              
1786 2157         3273 my @parts;
1787 2157         3088 my $form = $self;
1788              
1789 2157         4235 while(my $parent_form = $form->parent_form)
1790             {
1791 4065         8203 unshift(@parts, $form->form_name);
1792 4065         9390 $form = $parent_form;
1793             }
1794              
1795 2157 50       10388 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       303 return undef unless($self->parent_form);
1803              
1804 18         23 my @context;
1805 18         21 my $form = $self;
1806              
1807 18         19 for(;;)
1808             {
1809 45 100       59 last unless($form->parent_form);
1810 27         65 unshift(@context, $form->form_name);
1811 27         45 $form = $form->parent_form;
1812             }
1813              
1814 18         56 return join(FF_SEPARATOR, @context) . FF_SEPARATOR;
1815             }
1816              
1817             sub local_form
1818             {
1819 2174     2174 1 4035 my($self, $name) = @_;
1820 2174 100       7613 return $self->{'forms'}{$name} if(exists $self->{'forms'}{$name});
1821 1061         4035 return undef;
1822             }
1823              
1824             sub form
1825             {
1826 562     562 1 9030 my($self, $name) = (shift, shift);
1827              
1828             # Set form
1829 562 100       1370 if(@_)
1830             {
1831 1         3 my $form = shift;
1832 1         34 $self->delete_form($name);
1833 1         6 return $self->add_form($name => $form);
1834             }
1835              
1836             # Local form?
1837 561 100       1581 if(my $form = $self->local_form($name))
1838             {
1839 200         1306 return $form;
1840             }
1841              
1842             # Look up nested form
1843 361         1322 my($parent_form, $local_name) = $self->find_parent_form($name);
1844 361 100       2144 return undef unless(defined $parent_form);
1845 62         254 return $parent_form->form($local_name);
1846             }
1847              
1848             sub _html_table
1849             {
1850 5     5   30 my($self, %args) = @_;
1851              
1852 5 50       29 my $xhtml = delete $args{'_xhtml'} ? 'xhtml' : 'html';
1853 5         18 my $xhtml_field = "${xhtml}_field";
1854 5         12 my $xhtml_label = "${xhtml}_label";
1855              
1856             my $max_button_depth =
1857 5 50       21 exists $args{'max_button_depth'} ? $args{'max_button_depth'} : 1;
1858              
1859 5 50       42 $args{'class'} = defined $args{'class'} ?
1860             "$args{'class'} form" : 'form';
1861              
1862 5   50     41 $args{'tr'} ||= {};
1863 5   50     36 $args{'td'} ||= {};
1864              
1865             $args{'table'}{'class'} = defined $args{'table'}{'class'} ?
1866             "$args{'table'}{'class'} form" :
1867 5 50       42 defined $args{'class'} ? $args{'class'} : undef;
    50          
1868              
1869 5 50       31 $args{'tr'}{'class'} = defined $args{'tr'}{'class'} ?
1870             "$args{'tr'}{'class'} field" : 'field';
1871              
1872 5         46 my $html = join('', map { $_->$xhtml() } $self->pre_children);
  2         15  
1873              
1874 0         0 $html .= join("\n", map { $_->$xhtml_field() }
1875 5         36 grep { $_->isa('Rose::HTML::Form::Field::Hidden') } $self->fields);
  10         91  
1876              
1877 5 100       21 $html .= "\n\n" if($html);
1878              
1879 5         34 $html .= '<table' . Rose::HTML::Util::html_attrs_string($args{'table'}) . ">\n";
1880              
1881 5         187 my $form_start = "start_$xhtml";
1882 5         14 my $form_end = "end_$xhtml";
1883              
1884 5         21 my $i = 1;
1885              
1886 5         13 my @buttons;
1887              
1888 5         29 foreach my $field (grep { !$_->isa('Rose::HTML::Form::Field::Hidden') } $self->fields_depth_first)
  10         56  
1889             {
1890 10 50       55 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       108 if($field->isa('Rose::HTML::Form::Field::File'))
1902             {
1903 0         0 $form_start = "start_multipart_$xhtml";
1904             }
1905              
1906 10 100       48 my $odd_even = $i++ % 2 ? 'odd' : 'even';
1907              
1908 10         74 local $args{'tr'}{'class'} = "field-$odd_even";
1909 10 50       51 local $args{'td'}{'class'} = $args{'td'}{'class'} ? "$args{'td'}{'class'} label" : 'label';
1910              
1911 10         96 my $label = $field->$xhtml_label();
1912              
1913 10 50       37 unless($label)
1914             {
1915 10         44 my $name = $field->name;
1916              
1917 10         30 for($name)
1918             {
1919 10         32 tr[_.][ ];
1920 10         158 s/\b(\w)/\u$1/g;
1921             }
1922              
1923 10         43 $label = Rose::HTML::Label->new(contents => Rose::HTML::Util::escape_html($name));
1924              
1925 10 50       50 if($field->html_attr_exists('id'))
1926             {
1927 0         0 $label->for($field->html_attr('id'));
1928             }
1929              
1930 10         56 $label = $label->$xhtml();
1931             }
1932              
1933 10 50       87 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         42 '<td' . Rose::HTML::Util::html_attrs_string($args{'td'}) . ">$label</td>\n";
1944              
1945 10         361 $args{'td'}{'class'} =~ s/(?:^| )label$//;
1946 10 50       42 $args{'td'}{'class'} = $args{'td'}{'class'} ? "$args{'td'}{'class'} field" : 'field';
1947              
1948 10         38 $html .= '<td' . Rose::HTML::Util::html_attrs_string($args{'td'}) . '>' .
1949             $field->$xhtml() .
1950             "</td>\n</tr>\n";
1951             }
1952             }
1953              
1954 5 50       26 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         41 $html .= "</table>\n\n" . join('', map { $_->$xhtml() } $self->post_children);
  2         11  
1970              
1971 5 100       44 $html .= "\n\n" unless($html =~ /\n\n\z/);
1972              
1973 5         52 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 36 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   3879 my($self) = $_[0];
1998              
1999 3 50       17 my $class = ref($self) or croak "$self is not an object";
2000              
2001 3         16 my $delegate = $class->delegate_to_subforms;
2002              
2003 3 50       77 unless($delegate)
2004             {
2005 0         0 goto &Rose::HTML::Object::AUTOLOAD;
2006             }
2007              
2008 3         8 my $method = $AUTOLOAD;
2009 3         24 $method =~ s/.*://;
2010              
2011 3         7 my $to_form;
2012              
2013 3         12 foreach my $form ($self->forms)
2014             {
2015 3 100       109 if($form->can($method))
2016             {
2017 2         5 $to_form = $form;
2018 2         3 last;
2019             }
2020             }
2021              
2022 3 100       24 unless($to_form)
2023             {
2024 1         3 $Rose::HTML::Object::AUTOLOAD = $AUTOLOAD;
2025 1         6 goto &Rose::HTML::Object::AUTOLOAD;
2026             }
2027              
2028 2 50       9 if($delegate eq 'compile')
    0          
2029             {
2030 2         6 my $form_name = $to_form->form_name;
2031              
2032 8     8   78 no strict 'refs';
  8         17  
  8         1531  
2033 2     2   16 *$AUTOLOAD = sub { shift->form($form_name)->$method(@_) };
  2         9  
2034 2         4 ${$class . '::__AUTODELEGATED'}{$method} = 1;
  2         12  
2035 2         9 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   2979 use utf8; # The __DATA__ section contains UTF-8 text
  8         1311  
  8         77  
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.