File Coverage

blib/lib/HTML/FormFu/Element/Date.pm
Criterion Covered Total %
statement 221 233 94.8
branch 63 78 80.7
condition 17 23 73.9
subroutine 32 32 100.0
pod 1 6 16.6
total 334 372 89.7


line stmt bran cond sub pod time code
1             package HTML::FormFu::Element::Date;
2              
3 23     23   4640 use strict;
  23         27  
  23         1858  
4             our $VERSION = '2.05'; # VERSION
5              
6 23     23   90 use Moose;
  23         30  
  23         142  
7 23     23   137101 use MooseX::Attribute::FormFuChained;
  23         40  
  23         816  
8              
9             extends 'HTML::FormFu::Element::Multi';
10              
11 23     23   91 use HTML::FormFu::Util qw( _filter_components _parse_args );
  23         27  
  23         1282  
12 23     23   7299 use DateTime;
  23         3168723  
  23         711  
13 23     23   12981 use DateTime::Format::Builder;
  23         1036541  
  23         204  
14 23     23   13163 use DateTime::Format::Natural;
  23         608200  
  23         1507  
15 23     23   173 use DateTime::Locale;
  23         37  
  23         521  
16 23     23   95 use Moose::Util qw( apply_all_roles );
  23         30  
  23         272  
17 23     23   6151 use Scalar::Util qw( blessed );
  23         35  
  23         1053  
18 23     23   92 use List::Util 1.45 qw( all none uniq );
  23         565  
  23         1383  
19 23     23   99 use Carp qw( croak );
  23         30  
  23         5692  
