Subject: | HTML::FormHandler::Field::DateTime deflate method doesn't allow for alternate naming of accessors |
When there are more than one DateTime fields in a form, there is a
namespace conflict on the day/month/year fields.
has_field 'date_of_birth' => (type => 'DateTime');
has_field 'date_of_birth.year' => (type => 'Year');
has_field 'date_of_birth.month' => (type => 'Month');
has_field 'date_of_birth.day' => (type => 'MonthDay');
has_field 'date_of_registration' => (type => 'DateTime');
has_field 'date_of_registration.year' => (type => 'Year');
has_field 'date_of_registration.month' => (type => 'Month');
has_field 'date_of_registration.day' => (type => 'MonthDay');
This can be gotten around by using different compound names, and fixing
the accessor:
has_field 'date_of_birth' => (type => 'DateTime');
has_field 'date_of_birth.dob_year' => (type => 'Year', accessor => 'year');
has_field 'date_of_birth.dob_month' => (type => 'Month', accessor =>
'month');
has_field 'date_of_birth.dob_day' => (type => 'MonthDay', accessor =>
'day');
has_field 'date_of_registration' => (type => 'DateTime');
has_field 'date_of_registration.dor_year' => (type => 'Year', accessor
=> 'year');
has_field 'date_of_registration.dor_month' => (type => 'Month', accessor
=> 'month');
has_field 'date_of_registration.dor_day' => (type => 'MonthDay',
accessor => 'day');
This fixes it for the validate method. However, it breaks within
deflate. Validate knows about accessors, where deflate does not.
I believe that line 19, which currently reads:
my $meth = $field->name;
should actually be:
my $meth = $field->accessor;
see attached file for the complete proposed fix.
Thank you for your time!
Subject: | DateTime.pm |
package HTML::FormHandler::Field::DateTime;
# ABSTRACT: compound DateTime field
use Moose;
extends 'HTML::FormHandler::Field::Compound';
use DateTime;
use Try::Tiny;
our $VERSION = '0.05';
has '+widget' => ( default => 'compound' );
sub deflate {
my ( $self, $value ) = @_;
return $value unless ref $value eq 'DateTime';
my %hash;
foreach my $field ( $self->all_fields ) {
my $meth = $field->accessor;
$hash{$meth} = $value->$meth;
}
return \%hash;
}
sub validate {
my ($self) = @_;
my @dt_parms;
foreach my $child ( $self->all_fields ) {
next unless $child->value;
push @dt_parms, ( $child->accessor => $child->value );
}
# set the value
my $dt;
try {
$dt = DateTime->new(@dt_parms);
}
catch {
$self->add_error('Not a valid DateTime');
};
if( $dt ) {
$self->_set_value($dt);
}
else {
$self->_set_value( {@dt_parms} );
}
}
__PACKAGE__->meta->make_immutable;
use namespace::autoclean;
1;
__END__
=pod
=head1 NAME
HTML::FormHandler::Field::DateTime - compound DateTime field
=head1 VERSION
version 0.32002
=head1 DESCRIPTION
This is a compound field that uses modified field names for the
sub fields instead of using a separate sub-form. Widget type is 'compound'.
If you want to use drop-down select boxes for your DateTime, you
can use fields like:
has_field 'my_date' => ( type => 'DateTime' );
has_field 'my_date.month' => ( type => 'Month' );
has_field 'my_date.day' => ( type => 'MonthDay' );
has_field 'my_date.year' => ( type => 'Year' );
has_field 'my_date.hour' => ( type => 'Hour' );
has_field 'my_date.minute' => ( type => 'Minute' );
If you want simple input fields:
has_field 'my_date' => ( type => 'DateTime' );
has_field 'my_date.month' => ( type => 'Integer', range_start => 1,
range_end => 12 );
has_field 'my_date.day' => ( type => 'Integer', range_start => 1,
range_end => 31 );
=head1 AUTHOR
FormHandler Contributors - see HTML::FormHandler
=head1 COPYRIGHT AND LICENSE
This software is copyright (c) 2010 by Gerda Shank.
This is free software; you can redistribute it and/or modify it under
the same terms as the Perl 5 programming language system itself.
=cut