File Coverage

blib/lib/HTML/FormFu/Role/Element/Field.pm
Criterion Covered Total %
statement 308 407 75.6
branch 127 226 56.1
condition 111 153 72.5
subroutine 41 56 73.2
pod 8 19 42.1
total 595 861 69.1


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