20              
21             __PACKAGE__->mk_attrs(qw( day month year ));
22              
23             has auto_inflate => ( is => 'rw', traits => ['FormFuChained'] );
24             has default_natural => ( is => 'rw', traits => ['FormFuChained'] );
25             has default_datetime_args => ( is => 'rw', traits => ['FormFuChained'] );
26             has printf_day => ( is => 'rw', traits => ['FormFuChained'] );
27             has printf_month => ( is => 'rw', traits => ['FormFuChained'] );
28             has printf_year => ( is => 'rw', traits => ['FormFuChained'] );
29              
30             has _known_fields => ( is => 'rw' );
31              
32             has strftime => (
33             is => 'rw',
34             default => '%d-%m-%Y',
35             lazy => 1,
36             traits => ['FormFuChained'],
37             );
38              
39             *default = \&value;
40              
41             # build get_Xs methods
42             for my $method ( qw(
43             deflator filter
44             constraint inflator
45             validator transformer
46             ) )
47             {
48             my $sub = sub {
49 104     104   119 my $self = shift;
50 104         243 my %args = _parse_args(@_);
51 104         237 my $get_method = "get_${method}s";
52              
53 104         176 my $accessor = "_${method}s";
54 104         106 my @x = @{ $self->$accessor };
  104         2801  
55 104         135 push @x, map { @{ $_->$get_method(@_) } } @{ $self->_elements };
  369         258  
  369         962  
  104         2444  
56              
57 104         214 return _filter_components( \%args, \@x );
58             };
59              
60             my $name = __PACKAGE__ . "::get_${method}s";
61              
62             ## no critic (ProhibitNoStrict);
63 23     23   110 no strict 'refs';
  23         33  
  23         40994  
64              
65             *{$name} = $sub;
66             }
67              
68             after BUILD => sub {
69             my ( $self, $args ) = @_;
70              
71             $self->printf_day('%d');
72             $self->printf_month('%d');
73             $self->printf_year('%d');
74              
75             $self->_known_fields( [qw( day month year )] );
76              
77             $self->field_order( [qw( day month year )] );
78              
79             $self->day( { prefix => [], } );
80              
81             $self->month( { prefix => [], } );
82              
83             $self->year( {
84             prefix => [],
85             less => 0,
86             plus => 10,
87             reverse => 0,
88             } );
89              
90             return;
91             };
92              
93             sub value {
94 168     168 0 600 my ( $self, $value ) = @_;
95              
96 168 100       393 if ( @_ > 1 ) {
97 27         63 $self->{value} = $value;
98              
99             # if we're already built - i.e. process() has ben called,
100             # call default() on our children
101              
102 27 100       32 if ( @{ $self->_elements } ) {
  27         734  
103 7         26 $self->_date_defaults;
104              
105 7         9 my @order = @{ $self->field_order };
  7         23  
106              
107 7         23 for my $i ( 0 .. $#order ) {
108 31         29 my $field = $order[$i];
109              
110 31         40 my $printf_method = "printf_$field";
111              
112             my $default
113             = $value
114             ? sprintf( $self->$printf_method, $self->$field->{default} )
115 31 100       168 : undef;
116              
117 31         691 $self->_elements->[$i]->default($default);
118             }
119             }
120              
121 27         160 return $self;
122             }
123              
124 141         1030 return $self->{value};
125             }
126              
127             sub _add_elements {
128 47     47   71 my ($self) = @_;
129              
130 47         1143 $self->_elements( [] );
131              
132 47         177 $self->_date_defaults;
133              
134 47         65 for my $order ( @{ $self->field_order } ) {
  47         103  
135 172         453 my $method = "_add_$order";
136              
137 172         828 $self->$method;
138             }
139              
140 47 100 100     1359 if ( $self->auto_inflate
141 20         137 && !@{ $self->get_inflators( { type => "DateTime" } ) } )
142             {
143 10         38 _add_inflator($self);
144             }
145              
146 47         124 return;
147             }
148              
149             sub _date_defaults {
150 54     54   98 my ($self) = @_;
151              
152 54         81 my $default;
153              
154 54 100 100     168 if ( defined( $default = $self->default ) && length $default ) {
    100          
155              
156 38 100 66     790 if ( !$self->form->submitted || $self->render_processed_value ) {
157 32         42 for my $deflator ( @{ $self->_deflators } ) {
  32         871  
158 1         7 $default = $deflator->process($default);
159             }
160             }
161              
162 38         601 my $is_blessed = blessed($default);
163              
164 38 100 33     286 if ( !$is_blessed || ( $is_blessed && !$default->isa('DateTime') ) ) {
      66        
165 19         126 my $builder = DateTime::Format::Builder->new;
166 19         731 $builder->parser( { strptime => $self->strftime } );
167              
168 19         23189 $default = $builder->parse_datetime($default);
169             }
170             }
171             elsif ( defined( $default = $self->default_natural ) ) {
172 3         3 my $parser;
173              
174 3 100       74 if ( defined( my $datetime_args = $self->default_datetime_args ) ) {
175 2 100       9 if ( exists $datetime_args->{set_time_zone} ) {
176 1         2 my $tz = $datetime_args->{set_time_zone};
177 1         11 $parser = DateTime::Format::Natural->new( time_zone => $tz );
178             }
179             else {
180 1         12 $parser = DateTime::Format::Natural->new;
181             }
182             }
183             else {
184 1         12 $parser = DateTime::Format::Natural->new;
185             }
186 3         56589 $default = $parser->parse_datetime($default);
187             }
188             else {
189 13         23 $default = undef;
190             }
191              
192 54 100       23203 if ( defined $default ) {
193              
194 41 100       1297 if ( defined( my $datetime_args = $self->default_datetime_args ) ) {
195 2         9 for my $key ( keys %$datetime_args ) {
196 2         9 $default->$key( $datetime_args->{$key} );
197             }
198             }
199              
200 41         402 for my $field ( @{ $self->field_order } ) {
  41         132  
201 153         465 $self->$field->{default} = $default->$field;
202             }
203             }
204              
205 54         171 return;
206             }
207              
208             sub _add_day {
209 43     43   64 my ($self) = @_;
210              
211 43         136 my $day = $self->day;
212              
213 43         175 my $day_name = $self->_build_name('day');
214              
215             my @day_prefix
216             = ref $day->{prefix}
217 31         87 ? @{ $day->{prefix} }
218 43 100       165 : $day->{prefix};
219              
220 43 50       133 if ( exists $day->{prefix_loc} ) {
221             @day_prefix
222             = ref $day->{prefix_loc}
223 0         0 ? map { $self->form->localize($_) } @{ $day->{prefix_loc} }
  0         0  
224 0 0       0 : $self->form->localize( $day->{prefix_loc} );
225             }
226              
227 43         99 @day_prefix = map { [ '', $_ ] } @day_prefix;
  12         50  
228              
229             my $element = $self->element( {
230             type => 'Select',
231             name => $day_name,
232 1333         1723 options => [ @day_prefix, map { [ $_, $_ ] } 1 .. 31 ],
233             attributes => $day->{attributes},
234              
235 43 100       124 defined $day->{default} ? ( default => $day->{default} ) : (),
236             } );
237              
238 43         431 apply_all_roles( $element, 'HTML::FormFu::Role::Element::MultiElement' );
239              
240 43         470603 return;
241             }
242              
243             sub _add_month {
244 47     47   83 my ($self) = @_;
245              
246 47         232 my $month = $self->month;
247              
248 47         176 my $month_name = $self->_build_name('month');
249              
250 47         175 my @months = _build_month_list($self);
251              
252             my @month_prefix
253             = ref $month->{prefix}
254 33         93 ? @{ $month->{prefix} }
255 47 100       211 : $month->{prefix};
256              
257 47 50       165 if ( exists $month->{prefix_loc} ) {
258             @month_prefix
259             = ref $month->{prefix_loc}
260 0         0 ? map { $self->form->localize($_) } @{ $month->{prefix_loc} }
  0         0  
261 0 0       0 : $self->form->localize( $month->{prefix_loc} );
262             }
263              
264 47         104 @month_prefix = map { [ '', $_ ] } @month_prefix;
  14         58  
265              
266 47         108 my $options = [ @month_prefix, map { [ $_ + 1, $months[$_] ] } 0 .. 11 ];
  564         761  
267              
268             my $element = $self->element( {
269             type => 'Select',
270             name => $month_name,
271             options => $options,
272             attributes => $month->{attributes},
273              
274 47 100       508 defined $month->{default} ? ( default => $month->{default} ) : (),
275             } );
276              
277 47         246 apply_all_roles( $element, 'HTML::FormFu::Role::Element::MultiElement' );
278              
279 47         416206 return;
280             }
281              
282             sub _add_year {
283 47     47   88 my ($self) = @_;
284              
285 47         247 my $year = $self->year;
286              
287 47         160 my $year_name = $self->_build_name('year');
288              
289             my $year_ref
290             = defined $year->{reference}
291             ? $year->{reference}
292 47 100       5960 : ( localtime(time) )[5] + 1900;
293              
294             my @years
295             = defined $year->{list}
296 36         172 ? @{ $year->{list} }
297 47 100       269 : ( $year_ref - $year->{less} ) .. ( $year_ref + $year->{plus} );
298              
299 47 100       195 if ( $year->{reverse} ) {
300 1         3 @years = reverse(@years);
301             }
302              
303             my @year_prefix
304             = ref $year->{prefix}
305 33         88 ? @{ $year->{prefix} }
306 47 100       202 : $year->{prefix};
307              
308 47 50       153 if ( exists $year->{prefix_loc} ) {
309             @year_prefix
310             = ref $year->{prefix_loc}
311 0         0 ? map { $self->form->localize($_) } @{ $year->{prefix_loc} }
  0         0  
312 0 0       0 : $self->form->localize( $year->{prefix_loc} );
313             }
314              
315 47         152 @year_prefix = map { [ '', $_ ] } @year_prefix;
  14         73  
316              
317             my $element = $self->element( {
318             type => 'Select',
319             name => $year_name,
320 403         891 options => [ @year_prefix, map { [ $_, $_ ] } @years ],
321             attributes => $year->{attributes},
322              
323 47 100       129 defined $year->{default} ? ( default => $year->{default} ) : (),
324             } );
325              
326 47         315 apply_all_roles( $element, 'HTML::FormFu::Role::Element::MultiElement' );
327              
328 47         419788 return;
329             }
330              
331             sub _build_month_list {
332 47     47   85 my ($self) = @_;
333              
334 47         186 my $month = $self->month;
335 47         84 my @months;
336              
337 47 50       170 if ( defined $month->{names} ) {
338 0         0 @months = @{ $month->{names} };
  0         0  
339             }
340             else {
341 47         311 my $languages = $self->form->languages;
342 47 50       177 if ( ref $languages ne 'ARRAY' ) {
343 0         0 $languages = [$languages];
344             }
345              
346 47         117 for my $lang (@$languages) {
347 47         61 my $loc;
348              
349 47         99 eval { $loc = DateTime::Locale->load($lang) };
  47         464  
350 47 50       1902 if ( !$@ ) {
351             @months
352             = $month->{short_names}
353 14         83 ? @{ $loc->month_format_abbreviated }
354 47 100       159 : @{ $loc->month_format_wide };
  33         191  
355              
356 47         449 @months = map {ucfirst} @months;
  564         739  
357              
358 47         163 last;
359             }
360             }
361             }
362              
363 47         275 return @months;
364             }
365              
366             sub _build_number_list {
367 19     19   67 my ( $self, $start, $end, $interval ) = @_;
368              
369 19   100     108 $interval ||= 1;
370              
371 19         24 my @list;
372              
373 19         60 for ( my $i = $start; $i <= $end; $i += $interval ) {
374 1034         1197 push @list, $i;
375             }
376              
377 19         123 return @list;
378             }
379              
380             sub _build_name {
381 172     172   325 my ( $self, $type ) = @_;
382              
383             my $name
384             = defined $self->$type->{name}
385             ? $self->$type->{name}
386 172 50       395 : sprintf "%s_%s", $self->name, $type;
387              
388 172         353 return $name;
389             }
390              
391             sub _add_inflator {
392 10     10   22 my ($self) = @_;
393              
394 10         284 $self->inflator( {
395             type => "DateTime",
396             parser => { strptime => $self->strftime, },
397             strptime => $self->strftime,
398             } );
399              
400 10         38 return;
401             }
402              
403             sub field_order {
404 173     173 1 265 my ( $self, @order ) = @_;
405              
406 173 100       353 if ( @_ > 1 ) {
407 60 50 33     335 if ( @order == 1 && ref( $order[0] ) eq 'ARRAY' ) {
408 60         65 @order = @{ $order[0] };
  60         137  
409             }
410              
411 60         105 for my $field (@order) {
412             croak "unknown field type: '$field'"
413 206 100   486   455 if none { $field eq $_ } @{ $self->_known_fields };
  486         926  
  206         4928  
414             }
415              
416 59 100       522 croak 'repeated field type'
417             if scalar( uniq @order ) != scalar(@order);
418              
419 58         142 $self->{field_order} = \@order;
420              
421 58         153 return $self;
422             }
423             else {
424 113         300 return $self->{field_order};
425             }
426             }
427              
428             sub process {
429 47     47 0 75 my ( $self, @args ) = @_;
430              
431 47         173 $self->_add_elements;
432              
433 47         405 return $self->SUPER::process(@args);
434             }
435              
436             sub process_input {
437 18     18 0 25 my ( $self, $input ) = @_;
438              
439 18         21 my %value;
440              
441 18         26 my @order = @{ $self->field_order };
  18         54  
442              
443 18         56 for my $i ( 0 .. $#order ) {
444 63         68 my $field = $order[$i];
445              
446 63         1592 my $name = $self->_elements->[$i]->nested_name;
447              
448 63         199 $value{$field} = $self->get_nested_hash_value( $input, $name );
449             }
450              
451 18 100 100 55   121 if ( ( all {defined} values %value )
  55         125  
452 50     50   103 && all {length} values %value )
453             {
454 14         17 my $dt;
455              
456 14         25 eval {
457 14         35 $dt = DateTime->new( map { $_, $value{$_} } keys %value );
  49         135  
458             };
459              
460 14         3953 my $value;
461              
462 14 100       37 if ($@) {
463 3         107 $value = $self->strftime;
464             }
465             else {
466 11         317 $value = $dt->strftime( $self->strftime );
467             }
468              
469 14         584 $self->set_nested_hash_value( $input, $self->nested_name, $value );
470             }
471              
472 18         126 return $self->SUPER::process_input($input);
473             }
474              
475             sub render_data {
476 47     47 0 166 return shift->render_data_non_recursive(@_);
477             }
478              
479             sub render_data_non_recursive {
480 47     47 0 72 my ( $self, $args ) = @_;
481              
482             my $render = $self->SUPER::render_data_non_recursive( {
483 47 50       73 elements => [ map { $_->render_data } @{ $self->_elements } ],
  179         543  
  47         1364  
484             $args ? %$args : (),
485             } );
486              
487 47         222 return $render;
488             }
489              
490             __PACKAGE__->meta->make_immutable;
491              
492             1;
493              
494             __END__
495              
496             =head1 NAME
497              
498             HTML::FormFu::Element::Date - 3 select menu multi-field
499              
500             =head1 VERSION
501              
502             version 2.05
503              
504             =head1 SYNOPSIS
505              
506             ---
507             elements:
508             - type: Date
509             name: birthdate
510             label: 'Birthdate:'
511             day:
512             prefix: "- Day -"
513             month:
514             prefix: "- Month -"
515             year:
516             prefix: "- Year -"
517             less: 70
518             plus: 0
519             auto_inflate: 1
520              
521              
522             =head1 DESCRIPTION
523              
524             Creates a L<multi|HTML::FormFu::Element::Multi> element containing 3 select
525             menus for the day, month and year.
526              
527             A date element named C<foo> would result in 3 select menus with the names
528             C<foo_day>, C<foo_month> and C<foo_year>. The names can instead be
529             overridden by the C<name> value in L</day>, L</month> and L</year>.
530              
531             This element automatically merges the input parameters from the select
532             menu into a single date parameter (and doesn't delete the individual menu's
533             parameters).
534              
535             =head1 METHODS
536              
537             =head2 default
538              
539             Arguments: DateTime object
540              
541             Arguments: $date_string
542              
543             Accepts either a L<DateTime> object, or a string containing a date, matching
544             the L</strftime> format. Overwrites any default value set in L</day>,
545             L</month> or L</year>.
546              
547             =head2 default_natural
548              
549             Arguments: $date_string
550              
551             - type: Date
552             default_natural: 'today'
553              
554             Accepts a date/time string suitable for passing to
555             L<DateTime::Format::Natural/parse_datetime>.
556              
557             =head2 default_datetime_args
558              
559             - type: Date
560             default_natural: 'today'
561             default_datetime_args:
562             set_time_zone: 'Europe/London'
563              
564             Accepts a hashref of method-names / values that will be called on the
565             L</default> L<DateTime|DateTime> object, before the select fields' values
566             are set from it.
567              
568             =head2 strftime
569              
570             Default Value: "%d-%m-%Y"
571              
572             The format of the date as returned by L<HTML::FormFu/params>, if
573             L</auto_inflate> is not set.
574              
575             If L</auto_inflate> is used, this is still the format that the parameter
576             will be in prior to the DateTime inflator being run; which is
577             what any L<Filters|HTML::FormFu::Filter> and
578             L<Constraints|HTML::FormFu::Constraint> will receive.
579              
580             =head2 day
581              
582             Arguments: \%setting
583              
584             Set values effecting the C<day> select menu. Known keys are:
585              
586             =head3 name
587              
588             Override the auto-generated name of the select menu.
589              
590             =head3 default
591              
592             Set the default value of the select menu
593              
594             =head3 prefix
595              
596             Arguments: $value
597              
598             Arguments: \@values
599              
600             A string or arrayref of strings to be inserted into the start of the select
601             menu.
602              
603             Each value is only used as the label for a select item - the value for each
604             of these items is always the empty string C<''>.
605              
606             =head3 prefix_loc
607              
608             Arguments: $localization_key
609              
610             Arguments: \@localization_keys
611              
612             A localized string or arrayref of localized strings to be inserted into the
613             start of the select menu.
614              
615             Each value is localized and then only used as the label for a select item
616             - the value for each of these items is always the empty string C<''>.
617              
618             Use C<prefix_loc> insted of C<prefix>.
619              
620             =head2 month
621              
622             Arguments: \%setting
623              
624             Set values effecting the C<month> select menu. Known keys are:
625              
626             =head3 name
627              
628             Override the auto-generated name of the select menu.
629              
630             =head3 default
631              
632             Set the default value of the select menu
633              
634             =head3 prefix
635              
636             Arguments: $value
637              
638             Arguments: \@values
639              
640             A string or arrayref of strings to be inserted into the start of the select
641             menu.
642              
643             Each value is only used as the label for a select item - the value for each
644             of these items is always the empty string C<''>.
645              
646             =head3 prefix_loc
647              
648             Arguments: $localization_key
649              
650             Arguments: \@localization_keys
651              
652             A localized string or arrayref of localized strings to be inserted into the
653             start of the select menu.
654              
655             Each value is localized and then only used as the label for a select item
656             - the value for each of these items is always the empty string C<''>.
657              
658             Use C<prefix_loc> insted of C<prefix>.
659              
660             =head3 names
661              
662             Arguments: \@months
663              
664             A list of month names used for the month menu.
665              
666             If not set, the list of month names is obtained from L<DateTime::Locale>
667             using the locale set in L<HTML::FormFu/languages>.
668              
669             =head3 short_names
670              
671             Argument: bool
672              
673             If true (and C<months> is not set) the list of abbreviated month names is
674             obtained from L<DateTime::Locale> using the locale set in
675             L<HTML::FormFu/languages>.
676              
677             =head2 year
678              
679             Arguments: \%setting
680              
681             Set values effecting the C<year> select menu. Known keys are:
682              
683             =head3 name
684              
685             Override the auto-generated name of the select menu.
686              
687             =head3 default
688              
689             Set the default value of the select menu
690              
691             =head3 prefix
692              
693             Arguments: $value
694              
695             Arguments: \@values
696              
697             A string or arrayref of strings to be inserted into the start of the select
698             menu.
699              
700             Each value is only used as the label for a select item - the value for each
701             of these items is always the empty string C<''>.
702              
703             =head3 prefix_loc
704              
705             Arguments: $localization_key
706              
707             Arguments: \@localization_keys
708              
709             A localized string or arrayref of localized strings to be inserted into the
710             start of the select menu.
711              
712             Each value is localized and then only used as the label for a select item
713             - the value for each of these items is always the empty string C<''>.
714              
715             Use C<prefix_loc> insted of C<prefix>.
716              
717             =head3 list
718              
719             Arguments: \@years
720              
721             A list of years used for the year menu.
722              
723             If this is set, C<reference>, C<less> and C<plus> are ignored.
724              
725             =head3 reference
726              
727             Arguments: $year
728              
729             Default Value: the current year, calculated from L<time()|perlfunc/time()>
730              
731             If C<list> is not set, the list is created from the range of
732             C<reference - year_less> to C<reference + year_plus>.
733              
734             =head3 less
735              
736             Arguments: $count
737              
738             Default Value: 0
739              
740             =head3 plus
741              
742             Arguments: $count
743              
744             Default Value: 10
745              
746             =head3 reverse
747              
748             Arguments: bool
749              
750             Default Value: 0
751              
752             If true, the list of years is listed in reverse (decreasing) order.
753              
754             =head2 field_order
755              
756             Arguments: \@fields
757              
758             Default Value: ['day', 'month', 'year']
759              
760             Specify the order of the date fields in the rendered HTML.
761              
762             Not all 3 fields are required. No single field can be used more than once.
763              
764             =head2 auto_inflate
765              
766             If true, a L<DateTime Inflator|HTML::FormFu::Inflator::DateTime> will
767             automatically be added to the element, and it will be given a formatter so
768             that stringification will result in the format specified in L</strftime>.
769              
770             If you require the DateTime Inflator to have a different stringification
771             format to the format used internally by your Filters and Constraints, then
772             you must explicitly add your own DateTime Inflator, rather than using
773             L</auto_inflate>.
774              
775             =head1 CAVEATS
776              
777             Although this element inherits from L<HTML::FormFu::Element::Block>, its
778             behaviour for the methods
779             L<filterE<sol>filters|HTML::FormFu/filters>,
780             L<constraintE<sol>constraints|HTML::FormFu/constraints>,
781             L<inflatorE<sol>inflators|HTML::FormFu/inflators>,
782             L<validatorE<sol>validators|HTML::FormFu/validators> and
783             L<transformerE<sol>transformers|HTML::FormFu/transformers> is more like that of
784             a L<field element|HTML::FormFu::Role::Element::Field>, meaning all processors are
785             added directly to the date element, not to its select-menu child elements.
786              
787             This element's L<get_elements|HTML::FormFu/get_elements> and
788             L<get_all_elements|HTML::FormFu/get_all_elements> are inherited from
789             L<HTML::FormFu::Element::Block>, and so have the same behaviour. However, it
790             overrides the C<get_fields|HTML::FormFu/get_fields> method, such that it
791             returns both itself and its child elements.
792              
793             =head1 SEE ALSO
794              
795             Is a sub-class of, and inherits methods from
796             L<HTML::FormFu::Role::Element::Field>,
797             L<HTML::FormFu::Element::Multi>,
798             L<HTML::FormFu::Element::Block>,
799             L<HTML::FormFu::Element>
800              
801             L<HTML::FormFu>
802              
803             =head1 AUTHOR
804              
805             Carl Franks, C<cfranks@cpan.org>
806              
807             =head1 LICENSE
808              
809             This library is free software, you can redistribute it and/or modify it under
810             the same terms as Perl itself.
811              
812             =cut