| Rose-HTML-Objects documentation | Contained in the Rose-HTML-Objects distribution. |
Rose::HTML::Form::Field::DateTime - Text field that inflates valid dates and times into DateTime objects.
$field =
Rose::HTML::Form::Field::DateTime->new(
label => 'Date',
name => 'date',
default => '12/31/2002 8pm');
print $field->internal_value; # "2002-12-31T20:00:00"
print $field->output_value; # "2002-12-31 08:00:00 PM"
$field->input_value('blah');
# "Could not parse date: blah"
$field->validate or warn $field->error;
$field->input_value('4/30/1980 5:30 p.m.');
$dt = $field->internal_value; # DateTime object
print $dt->hour; # 17
print $dt->day_name; # Wednesday
print $field->html;
...
Rose::HTML::Form::Field::DateTime is a subclass of Rose::HTML::Form::Field::Text that allows only valid dates as input, which it then coerces to DateTime objects. It overrides the validate(), inflate_value(), and deflate_value() methods of its parent class.
Valid input is converted to the format "YYYY-MM-DD HH:MM:SS AM/PM" on output.
Get or set the date parser object. This object must include a parse_datetime() method that takes a single string as an argument and returns a DateTime object, or undef if parsing fails.
If the parser object has an error() method, it will be called to set the error message after a failed parsing attempt.
The parser object defaults to Rose::DateTime::Parser->new().
Get or set the format string passed to Rose::DateTime::Util's format_date function in order to generate the field's output value. Defaults to "%Y-%m-%d %I:%M:%S %p"
If the parser object has a time_zone() method, this method simply calls it, passing all arguments. Otherwise, undef is returned.
Other examples of custom fields:
A text field that only accepts valid email addresses.
Uses inflate/deflate to coerce input into a fixed format.
A compound field whose internal value consists of more than one object.
A simple compound field that coalesces multiple subfields into a single value.
A compound field that uses inflate/deflate convert input from multiple subfields into a DateTime object.
A compound field that includes other compound fields and uses inflate/deflate convert input from multiple subfields into a DateTime object.
John C. Siracusa (siracusa@gmail.com)
Copyright (c) 2010 by John C. Siracusa. All rights reserved. This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.
| Rose-HTML-Objects documentation | Contained in the Rose-HTML-Objects distribution. |
package Rose::HTML::Form::Field::DateTime; use strict; use Rose::HTML::Object::Errors qw(:field :date); use Rose::DateTime::Util(); use Rose::DateTime::Parser; use base 'Rose::HTML::Form::Field::Text'; our $VERSION = '0.606'; use Rose::Object::MakeMethods::Generic ( 'scalar --get_set_init' => [ 'date_parser', 'output_format', ] ); __PACKAGE__->add_required_html_attr( { size => 25, }); sub init_date_parser { Rose::DateTime::Parser->new() } sub time_zone { my($self) = shift; my $parser = $self->date_parser; return $parser->time_zone(@_) if($parser->can('time_zone')); return undef; } sub inflate_value { my($self, $date) = @_; return undef unless(ref $date || (defined $date && length $date)); my $dt; local $@; eval { $dt = $self->date_parser->parse_datetime($date) }; return $dt; } sub init_output_format { '%Y-%m-%d %I:%M:%S %p' } sub deflate_value { my($self, $date) = @_; return $self->input_value_filtered unless($date); return Rose::DateTime::Util::format_date($date, $self->output_format); } sub validate { my($self) = shift; no warnings 'uninitialized'; if($self->input_value !~ /\S/) { my $ok = $self->SUPER::validate(@_); return $ok unless($ok); } my $date = $self->internal_value; if(UNIVERSAL::isa($date, 'DateTime')) { return $self->validate_with_validator($date) if($self->validator); return 1; } if($self->has_partial_value) { $self->add_error_id(FIELD_PARTIAL_VALUE); return 0; } my $input = $self->input_value_filtered; no warnings 'uninitialized'; return 1 unless(length $input); $date = $self->date_parser->parse_datetime($input); unless(defined $date) { # XXX: Parser errors ar English-only right now... # XXX: ...but it produces some horribly ugly errors. #if($self->locale eq 'en') #{ # $self->add_error($self->date_parser->error) # if($self->date_parser->can('error')); #} #else #{ $self->add_error_id(DATE_INVALID); #} return 0; } die "This should never be reached!"; } if(__PACKAGE__->localizer->auto_load_messages) { __PACKAGE__->localizer->load_all_messages; } use utf8; # The __DATA__ section contains UTF-8 text 1; __DATA__ [% LOCALE en %] DATE_INVALID = "Invalid date." [% LOCALE de %] DATE_INVALID = "Ungültiges Datum." [% LOCALE fr %] DATE_INVALID = "Date invalide." [% LOCALE bg %] DATE_INVALID = "Ðевалидна даÑа." __END__