File Coverage

blib/lib/HTML/FormFu/Role/Element/Field.pm
Criterion Covered Total %
statement 306 402 76.1
branch 125 220 56.8
condition 108 150 72.0
subroutine 42 55 76.3
pod 8 19 42.1
total 589 846 69.6


line stmt bran cond sub pod time code
1             package HTML::FormFu::Role::Element::Field;
2              
3 383     383   247891 use strict;
  383         588  
  383         15141  
4             our $VERSION = '2.05'; # VERSION
5              
6 383     383   1466 use Moose::Role;
  383         501  
  383         2228  
7 383     383   1452076 use MooseX::Aliases;
  383         328961  
  383         1201  
8 383     383   16941945 use MooseX::Attribute::FormFuChained;
  383         662  
  383         16640  
9              
10             with 'HTML::FormFu::Role::ContainsElementsSharedWithField',
11             'HTML::FormFu::Role::NestedHashUtils',
12             'HTML::FormFu::Role::FormBlockAndFieldMethods',
13             'HTML::FormFu::Role::Element::Layout';
14              
15 383         23276 use HTML::FormFu::Attribute qw(
16             mk_attrs
17             mk_output_accessors
18 383     383   1509 );
  383         546  
19 383     383   1556 use HTML::FormFu::Constants qw( $EMPTY_STR );
  383         504  
  383         39330  
20 383         22143 use HTML::FormFu::Util qw(
21             _parse_args append_xml_attribute
22             xml_escape require_class
23             process_attrs _filter_components
24 383     383   1797 );
  383         592  
25 383     383   1602 use Class::MOP::Method;
  383         522  
  383         7072  
26 383     383   1345 use Clone ();
  383         532  
  383         8069  
27 383     383   1370 use List::Util 1.45 qw( uniq );
  383         9886  
  383         21040  
28 383     383   1591 use Carp qw( croak carp );
  383         490  
  383         1730753  
