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