29              
30             __PACKAGE__->mk_attrs( qw(
31             comment_attributes
32             container_attributes
33             label_attributes
34             error_attributes
35             error_container_attributes
36             ) );
37              
38             has _constraints => ( is => 'rw', traits => ['FormFuChained'] );
39             has _filters => ( is => 'rw', traits => ['FormFuChained'] );
40             has _inflators => ( is => 'rw', traits => ['FormFuChained'] );
41             has _deflators => ( is => 'rw', traits => ['FormFuChained'] );
42             has _validators => ( is => 'rw', traits => ['FormFuChained'] );
43             has _transformers => ( is => 'rw', traits => ['FormFuChained'] );
44             has _plugins => ( is => 'rw', traits => ['FormFuChained'] );
45             has _errors => ( is => 'rw', traits => ['FormFuChained'] );
46             has container_tag => ( is => 'rw', traits => ['FormFuChained'] );
47             has field_filename => ( is => 'rw', traits => ['FormFuChained'] );
48             has label_filename => ( is => 'rw', traits => ['FormFuChained'] );
49             has label_tag => ( is => 'rw', traits => ['FormFuChained'] );
50             has retain_default => ( is => 'rw', traits => ['FormFuChained'] );
51             has force_default => ( is => 'rw', traits => ['FormFuChained'] );
52             has javascript => ( is => 'rw', traits => ['FormFuChained'] );
53             has non_param => ( is => 'rw', traits => ['FormFuChained'] );
54             has reverse_single => ( is => 'rw', traits => ['FormFuChained'] );
55             has reverse_multi => ( is => 'rw', traits => ['FormFuChained'] );
56             has multi_value => ( is => 'rw', traits => ['FormFuChained'] );
57             has original_name => ( is => 'rw', traits => ['FormFuChained'] );
58             has original_nested_name => ( is => 'rw', traits => ['FormFuChained'] );
59             has default_empty_value => ( is => 'rw', traits => ['FormFuChained'] );
60              
61             __PACKAGE__->mk_output_accessors(qw( comment label value ));
62              
63             alias( "default", "value" );
64             alias( "default_xml", "value_xml" );
65             alias( "default_loc", "value_loc" );
66              
67             after BUILD => sub {
68             my $self = shift;
69              
70             $self->_constraints( [] );
71             $self->_filters( [] );
72             $self->_deflators( [] );
73             $self->_inflators( [] );
74             $self->_validators( [] );
75             $self->_transformers( [] );
76             $self->_plugins( [] );
77             $self->_errors( [] );
78             $self->comment_attributes( {} );
79             $self->container_attributes( {} );
80             $self->label_attributes( {} );
81             $self->error_attributes( {} );
82             $self->error_container_attributes( {} );
83             $self->label_filename('label');
84             $self->label_tag('label');
85             $self->container_tag('div');
86             $self->is_field(1);
87              
88             return;
89             };
90              
91             sub nested {
92 1012     1012 0 1125 my ($self) = @_;
93              
94 1012 50       1973 croak 'cannot set nested' if @_ > 1;
95              
96 1012 50       2013 if ( defined $self->name ) {
97 1012         1008 my $parent = $self;
98              
99 1012         2330 while ( defined( $parent = $parent->parent ) ) {
100              
101 1294 100 100     15715 if ( $parent->can('is_field') && $parent->is_field ) {
102 97 50       201 return 1 if defined $parent->name;
103             }
104             else {
105 1197 100       25818 return 1 if defined $parent->nested_name;
106             }
107             }
108             }
109              
110 760         1921 return;
111             }
112              
113             sub nested_name {
114 18163     18163 0 15800 my ($self) = @_;
115              
116 18163 50       26221 croak 'cannot set nested_name' if @_ > 1;
117              
118 18163 100       32141 return if !defined $self->name;
119              
120 18105         28129 my @names = $self->nested_names;
121              
122 18105 50       37086 if ( $self->form->nested_subscript ) {
123 0         0 my $name = shift @names;
124 0         0 map { $name .= "[$_]" } @names;
  0         0  
125              
126             # TODO - Mario Minati 19.05.2009
127             # Does this (name formatted as '[name]') collide with FF::Model::HashRef as
128             # it uses /_\d/ to parse repeatable names?
129 0         0 return $name;
130             }
131             else {
132 18105         67754 return join ".", @names;
133             }
134             }
135              
136             sub nested_names {
137 16075     16075 0 12191 my ($self) = @_;
138              
139 16075 50       21954 croak 'cannot set nested_names' if @_ > 1;
140              
141 16075 50       23036 if ( defined( my $name = $self->name ) ) {
142 16075         11512 my @names;
143 16075         11421 my $parent = $self;
144              
145             # micro optimization! this method's called a lot, so access
146             # parent hashkey directly, instead of calling parent()
147 16075         23935 while ( defined( $parent = $parent->{parent} ) ) {
148              
149 26160 100 100     308783 if ( $parent->can('is_field') && $parent->is_field ) {
    100 100        
150              
151             # handling Field
152 535 100       945 push @names, $parent->name
153             if defined $parent->name;
154             }
155             elsif ( $parent->can('is_repeatable') && $parent->is_repeatable ) {
156              
157             # handling Repeatable
158             # ignore Repeatables nested_name attribute as it is provided
159             # by the childrens Block elements
160             }
161             else {
162              
163             # handling 'not Field' and 'not Repeatable'
164 22737 100       484497 push @names, $parent->nested_name
165             if defined $parent->nested_name;
166             }
167             }
168              
169 16075 100       24949 if (@names) {
170 3205         7890 return reverse $name, @names;
171             }
172             }
173              
174 12870         23092 return ( $self->name );
175             }
176              
177             sub build_original_nested_name {
178 67     67 0 67 my ($self) = @_;
179              
180 67 50       131 croak 'cannot set build_original_nested_name' if @_ > 1;
181              
182 67 50       118 return if !defined $self->name;
183              
184 67         129 my @names = $self->build_original_nested_names;
185              
186 67 50       196 if ( $self->form->nested_subscript ) {
187 0         0 my $name = shift @names;
188 0         0 map { $name .= "[$_]" } @names;
  0         0  
189              
190             # TODO - Mario Minati 19.05.2009
191             # Does this (name formatted as '[name]') collide with FF::Model::HashRef as
192             # it uses /_\d/ to parse repeatable names?
193 0         0 return $name;
194             }
195             else {
196 67         1729 return join ".", @names;
197             }
198             }
199              
200             sub build_original_nested_names {
201 67     67 0 69 my ($self) = @_;
202              
203 67 50       120 croak 'cannot set build_original_nested_names' if @_ > 1;
204              
205             # TODO - Mario Minati 19.05.2009
206             # Maybe we have to use original_name instead of name.
207             # Yet there is no testcase, which is currently failing.
208              
209 67 50       103 if ( defined( my $name = $self->name ) ) {
210 67         52 my @names;
211 67         66 my $parent = $self;
212              
213             # micro optimization! this method's called a lot, so access
214             # parent hashkey directly, instead of calling parent()
215 67         129 while ( defined( $parent = $parent->{parent} ) ) {
216              
217 179 100 100     2900 if ( $parent->can('is_field') && $parent->is_field ) {
    100 100        
218              
219             # handling Field
220 10 50       254 if ( defined $parent->original_name ) {
    0          
221 10         257 push @names, $parent->original_name;
222             }
223             elsif ( defined $parent->name ) {
224 0         0 push @names, $parent->name;
225             }
226             }
227             elsif ( $parent->can('is_repeatable') && $parent->is_repeatable ) {
228              
229             # handling Repeatable
230             # TODO - Mario Minati 19.05.2009
231             # Do we have to take care of chains of Repeatable elements, if the Block
232             # elements have already been created for the outer Repeatable elements to
233             # avoid 'outer.outer_1.inner'
234             # Yet there is no failing testcase. All testcases in FF and FF::Model::DBIC
235             # which have nested repeatable elements are passing currently.
236 69 100       1611 push @names, $parent->original_nested_name
237             if defined $parent->original_nested_name;
238             }
239             else {
240              
241             # handling 'not Field' and 'not Repeatable'
242 100 50 66     2344 if ( $parent->can('original_nested_name')
    50          
243             && defined $parent->original_nested_name )
244             {
245 0         0 push @names, $parent->original_nested_name;
246             }
247             elsif ( defined $parent->nested_name ) {
248 0         0 push @names, $parent->nested_name;
249             }
250             }
251             }
252              
253 67 50       129 if (@names) {
254 67         202 return reverse $name, @names;
255             }
256             }
257              
258 0         0 return ( $self->name );
259             }
260              
261             sub nested_base {
262 0     0 0 0 my ($self) = @_;
263              
264 0 0       0 croak 'cannot set nested_base' if @_ > 1;
265              
266 0         0 my $parent = $self;
267              
268 0         0 while ( defined( $parent = $parent->parent ) ) {
269              
270 0 0       0 return $parent->nested_name if defined $parent->nested_name;
271             }
272             }
273              
274             sub get_deflators {
275 111     111 1 1712 my $self = shift;
276 111         201 my %args = _parse_args(@_);
277              
278 111         79 my @x = @{ $self->_deflators };
  111         2735  
279              
280 111         365 return _filter_components( \%args, \@x );
281             }
282              
283             sub get_filters {
284 1211     1211 1 1230 my $self = shift;
285 1211         2269 my %args = _parse_args(@_);
286              
287 1211         1103 my @x = @{ $self->_filters };
  1211         29643  
288              
289 1211         2621 return _filter_components( \%args, \@x );
290             }
291              
292             sub get_constraints {
293 1239     1239 1 1166 my $self = shift;
294 1239         2325 my %args = _parse_args(@_);
295              
296 1239         1065 my @x = @{ $self->_constraints };
  1239         30633  
297              
298 1239         2553 return _filter_components( \%args, \@x );
299             }
300              
301             sub get_inflators {
302 994     994 1 3167 my $self = shift;
303 994         1848 my %args = _parse_args(@_);
304              
305 994         906 my @x = @{ $self->_inflators };
  994         24859  
306              
307 994         2095 return _filter_components( \%args, \@x );
308             }
309              
310             sub get_validators {
311 808     808 1 1071 my $self = shift;
312 808         1676 my %args = _parse_args(@_);
313              
314 808         740 my @x = @{ $self->_validators };
  808         20133  
315              
316 808         2252 return _filter_components( \%args, \@x );
317             }
318              
319             sub get_transformers {
320 806     806 1 847 my $self = shift;
321 806         1434 my %args = _parse_args(@_);
322              
323 806         734 my @x = @{ $self->_transformers };
  806         20443  
324              
325 806         1707 return _filter_components( \%args, \@x );
326             }
327              
328             sub get_errors {
329 8026     8026 1 6855 my $self = shift;
330 8026         12809 my %args = _parse_args(@_);
331              
332 8026         6135 my @x = @{ $self->_errors };
  8026         193794  
333              
334 8026         15102 _filter_components( \%args, \@x );
335              
336 8026 100       12920 if ( !$args{forced} ) {
337 6393         6784 @x = grep { !$_->forced } @x;
  1170         27821  
338             }
339              
340 8026         17555 return \@x;
341             }
342              
343             sub clear_errors {
344 1252     1252 1 1228 my ($self) = @_;
345              
346 1252         29484 $self->_errors( [] );
347              
348 1252         2135 return;
349             }
350              
351             after pre_process => sub {
352             my $self = shift;
353              
354             for my $plugin ( @{ $self->_plugins } ) {
355             $plugin->pre_process;
356             }
357              
358             return;
359             };
360              
361             after process => sub {
362             my $self = shift;
363              
364             for my $plugin ( @{ $self->_plugins } ) {
365             $plugin->process;
366             }
367              
368             return;
369             };
370              
371             after post_process => sub {
372             my $self = shift;
373              
374             for my $plugin ( @{ $self->_plugins } ) {
375             $plugin->post_process;
376             }
377              
378             return;
379             };
380              
381             sub process_input {
382 1231     1231 0 1337 my ( $self, $input ) = @_;
383              
384 1231         2680 my $submitted = $self->form->submitted;
385 1231         3749 my $default = $self->default;
386 1231         2216 my $original = $self->value;
387 1231         2352 my $name = $self->nested_name;
388              
389             # set input to default value (defined before calling FormFu->process)
390 1231 100 66     32295 if ( $submitted && $self->force_default && defined $default ) {
    100 100        
    100 66        
      100        
      100        
      66        
      66        
      100        
391 33         120 $self->set_nested_hash_value( $input, $name, $default );
392             }
393              
394             # checkbox, radio
395             elsif ($submitted
396             && $self->force_default
397             && $self->can('checked')
398             && $self->checked )
399             {
400              
401             # the checked attribute is set, so force input to be the original value
402 8         20 $self->set_nested_hash_value( $input, $name, $original );
403             }
404              
405             # checkbox, radio
406             elsif ($submitted
407             && $self->force_default
408             && !defined $default
409             && defined $original )
410             {
411              
412             # default and value are not equal, so this element is not checked by default
413 8         30 $self->set_nested_hash_value( $input, $name, undef );
414             }
415              
416 1231         2713 return;
417             }
418              
419             sub prepare_id {
420 1270     1270 0 1443 my ( $self, $render ) = @_;
421              
422 1270 100 100     6673 if ( !defined $render->{attributes}{id}
      66        
423             && defined $self->auto_id
424             && length $self->auto_id )
425             {
426 39 100       101 my $form_name
427             = defined $self->form->id
428             ? $self->form->id
429             : $EMPTY_STR;
430              
431             my $field_name
432             = defined $render->{nested_name}
433             ? $render->{nested_name}
434 39 50       108 : $EMPTY_STR;
435              
436 39         103 my %string = (
437             f => $form_name,
438             n => $field_name,
439             );
440              
441 39         68 my $id = $self->auto_id;
442 39         273 $id =~ s/%([fn])/$string{$1}/g;
443              
444 39 100       115 if ( defined( my $count = $self->repeatable_count ) ) {
445 4         9 $id =~ s/%r/$count/g;
446             }
447              
448 39         111 $render->{attributes}{id} = $id;
449             }
450              
451 1270         1985 return;
452             }
453              
454             sub process_value {
455 1202     1202 0 1377 my ( $self, $value ) = @_;
456              
457 1202         3935 my $submitted = $self->form->submitted;
458 1202         3821 my $default = $self->default;
459              
460 1202         1196 my $new;
461              
462 1202 100       1942 if ($submitted) {
463 416 100       832 if ( defined $value ) {
    100          
464 351         441 $new = $value;
465             }
466             elsif ( defined $default ) {
467 37         140 $new = $EMPTY_STR;
468             }
469             }
470             else {
471 786         811 $new = $default;
472             }
473              
474 1202 50 100     13612 if ( $submitted
      66        
      66        
475             && $self->retain_default
476             && defined $new
477             && $new eq $EMPTY_STR )
478             {
479 12         72 $new = $default;
480             }
481              
482             # if the default value has been changed after FormFu->process has been
483             # called we use it and set the value to that changed default again
484 1202 100 100     13093 if ( $submitted
      100        
      100        
485             && $self->force_default
486             && defined $default
487             && $new ne $default )
488             {
489 2         2 $new = $default;
490             }
491              
492 1202         2138 return $new;
493             }
494              
495             around render_data_non_recursive => sub {
496             my ( $orig, $self, $args ) = @_;
497              
498             my $render = $self->$orig( {
499             nested_name => xml_escape( $self->nested_name ),
500             comment_attributes => xml_escape( $self->comment_attributes ),
501             container_attributes => xml_escape( $self->container_attributes ),
502             label_attributes => xml_escape( $self->label_attributes ),
503             comment => xml_escape( $self->comment ),
504             label => xml_escape( $self->label ),
505             field_filename => $self->field_filename,
506             label_filename => $self->label_filename,
507             label_tag => $self->label_tag,
508             container_tag => $self->container_tag,
509             error_container_tag => $self->error_container_tag,
510             error_tag => $self->error_tag,
511             reverse_single => $self->reverse_single,
512             reverse_multi => $self->reverse_multi,
513             javascript => $self->javascript,
514             $args ? %$args : (),
515             } );
516              
517             $self->_render_container_class($render);
518             $self->_render_comment_class($render);
519             $self->_render_label($render);
520             $self->_render_value($render);
521             $self->_render_constraint_class($render);
522             $self->_render_inflator_class($render);
523             $self->_render_validator_class($render);
524             $self->_render_transformer_class($render);
525             $self->_render_error_class($render);
526              
527             return $render;
528             };
529              
530             sub _render_label {
531 1318     1318   1404 my ( $self, $render ) = @_;
532              
533 1318 100 100     5035 if ( !defined $render->{label}
      66        
534             && defined $self->auto_label
535             && length $self->auto_label )
536             {
537             my %string = (
538             f => defined $self->form->id ? $self->form->id : '',
539 6 100       24 n => defined $render->{name} ? $render->{name} : '',
    50          
540             );
541              
542 6         16 my $label = $self->auto_label;
543 6         58 $label =~ s/%([fn])/$string{$1}/g;
544              
545 6         25 $render->{label} = $self->form->localize($label);
546             }
547              
548 1318 100 100     3362 if ( defined $render->{label}
      66        
549             && defined $self->auto_label_class
550             && length $self->auto_label_class
551             )
552             {
553 1 50       4 my $form_name
554             = defined $self->form->id
555             ? $self->form->id
556             : $EMPTY_STR;
557              
558             my $field_name
559             = defined $render->{nested_name}
560             ? $render->{nested_name}
561 1 50       7 : $EMPTY_STR;
562              
563 1         27 my $type = lc $self->type;
564 1         3 $type =~ s/:://g;
565              
566 1         4 my %string = (
567             f => $form_name,
568             n => $field_name,
569             t => $type,
570             );
571              
572 1         2 my $class = $self->auto_label_class;
573 1         7 $class =~ s/%([fnt])/$string{$1}/g;
574              
575             append_xml_attribute( $render->{label_attributes},
576 1         5 'class', $class );
577             }
578              
579 1318 100 100     3038 if ( defined $render->{label}
      66        
580             && defined $self->auto_container_label_class
581             && length $self->auto_container_label_class
582             )
583             {
584 3 100       9 my $form_name
585             = defined $self->form->id
586             ? $self->form->id
587             : $EMPTY_STR;
588              
589             my $field_name
590             = defined $render->{nested_name}
591             ? $render->{nested_name}
592 3 50       17 : $EMPTY_STR;
593              
594 3         84 my $type = lc $self->type;
595 3         7 $type =~ s/:://g;
596              
597 3         12 my %string = (
598             f => $form_name,
599             n => $field_name,
600             t => $type,
601             );
602              
603 3         9 my $class = $self->auto_container_label_class;
604 3         10 $class =~ s/%([fnt])/$string{$1}/g;
605              
606             append_xml_attribute( $render->{container_attributes},
607 3         10 'class', $class );
608             }
609              
610             # label "for" attribute
611 1318 100 100     3172 if ( defined $render->{label}
      66        
612             && defined $render->{attributes}{id}
613             && !exists $render->{label_attributes}{for} )
614             {
615 27         51 $render->{label_attributes}{for} = $render->{attributes}{id};
616             }
617              
618 1318         1271 return;
619             }
620              
621             sub _render_comment_class {
622 1318     1318   3347 my ( $self, $render ) = @_;
623              
624 1318 100 100     3314 if ( defined $render->{comment}
      66        
625             && defined $self->auto_comment_class
626             && length $self->auto_comment_class
627             )
628             {
629 3 100       8 my $form_name
630             = defined $self->form->id
631             ? $self->form->id
632             : $EMPTY_STR;
633              
634             my $field_name
635             = defined $render->{nested_name}
636             ? $render->{nested_name}
637 3 50       13 : $EMPTY_STR;
638              
639 3         7 my %string = (
640             f => $form_name,
641             n => $field_name,
642             );
643              
644 3         7 my $class = $self->auto_comment_class;
645 3         11 $class =~ s/%([fn])/$string{$1}/g;
646              
647             append_xml_attribute( $render->{comment_attributes},
648 3         10 'class', $class );
649             }
650              
651 1318 100 100     3222 if ( defined $render->{comment}
      66        
652             && defined $self->auto_container_comment_class
653             && length $self->auto_container_comment_class
654             )
655             {
656 3 100       8 my $form_name
657             = defined $self->form->id
658             ? $self->form->id
659             : $EMPTY_STR;
660              
661             my $field_name
662             = defined $render->{nested_name}
663             ? $render->{nested_name}
664 3 50       12 : $EMPTY_STR;
665              
666 3         8 my %string = (
667             f => $form_name,
668             n => $field_name,
669             );
670              
671 3         9 my $class = $self->auto_container_comment_class;
672 3         10 $class =~ s/%([fn])/$string{$1}/g;
673              
674             append_xml_attribute( $render->{container_attributes},
675 3         9 'class', $class );
676             }
677              
678 1318         1235 return;
679             }
680              
681             sub _render_value {
682 1318     1318   1345 my ( $self, $render ) = @_;
683              
684 1318         3180 my $form = $self->form;
685 1318         2361 my $name = $self->nested_name;
686              
687 1318         1458 my $input;
688              
689 1318 100 100     2616 if ( $self->form->submitted
      100        
690             && defined $name
691             && $self->nested_hash_key_exists( $form->input, $name ) )
692             {
693 409 100       1263 if ( $self->render_processed_value ) {
694 7         155 $input
695             = $self->get_nested_hash_value( $form->_processed_params, $name,
696             );
697             }
698             else {
699 402         8557 $input = $self->get_nested_hash_value( $form->input, $name, );
700             }
701             }
702              
703 1318 100       3007 if ( ref $input eq 'ARRAY' ) {
704 24         61 my $elems = $self->form->get_fields( $self->name );
705 24         107 for ( 0 .. @$elems - 1 ) {
706 42 100       118 if ( $self == $elems->[$_] ) {
707 24         47 $input = $input->[$_];
708             }
709             }
710             }
711              
712 1318         3183 my $value = $self->process_value($input);
713              
714 1318 100 100     4557 if ( !$self->form->submitted
      66        
715             || ( $self->render_processed_value && defined $value ) )
716             {
717 836         1072 for my $deflator ( @{ $self->_deflators } ) {
  836         20585  
718 31         210 $value = $deflator->process($value);
719             }
720             }
721              
722             # handle multiple values for the same name
723 1318 100 66     3848 if ( ref $value eq 'ARRAY' && defined $self->name ) {
724 12         23 my $max = $#$value;
725 12         34 my $fields = $self->form->get_fields( name => $self->name );
726              
727 12         48 for my $i ( 0 .. $max ) {
728 12 50 33     91 if ( defined $fields->[$i] && $fields->[$i] eq $self ) {
729 12         20 $value = $value->[$i];
730 12         26 last;
731             }
732             }
733             }
734              
735 1318         3256 $render->{value} = xml_escape($value);
736              
737 1318         2157 return;
738             }
739              
740             sub _render_container_class {
741 1318     1318   1986 my ( $self, $render ) = @_;
742              
743 1318 100 66     3818 if ( defined $self->auto_container_class
744             && length $self->auto_container_class
745             )
746             {
747 3 100       9 my $form_name
748             = defined $self->form->id
749             ? $self->form->id
750             : $EMPTY_STR;
751              
752             my $field_name
753             = defined $render->{nested_name}
754             ? $render->{nested_name}
755 3 50       10 : $EMPTY_STR;
756              
757 3         71 my $type = lc $self->type;
758 3         8 $type =~ s/:://g;
759              
760 3         10 my %string = (
761             f => $form_name,
762             n => $field_name,
763             t => $type,
764             );
765              
766 3         7 my $class = $self->auto_container_class;
767 3         17 $class =~ s/%([fnt])/$string{$1}/g;
768              
769             append_xml_attribute( $render->{container_attributes},
770 3         11 'class', $class );
771             }
772              
773 1318         1435 return;
774             }
775              
776             sub _render_constraint_class {
777 1318     1318   1453 my ( $self, $render ) = @_;
778              
779 1318         3421 my $auto_class = $self->auto_constraint_class;
780              
781 1318 100       2753 return if !defined $auto_class;
782              
783 2         2 for my $c ( @{ $self->_constraints } ) {
  2         57  
784             my %string = (
785             f => defined $self->form->id ? $self->form->id : '',
786 2 50       5 n => defined $render->{name} ? $render->{name} : '',
    50          
    50          
787             t => defined $c->type ? lc( $c->type ) : '',
788             );
789              
790 2         5 $string{t} =~ s/::/_/g;
791 2         1 $string{t} =~ s/\+//;
792              
793 2         4 my $class = $auto_class;
794              
795 2         14 $class =~ s/%([fnt])/$string{$1}/g;
796              
797             append_xml_attribute( $render->{container_attributes},
798 2         6 'class', $class, );
799             }
800              
801 2         3 return;
802             }
803              
804             sub _render_inflator_class {
805 1318     1318   1376 my ( $self, $render ) = @_;
806              
807 1318         3175 my $auto_class = $self->auto_inflator_class;
808              
809 1318 50       2625 return if !defined $auto_class;
810              
811 0         0 for my $c ( @{ $self->_inflators } ) {
  0         0  
812             my %string = (
813             f => defined $self->form->id ? $self->form->id : '',
814 0 0       0 n => defined $render->{name} ? $render->{name} : '',
    0          
    0          
815             t => defined $c->type ? lc( $c->type ) : '',
816             );
817              
818 0         0 $string{t} =~ s/::/_/g;
819 0         0 $string{t} =~ s/\+//;
820              
821 0         0 my $class = $auto_class;
822              
823 0         0 $class =~ s/%([fnt])/$string{$1}/g;
824              
825             append_xml_attribute( $render->{container_attributes},
826 0         0 'class', $class, );
827             }
828              
829 0         0 return;
830             }
831              
832             sub _render_validator_class {
833 1318     1318   1371 my ( $self, $render ) = @_;
834              
835 1318         3397 my $auto_class = $self->auto_validator_class;
836              
837 1318 50       2695 return if !defined $auto_class;
838              
839 0         0 for my $c ( @{ $self->_validators } ) {
  0         0  
840             my %string = (
841             f => defined $self->form->id ? $self->form->id : '',
842 0 0       0 n => defined $render->{name} ? $render->{name} : '',
    0          
    0          
843             t => defined $c->type ? lc( $c->type ) : '',
844             );
845              
846 0         0 $string{t} =~ s/::/_/g;
847 0         0 $string{t} =~ s/\+//;
848              
849 0         0 my $class = $auto_class;
850              
851 0         0 $class =~ s/%([fnt])/$string{$1}/g;
852              
853             append_xml_attribute( $render->{container_attributes},
854 0         0 'class', $class, );
855             }
856              
857 0         0 return;
858             }
859              
860             sub _render_transformer_class {
861 1318     1318   1314 my ( $self, $render ) = @_;
862              
863 1318         3226 my $auto_class = $self->auto_transformer_class;
864              
865 1318 50       2537 return if !defined $auto_class;
866              
867 0         0 for my $c ( @{ $self->_transformers } ) {
  0         0  
868             my %string = (
869             f => defined $self->form->id ? $self->form->id : '',
870 0 0       0 n => defined $render->{name} ? $render->{name} : '',
    0          
    0          
871             t => defined $c->type ? lc( $c->type ) : '',
872             );
873              
874 0         0 $string{t} =~ s/::/_/g;
875 0         0 $string{t} =~ s/\+//;
876              
877 0         0 my $class = $auto_class;
878              
879 0         0 $class =~ s/%([fnt])/$string{$1}/g;
880              
881             append_xml_attribute( $render->{container_attributes},
882 0         0 'class', $class, );
883             }
884              
885 0         0 return;
886             }
887              
888             sub _render_error_class {
889 1318     1318   1307 my ( $self, $render ) = @_;
890              
891 1318         1543 my @errors = @{ $self->get_errors( { forced => 1 } ) };
  1318         4375  
892              
893 1318 100       3584 return if !@errors;
894              
895 44         83 @errors = map { $_->render_data } @errors;
  47         292  
896              
897 44         108 $render->{errors} = \@errors;
898              
899 44         61 my @container_class;
900              
901             # auto_container_error_class
902 44         175 my $auto_class = $self->auto_container_error_class;
903              
904 44 100 66     174 if ( defined $auto_class && length $auto_class ) {
905             my %string = (
906 0 0   0   0 f => sub { defined $self->form->id ? $self->form->id : '' },
907 0 0   0   0 n => sub { defined $render->{name} ? $render->{name} : '' },
908 2         14 );
909              
910 2         5 $auto_class =~ s/%([fn])/$string{$1}->()/ge;
  0         0  
911              
912 2         13 push @container_class, $auto_class;
913             }
914              
915             # auto_container_per_error_class
916 44         169 my $item_class = $self->auto_container_per_error_class;
917              
918 44 100 66     160 if ( defined $item_class && length $item_class ) {
919 1         2 for my $error (@errors) {
920             my %string = (
921 0 0   0   0 f => sub { defined $self->form->id ? $self->form->id : '' },
922 0 0   0   0 n => sub { defined $render->{name} ? $render->{name} : '' },
923 1     1   3 s => sub { $error->{stage} },
924 1     1   3 t => sub { lc $error->{type} },
925 1         10 );
926              
927 1         2 my $string = $item_class;
928 1         5 $string =~ s/%([fnst])/$string{$1}->()/ge;
  2         5  
929              
930 1         8 push @container_class, $string;
931             }
932             }
933              
934             map {
935 44         163 append_xml_attribute( $render->{container_attributes}, 'class', $_ )
  3         10  
936             } uniq @container_class;
937              
938 44         70 my @error_container_class;
939              
940 44 50       146 if ( $self->error_container_tag ) {
941              
942             # auto_error_container_class
943 0         0 my $auto_class = $self->auto_error_container_class;
944              
945 0 0 0     0 if ( defined $auto_class && length $auto_class ) {
946             my %string = (
947 0 0   0   0 f => sub { defined $self->form->id ? $self->form->id : '' },
948 0 0   0   0 n => sub { defined $render->{name} ? $render->{name} : '' },
949 0         0 );
950              
951 0         0 $auto_class =~ s/%([fn])/$string{$1}->()/ge;
  0         0  
952              
953 0         0 push @error_container_class, $auto_class;
954             }
955              
956             # auto_container_per_error_class
957 0         0 my $item_class = $self->auto_container_per_error_class;
958              
959 0 0 0     0 if ( defined $item_class && length $item_class ) {
960 0         0 for my $error (@errors) {
961             my %string = (
962 0 0   0   0 f => sub { defined $self->form->id ? $self->form->id : '' },
963 0 0   0   0 n => sub { defined $render->{name} ? $render->{name} : '' },
964 0     0   0 s => sub { $error->{stage} },
965 0     0   0 t => sub { lc $error->{type} },
966 0         0 );
967              
968 0         0 my $string = $item_class;
969 0         0 $string =~ s/%([fnst])/$string{$1}->()/ge;
  0         0  
970              
971 0         0 push @error_container_class, $string;
972             }
973             }
974              
975             map {
976 0         0 append_xml_attribute( $render->{error_container_attributes}, 'class', $_ )
  0         0  
977             } uniq @error_container_class;
978             }
979              
980 44         118 return;
981             }
982              
983             sub render_label {
984 6     6 0 1583 my ($self) = @_;
985              
986 6         30 my $render = $self->render_data;
987              
988 6         16 return $self->_string_label( $render );
989             }
990              
991             sub render_field {
992 6     6 0 62 my ($self) = @_;
993              
994 6         14 my $render = $self->render_data;
995              
996 6         1550 return $self->_string_field( $render );
997             }
998              
999             sub _string_field_start {
1000 0     0   0 my ( $self, $render ) = @_;
1001              
1002             # field wrapper template - start
1003              
1004 0         0 my $html = '';
1005              
1006 0 0       0 if ( defined $render->{container_tag} ) {
1007             $html .= sprintf '<%s%s>',
1008             $render->{container_tag},
1009 0         0 process_attrs( $render->{container_attributes} );
1010             }
1011              
1012 0 0 0     0 if ( defined $render->{label} && $render->{label_tag} eq 'legend' ) {
1013 0         0 $html .= sprintf "\n%s", $self->_string_label($render);
1014             }
1015              
1016 0         0 $html .= $self->_string_errors( $render );
1017              
1018 0 0 0     0 if ( defined $render->{label}
      0        
1019             && $render->{label_tag} ne 'legend'
1020             && !$render->{reverse_single} )
1021             {
1022 0         0 $html .= sprintf "\n%s", $self->_string_label($render);
1023             }
1024              
1025 0 0       0 if ( defined $render->{container_tag} ) {
1026 0         0 $html .= "\n";
1027             }
1028              
1029 0         0 return $html;
1030             }
1031              
1032             sub _string_label {
1033 93     93   108 my ( $self, $render ) = @_;
1034              
1035             # label template
1036              
1037             my $html = sprintf "<%s%s>%s</%s>",
1038             $render->{label_tag},
1039             process_attrs( $render->{label_attributes} ),
1040             $render->{label},
1041             $render->{label_tag},
1042 93         256 ;
1043              
1044 93         341 return $html;
1045             }
1046              
1047             sub _string_errors {
1048 700     700   789 my ( $self, $render ) = @_;
1049              
1050 700 100       2911 return '' if !$render->{errors};
1051              
1052 40         61 my $html = '';
1053              
1054 40 50       139 if ( $render->{error_container_tag} ) {
1055             $html .= sprintf qq{<%s%s>\n},
1056             $render->{error_container_tag},
1057 0         0 process_attrs( $render->{error_container_attributes} ),
1058             ;
1059             }
1060              
1061 40         53 my @error_html;
1062 40         48 for my $error ( @{ $render->{errors} } ) {
  40         97  
1063             push @error_html, sprintf qq{<%s%s>%s</%s>},
1064             $render->{error_tag},
1065             process_attrs( $error->{attributes} ),
1066             $error->{message},
1067             $render->{error_tag},
1068 43         234 ;
1069             }
1070 40         133 $html .= join "\n", @error_html;
1071              
1072 40 50       118 if ( $render->{error_container_tag} ) {
1073 0         0 $html .= sprintf qq{\n</%s>}, $render->{error_container_tag};
1074             }
1075              
1076 40         135 return $html;
1077             }
1078              
1079             sub _string_field_end {
1080 0     0     my ( $self, $render ) = @_;
1081              
1082             # field wrapper template - end
1083              
1084 0           my $html = '';
1085              
1086 0 0 0       if ( defined $render->{label}
      0        
1087             && $render->{label_tag} ne 'legend'
1088             && $render->{reverse_single} )
1089             {
1090 0           $html .= sprintf "\n%s", $self->_string_label($render);
1091             }
1092              
1093 0 0         if ( defined $render->{comment} ) {
1094             $html .= sprintf "\n<span%s>\n%s\n</span>",
1095             process_attrs( $render->{comment_attributes} ),
1096             $render->{comment},
1097 0           ;
1098             }
1099              
1100 0 0         if ( defined $render->{container_tag} ) {
1101 0           $html .= sprintf "\n</%s>", $render->{container_tag},;
1102             }
1103              
1104 0 0         if ( defined $render->{javascript} ) {
1105             $html .= sprintf qq{\n<script type="text/javascript">\n%s\n</script>},
1106             $render->{javascript},
1107 0           ;
1108             }
1109              
1110 0           return $html;
1111             }
1112              
1113             around clone => sub {
1114             my $orig = shift;
1115             my $self = shift;
1116              
1117             my $clone = $self->$orig(@_);
1118              
1119             for my $list ( qw(
1120             _filters _constraints _inflators _validators _transformers
1121             _deflators _errors _plugins )
1122             )
1123             {
1124             $clone->$list( [ map { $_->clone } @{ $self->$list } ] );
1125              
1126             map { $_->parent($clone) } @{ $clone->$list };
1127             }
1128              
1129             $clone->comment_attributes( Clone::clone( $self->comment_attributes ) );
1130             $clone->container_attributes( Clone::clone( $self->container_attributes ) );
1131             $clone->label_attributes( Clone::clone( $self->label_attributes ) );
1132              
1133             return $clone;
1134             };
1135              
1136             1;
1137              
1138             __END__
1139              
1140             =head1 NAME
1141              
1142             HTML::FormFu::Role::Element::Field - Role for all form-field elements
1143              
1144             =head1 VERSION
1145              
1146             version 2.05
1147              
1148             =head1 DESCRIPTION
1149              
1150             Base-class for all form-field elements.
1151              
1152             =head1 METHODS
1153              
1154             =head2 default
1155              
1156             Set the form-field's default value.
1157              
1158             Is an L<output accessor|HTML::FormFu/OUTPUT ACCESSORS>.
1159              
1160             =head2 value
1161              
1162             For most fields, L</value> is an alias for L</default>.
1163              
1164             For the L<HTML::FormFu::Element::Checkbox> and
1165             L<HTML::FormFu::Element::Radio> elements, L</value> sets what the value of
1166             the field will be if it is checked or selected. If the L</default> is the
1167             same as the L</value>, then the field will be checked or selected when
1168             rendered.
1169              
1170             For the L<HTML::FormFu::Element::Radiogroup> and
1171             L<HTML::FormFu::Element::Select> elements, the L</value> is ignored:
1172             L<values|HTML::FormFu::Role::Element::Group/values> or
1173             L<options|HTML::FormFu::Role::Element::Group/options> provides the equivalent
1174             function.
1175              
1176             Is an L<output accessor|HTML::FormFu/OUTPUT ACCESSORS>.
1177              
1178             =head2 non_param
1179              
1180             Arguments: bool
1181              
1182             Default Value: false
1183              
1184             If true, values for this field are never returned by L<HTML::FormFu/params>,
1185             L<HTML::FormFu/param> and L<HTML::FormFu/valid>.
1186              
1187             This is useful for Submit buttons, when you only use its value as an
1188             L<indicator|HTML::FormFu/indicator>
1189              
1190             =head2 placeholder
1191              
1192             Sets the HTML5 attribute C<placeholder> to the specified value.
1193              
1194             Is an L<output accessor|HTML::FormFu/OUTPUT ACCESSORS>.
1195              
1196             =head2 javascript
1197              
1198             Arguments: [$javascript]
1199              
1200             If set, the contents will be rendered within a C<script> tag, within the
1201             field's container.
1202              
1203             =head2 retain_default
1204              
1205             If L</retain_default> is true and the form was submitted, but the field
1206             didn't have a value submitted, then when the form is redisplayed to the user
1207             the field will have its value set to its default value, rather than the
1208             usual behaviour of having an empty value.
1209              
1210             Default Value: C<false>
1211              
1212             =head2 force_default
1213              
1214             If L</force_default> is true and the form was submitted, and the field
1215             has a default/value set, then when the form is redisplayed to the user
1216             the field will have its value set to its default value.
1217              
1218             If the default value is being changed after FormFu->process is being called
1219             the later default value is respected for rendering, *but* nevertheless the
1220             input value doesn't respect that, it will remain the first value.
1221              
1222             Default Value: C<false>
1223              
1224             =head2 default_empty_value
1225              
1226             Designed for use by Checkbox fields. Normally if a checkbox is not checked,
1227             no value is submitted for that field. If C<default_empty_value> is true,
1228             the Checkbox field is given an empty value during
1229             L<process|HTML::FormFu/process>. Please note that, with this setting,
1230             the checkbox gets an EMPTY value (as opposed to no value at all without
1231             enabling it), NOT the default value assigned to the element (if any).
1232              
1233             Default Value: C<false>
1234              
1235             =head2 repeatable_count
1236              
1237             Only available for fields attached to a
1238             L<Repeatable|HTML::FormFu::Element::Repeatable> element, after
1239             L<< $repeatable->repeat($count) | HTML::FormFu::Element::Repeatable/repeat >>
1240             has been called.
1241              
1242             The value is inherited from
1243             L<HTML::FormFu::Element::Repeatable/repeatable_count>.
1244              
1245             =head2 clone
1246              
1247             See L<HTML::FormFu/clone> for details.
1248              
1249             =head2 deflators
1250              
1251             See L<HTML::FormFu/deflators> for details.
1252              
1253             =head2 deflator
1254              
1255             See L<HTML::FormFu/deflator> for details.
1256              
1257             =head2 auto_datalist_id
1258              
1259             Arguments: [$string]
1260              
1261             If any L<Input|HTML::FormFu::Role::Element::Input> element had a datalist,
1262             but does not have L<HTML::FormFu::Role::Element::Input/datalist_id> set,
1263             L</auto_datalist_id> is used to generate the datalist id.
1264              
1265             The following character substitution will be performed: C<%f> will be
1266             replaced by L<< $form->id|/id >>, C<%n> will be replaced by
1267             L<< $field->name|HTML::FormFu::Element/name >>, C<%r> will be replaced by
1268             L<< $block->repeatable_count|HTML::FormFu::Element::Repeatable/repeatable_count >>.
1269              
1270             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1271              
1272             =head1 FORM LOGIC AND VALIDATION
1273              
1274             =head2 filters
1275              
1276             See L<HTML::FormFu/filters> for details.
1277              
1278             =head2 filter
1279              
1280             See L<HTML::FormFu/filter> for details.
1281              
1282             =head2 constraints
1283              
1284             See L<HTML::FormFu/constraints> for details.
1285              
1286             =head2 constraint
1287              
1288             See L<HTML::FormFu/constraint> for details.
1289              
1290             =head2 inflators
1291              
1292             See L<HTML::FormFu/inflators> for details.
1293              
1294             =head2 inflator
1295              
1296             See L<HTML::FormFu/inflator> for details.
1297              
1298             =head2 validators
1299              
1300             See L<HTML::FormFu/validators> for details.
1301              
1302             =head2 validator
1303              
1304             See L<HTML::FormFu/validator> for details.
1305              
1306             =head2 transformers
1307              
1308             See L<HTML::FormFu/transformers> for details.
1309              
1310             =head2 transformer
1311              
1312             See L<HTML::FormFu/transformer> for details.
1313              
1314             =head1 CUSTOMIZING GENERATED MARKUP
1315              
1316             Each field is, by default, wrapped in a container.
1317             Each container may also contain a label, a comment, and after an invalid
1318             submission may contain 1 or more error messages.
1319              
1320             Example of generated form:
1321              
1322             1 <form action="" method="post">
1323             2 <div class="has-errors"> # container
1324             3 <ul class="errors"> # error container
1325             4 <li> # error message
1326             5 This field must contain an email address
1327             6 </li>
1328             7 </li>
1329             8 <label>Foo</label> # label
1330             9 <input name="foo" type="text" value="example.com" />
1331             10 <span class="comment"> # comment
1332             11 This is Foo
1333             12 </span>
1334             13 </div>
1335             14 </form>
1336              
1337             # Line 2 starts the 'container' - by default a DIV.
1338             # Line 2 starts an error container, which may contain 1 or more error
1339             messages - in this case, a unordered list (UL).
1340             # Line 4 starts a single error message - in this case, a list item (LI).
1341             # Line 8 shows a 'label'.
1342             # Line 9 shows the field's 'input' tag.
1343             # Lines 10 starts a 'comment'.
1344              
1345             To re-order the various parts of each form (label, input, errors, etc) and
1346             arbitrary extra tags, see the L<layout|/layout> method.
1347              
1348             =head2 CONTAINER
1349              
1350             =head3 container_tag
1351              
1352             Default value: 'div'
1353              
1354             The container wrapping each entire field, any label, comment, and errors.
1355              
1356             =head3 container_attributes
1357              
1358             Attributes added to the container tag.
1359              
1360             Is an L<attribute accessor|HTML::FormFu/ATTRIBUTE ACCESSOR>.
1361              
1362             =head3 auto_container_class
1363              
1364             Default Value: '%t'
1365              
1366             If set, then the container of each field will be given a class-name based on
1367             the given pattern.
1368              
1369             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1370              
1371             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1372              
1373             =head3 auto_container_label_class
1374              
1375             Default Value: 'label'
1376              
1377             If set, and if the field has a L<label|/label>, the container will be given a
1378             class-name based on the given pattern.
1379              
1380             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1381              
1382             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1383              
1384             =head3 auto_container_comment_class
1385              
1386             Default Value: '%t'
1387              
1388             If set, and if the field has a
1389             L<comment|HTML::FormFu::Role::Element::Field/comment>, the container will be
1390             given a class-name based on the given pattern.
1391              
1392             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1393              
1394             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1395              
1396             =head3 auto_container_error_class
1397              
1398             Default Value: 'error'
1399              
1400             If set, then the container of each field with an error will be given a
1401             class-name based on the given pattern.
1402              
1403             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>.
1404              
1405             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1406              
1407             =head3 auto_container_per_error_class
1408              
1409             Default Value: 'error_%s_%t'
1410              
1411             If set, then the container of each field with an error will be given a
1412             class-name based on the given pattern.
1413              
1414             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>, C<%s>.
1415              
1416             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1417              
1418             =head2 FORM FIELD
1419              
1420             =head3 auto_id
1421              
1422             If set, then the field will be given an L<id|HTML::FormFu::Element/id>
1423             attribute, if it doesn't have one already.
1424              
1425             E.g., setting C<< $form->auto_id('%n') >> will make each field have an ID
1426             the same as the field's name. This makes our form config simpler, and ensures
1427             we don't need to manually update IDs if any field names are changed.
1428              
1429             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%r>.
1430              
1431             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1432              
1433             =head2 LABEL
1434              
1435             =head3 label
1436              
1437             Set a label to communicate the purpose of the form-field to the user.
1438              
1439             Is an L<output accessor|HTML::FormFu/OUTPUT ACCESSORS>.
1440              
1441             =head3 auto_label
1442              
1443             If L<label|/label> isn't already set, the value of L</auto_label> is passed through
1444             L<localize|HTML::FormFu/localize> to generate a label.
1445              
1446             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>.
1447              
1448             The generated string will be passed to L</localize> to create the label.
1449              
1450             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1451              
1452             =head3 label_tag
1453              
1454             Default value: 'label'
1455             (except L<Checkboxgroup|HTML::FormFu::Element::Checkboxgroup>)
1456              
1457             Default value: 'legend'
1458             (only L<Checkboxgroup|HTML::FormFu::Element::Checkboxgroup>)
1459              
1460             Set which tag is used to wrap a L<label|/label>.
1461              
1462             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1463              
1464             =head3 label_attributes
1465              
1466             Attributes added to the label container.
1467              
1468             Is an L<attribute accessor|HTML::FormFu/ATTRIBUTE ACCESSOR>.
1469              
1470             =head2 COMMENT
1471              
1472             =head3 comment
1473              
1474             Set a comment to be displayed along with the form-field.
1475              
1476             Is an L<output accessor|HTML::FormFu/OUTPUT ACCESSORS>.
1477              
1478             =head3 comment_attributes
1479              
1480             Attributes added to the comment container.
1481              
1482             Is an L<attribute accessor|HTML::FormFu/ATTRIBUTE ACCESSOR>.
1483              
1484             =head3 auto_comment_class
1485              
1486             Default Value: '%t'
1487              
1488             If set, and if the field has a
1489             L<comment|HTML::FormFu::Role::Element::Field/comment>, the comment tag will
1490             be given a class-name based on the given pattern.
1491              
1492             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1493              
1494             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1495              
1496             =head2 ERROR CONTAINER
1497              
1498             =head3 error_container_tag
1499              
1500             If set, and if the field has any errors, a container of this type is
1501             wrapped around all of the field error messages.
1502              
1503             # Example - this would wrap each individual error in a 'li' tag,
1504             # with a single 'ul' tag wrapped around all the errors.
1505              
1506             element:
1507             name: foo
1508             error_container_tag: ul
1509             error_tag: li
1510              
1511             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1512              
1513             =head3 auto_error_container_class
1514              
1515             Add a class-name to the error container.
1516              
1517             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>.
1518              
1519             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1520              
1521             =head3 auto_error_container_per_error_class
1522              
1523             Add a class-name to the error container for each error on that field.
1524              
1525             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>, C<%s>.
1526              
1527             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1528              
1529             =head2 ERROR MESSAGES
1530              
1531             =head3 error_tag
1532              
1533             Default value: 'span'
1534              
1535             Sets the tag used to wrap each individual error message.
1536              
1537             Defaults to C<span>.
1538              
1539             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1540              
1541              
1542             =head3 auto_error_message
1543              
1544             Default Value: 'form_%s_%t'
1545              
1546             If set, then each error will be given an auto-generated
1547             L<message|HTML::FormFu::Exception::Input/message>, if it doesn't have one
1548             already.
1549              
1550             The generated string will be passed to L</localize> to create the message.
1551              
1552             For example, a L<Required constraint|HTML::FormFu::Constraint::Required>
1553             will return the string C<form_constraint_required>. Under the default
1554             localization behaviour, the appropriate message for
1555             C<form_constraint_required> will be used from the default I18N package.
1556              
1557             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>, C<%s>.
1558              
1559             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1560              
1561             =head3 error_attributes
1562              
1563             Set attributes on the tag of each error message.
1564              
1565             Is an L<attribute accessor|HTML::FormFu/ATTRIBUTE ACCESSOR>.
1566              
1567             =head3 auto_error_class
1568              
1569             Default Value: 'error_%s_%t'
1570              
1571             Add a class-name to the tag of each error message.
1572              
1573             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>, C<%s>.
1574              
1575             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1576              
1577             =head2 PROCESSOR CLASSES
1578              
1579             =head3 auto_constraint_class
1580              
1581             Add a class-name to the container tag, for each constraint added to the field.
1582              
1583             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1584              
1585             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1586              
1587             =head3 auto_inflator_class
1588              
1589             Add a class-name to the container tag, for each inflator added to the field.
1590              
1591             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1592              
1593             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1594              
1595             =head3 auto_validator_class
1596              
1597             Add a class-name to the container tag, for each validator added to the field.
1598              
1599             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1600              
1601             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1602              
1603             =head3 auto_transformer_class
1604              
1605             Add a class-name to the container tag, for each transformer added to the field.
1606              
1607             Supports L<substitutions|HTML::FormFu/ATTRIBUTE SUBSTITUTIONS>: C<%f>, C<%n>, C<%t>.
1608              
1609             Is an L<inheriting accessor|HTML::FormFu/INHERITING ACCESSORS>.
1610              
1611             =head2 REORDERING FIELD COMPONENTS
1612              
1613             =head2 layout
1614              
1615             Specify the order that each sub-part of the element should appear in the
1616             rendered markup.
1617              
1618             # Default Value
1619             $element->layout( [
1620             'errors',
1621             'label',
1622             'field',
1623             'comment',
1624             'javascript',
1625             ] );
1626              
1627             Example: Move the form field (the input tag or equivalent) inside the label
1628             tag, after the label text.
1629             Remove the comment - this will now never be rendered.
1630              
1631             # YAML config
1632             layout:
1633             - errors
1634             - label:
1635             - label_text
1636             - field
1637             - javascript
1638              
1639             # prettified example of rendered markup
1640             <div>
1641             <span>This field is required.</span>
1642             <label>
1643             Foo
1644             <input name="foo" type="text" />
1645             </label>
1646             </div>
1647              
1648             Example: Don't wrap the label text inside it's usual tag.
1649             Insert the form field (the input tag or equivalent) inside an arbitrary
1650             extra tag.
1651              
1652             # YAML config
1653             layout:
1654             - errors
1655             - label_text
1656             -
1657             div:
1658             attributes:
1659             class: xxx
1660             content: field
1661             - comment
1662             - javascript
1663              
1664             # prettified example of rendered markup
1665             <div>
1666             <span>This field is required.</span>
1667             Foo
1668             <div class="xxx">
1669             <input name="foo" type="text" />
1670             </div>
1671             </div>
1672              
1673             The following elements override the default L<layout> value:
1674              
1675             =over
1676              
1677             =item L<HTML::FormFu::Element::Checkboxgroup|HTML::FormFu::Element::Checkboxgroup>
1678              
1679             =item L<HTML::FormFu::Element::Hidden|HTML::FormFu::Element::Hidden>
1680              
1681             =back
1682              
1683             =head3 Specification
1684              
1685             The L<layout|/layout> method accepts an array-ref, hash-ref, or string
1686             argument.
1687              
1688             The processing is recursive, so each item in an array-ref may be any value
1689             accepted by the L<layout|/layout> method.
1690              
1691             A hash-ref must contain a single key and value pair.
1692             If the hash key is the string C<label>, it creates a C<label> tag, using any
1693             previously defined L<LABEL|/LABEL> customizations.
1694             This allows the label tag to contains other elements, such as the form field.
1695              
1696             All other hash key values are asssumed to be an arbitrary block tag name.
1697             The value must be a hash-ref, and may contain one or both C<attributes> or
1698             C<content> keys.
1699              
1700             Any C<attributes> value must be a hash-ref, whose key/values are added to
1701             the block tag. No processing or expansion is done to the C<attributes>
1702             hash-ref at all.
1703              
1704             The C<content> value may be anything accepted by the L<layout|/layout>
1705             method.
1706              
1707             The following strings are accepted:
1708              
1709             =over
1710              
1711             =item errors
1712              
1713             Renders the element error messages.
1714              
1715             See L<ERROR CONTAINER|/"ERROR CONTAINER"> and
1716             L<ERROR MESSAGES|/"ERROR MESSAGES"> to customize the tags and attributes.
1717              
1718             =item label
1719              
1720             Renders the element L<label|/label>.
1721              
1722             See L<LABEL|/LABEL> to customize the tag and attributes.
1723              
1724             =item label_text
1725              
1726             Renders the element L<label|/label> text, without the usual
1727             L<label_tag|/label_tag>.
1728              
1729             =item field
1730              
1731             Renders the form field control (an input tag, button, or other control).
1732              
1733             =item comment
1734              
1735             Renders the element L<comment|/comment>.
1736              
1737             See L<COMMENT|/COMMENT> to customize the tag and attributes.
1738              
1739             =item javascript
1740              
1741             Renders a C<script> tag containing any L<javascript|/javascript>.
1742              
1743             =back
1744              
1745             =head2 multi_layout
1746              
1747             Specify the order that each sub-part of each element within a
1748             L<HTML::FormFu::Element::Multi|HTML::FormFu::Element::Multi> should
1749             appear in the rendered markup.
1750              
1751             # Default Value
1752             $element->multi_layout( [
1753             'label',
1754             'field',
1755             ] );
1756              
1757             Example: Swap the label/field order. This is equivalent to the
1758             now-deprecated L<reverse_multi|/reverse_multi> method.
1759              
1760             # YAML config
1761             multi_layout:
1762             - field
1763             - label
1764              
1765             The following elements override the default C<multi_layout> value:
1766              
1767             =over
1768              
1769             =item L<HTML::FormFu::Element::Checkbox|HTML::FormFu::Element::Checkbox>
1770              
1771             =back
1772              
1773             =head1 RENDERING
1774              
1775             =head2 field_filename
1776              
1777             The template filename to be used for just the form field - not including the
1778             display of any container, label, errors, etc.
1779              
1780             Must be set by more specific field classes.
1781              
1782             =head2 label_filename
1783              
1784             The template filename to be used to render the label.
1785              
1786             Defaults to C<label>.
1787              
1788             =head1 ERROR HANDLING
1789              
1790             =head2 get_errors
1791              
1792             See L<HTML::FormFu/get_errors> for details.
1793              
1794             =head2 add_error
1795              
1796             =head2 clear_errors
1797              
1798             See L<HTML::FormFu/clear_errors> for details.
1799              
1800             =head1 INTROSPECTION
1801              
1802             =head2 get_deflators
1803              
1804             See L<HTML::FormFu/get_deflators> for details.
1805              
1806             =head2 get_deflator
1807              
1808             See L<HTML::FormFu/get_deflator> for details.
1809              
1810             =head2 get_filters
1811              
1812             See L<HTML::FormFu/get_filters> for details.
1813              
1814             =head2 get_filter
1815              
1816             See L<HTML::FormFu/get_filter> for details.
1817              
1818             =head2 get_constraints
1819              
1820             See L<HTML::FormFu/get_constraints> for details.
1821              
1822             =head2 get_constraint
1823              
1824             See L<HTML::FormFu/get_constraint> for details.
1825              
1826             =head2 get_inflators
1827              
1828             See L<HTML::FormFu/get_inflators> for details.
1829              
1830             =head2 get_inflator
1831              
1832             See L<HTML::FormFu/get_inflator> for details.
1833              
1834             =head2 get_validators
1835              
1836             See L<HTML::FormFu/get_validators> for details.
1837              
1838             =head2 get_validator
1839              
1840             See L<HTML::FormFu/get_validator> for details.
1841              
1842             =head2 get_transformers
1843              
1844             See L<HTML::FormFu/get_transformers> for details.
1845              
1846             =head2 get_transformer
1847              
1848             See L<HTML::FormFu/get_transformer> for details.
1849              
1850             =head2 get_errors
1851              
1852             See L<HTML::FormFu/get_errors> for details.
1853              
1854             =head2 clear_errors
1855              
1856             See L<HTML::FormFu/clear_errors> for details.
1857              
1858             =head1 DEPRECATED METHODS
1859              
1860             =over
1861              
1862             =item reverse_single
1863              
1864             See L<layout|/layout> instead.
1865              
1866             =item reverse_multi
1867              
1868             See L<multi_layout|/multi_layout> instead.
1869              
1870             =item errors_filename
1871              
1872             See L<layout_errors_filename|/layout_errors_filename> instead.
1873              
1874             =back
1875              
1876             =head1 SEE ALSO
1877              
1878             Base-class for L<HTML::FormFu::Role::Element::Group>,
1879             L<HTML::FormFu::Role::Element::Input>,
1880             L<HTML::FormFu::Element::Multi>,
1881             L<HTML::FormFu::Element::ContentButton>,
1882             L<HTML::FormFu::Element::Textarea>.
1883              
1884             Is a sub-class of, and inherits methods from L<HTML::FormFu::Element>
1885              
1886             L<HTML::FormFu>
1887              
1888             =head1 AUTHOR
1889              
1890             Carl Franks, C<cfranks@cpan.org>
1891              
1892             =head1 LICENSE
1893              
1894             This library is free software, you can redistribute it and/or modify it under
1895             the same terms as Perl itself.
1896              
1897             =cut