File Coverage

blib/lib/Rose/HTML/Form/Field/Time.pm
Criterion Covered Total %
statement 44 50 88.0
branch 12 20 60.0
condition 14 24 58.3
subroutine 7 7 100.0
pod 2 2 100.0
total 79 103 76.7


line stmt bran cond sub pod time code
1              
2             use strict;
3 7     7   85649  
  7         22  
  7         201  
4             use Rose::HTML::Object::Errors qw(:time);
5 7     7   390  
  7         13  
  7         45  
6             use base 'Rose::HTML::Form::Field::Text';
7 7     7   40  
  7         13  
  7         1287  
8             our $VERSION = '0.621';
9              
10             __PACKAGE__->add_required_html_attr(
11             {
12             size => 13,
13             });
14              
15             {
16             my($self, $time) = @_;
17              
18 197     197 1 337 no warnings; # undef time okay
19             if($time =~ /^\s*(\d\d?)(?::(\d\d)(?::(\d\d))?)?\s*([ap]\.?m\.?)?\s*$/i)
20 7     7   48 {
  7         21  
  7         2857  
21 197 100       574 my $hour = $1;
22             my $min = $2 || 0;
23 43         102 my $sec = $3 || 0;
24 43   100     118 my $ampm = $4 || '';
25 43   100     111  
26 43   50     114 if($ampm)
27             {
28 43 50       81 $ampm = uc($ampm);
29             $ampm =~ s/[^APM]//g;
30 43         68 }
31 43         85  
32             unless($ampm)
33             {
34 43 50       89 if($hour >= 12)
35             {
36 0 0       0 $hour -= 12 if($hour > 12);
37             $ampm = 'PM';
38 0 0       0 }
39 0         0 else { $ampm = 'AM' }
40             }
41 0         0  
42             return sprintf("%02d:%02d:%02d $ampm", $hour, $min, $sec);
43             }
44 43         240  
45             return $time;
46             }
47 154         264  
48             {
49             my($self) = shift;
50              
51             my $ok = $self->SUPER::validate(@_);
52 7     7 1 17 return $ok unless($ok);
53              
54 7         27 my $time = $self->internal_value;
55 7 50       27  
56             return 1 unless ($time && $time =~ /\S/);
57 7         18  
58             unless($time =~ /^(\d\d):(\d\d):(\d\d) ([AP]M)$/)
59 7 100 66     38 {
60             $self->add_error_id(TIME_INVALID);
61 5 100       16 return 0;
62             }
63 2         19  
64 2         22 my $hour = $1;
65             my $min = $2 || 0;
66             my $sec = $3 || 0;
67 3         8 my $ampm = $4 || '';
68 3   50     7  
69 3   50     8 if($hour > 12 && $ampm)
70 3   50     19 {
71             $self->add_error_id(TIME_INVALID_AMPM);
72 3 100 66     10 return 0;
73             }
74 1         5  
75 1         4 if($hour > 12 || $min > 59 || $sec > 59)
76             {
77             $self->add_error_id(TIME_INVALID);
78 2 50 33     12 return 0;
      33        
79             }
80 0         0  
81 0         0 return 1;
82             }
83              
84 2         8 if(__PACKAGE__->localizer->auto_load_messages)
85             {
86             __PACKAGE__->localizer->load_all_messages;
87             }
88              
89             use utf8; # The __DATA__ section contains UTF-8 text
90              
91             1;
92 7     7   49  
  7         14  
  7         45  
93              
94             [% LOCALE en %]
95              
96             TIME_INVALID = "Invalid time."
97             TIME_INVALID_AMPM = "AM/PM only valid with hours less than 12."
98              
99             [% LOCALE de %]
100              
101             TIME_INVALID = "Ungültige Zeit."
102             TIME_INVALID_AMPM = "AM und PM nur gültig mit Stunden kleiner 12."
103              
104             [% LOCALE fr %]
105              
106             TIME_INVALID = "Heure invalide."
107             TIME_INVALID_AMPM = "AM/PM n'est possible que si l'heure est plus petite que 12."
108              
109             [% LOCALE bg %]
110              
111             TIME_INVALID = "Невалиден час."
112             TIME_INVALID_AMPM = "Използването на AM/PM е разрешено за часове не по-големи от 12."
113              
114             __END__
115              
116             =head1 NAME
117              
118             Rose::HTML::Form::Field::Time - Text field that accepts only valid times and coerces valid input into HH:MM:SS AM/PM format.
119              
120             =head1 SYNOPSIS
121              
122             $field =
123             Rose::HTML::Form::Field::Time->new(
124             label => 'Time',
125             name => 'time',
126             default => '8am');
127              
128             print $field->internal_value; # "08:00:00 PM"
129              
130             $field->input_value('13:00:00 PM');
131              
132             # "AM/PM only valid with hours less than 12"
133             $field->validate or warn $field->error;
134              
135             $field->input_value('blah');
136              
137             # "Invalid time"
138             $field->validate or warn $field->error;
139              
140             $field->input_value('6:30 a.m.');
141              
142             print $field->internal_value; # "06:30:00 AM"
143              
144             print $field->html;
145             ...
146              
147             =head1 DESCRIPTION
148              
149             L<Rose::HTML::Form::Field::Time> is a subclass of L<Rose::HTML::Form::Field::Text> that only allows values that are valid times, which it coerces into the form HH:MM:SS AM/PM. It overrides the L<validate()|Rose::HTML::Form::Field/validate> and L<inflate_value()|Rose::HTML::Form::Field/inflate_value> methods of its parent class.
150              
151             This is a good example of a custom field class that constrains the kinds of inputs that it accepts and coerces all valid input and output to a particular format.
152              
153             =head1 SEE ALSO
154              
155             Other examples of custom fields:
156              
157             =over 4
158              
159             =item L<Rose::HTML::Form::Field::Email>
160              
161             A text field that only accepts valid email addresses.
162              
163             =item L<Rose::HTML::Form::Field::DateTime>
164              
165             Uses inflate/deflate to convert input to a L<DateTime> object.
166              
167             =item L<Rose::HTML::Form::Field::DateTime::Range>
168              
169             A compound field whose internal value consists of more than one object.
170              
171             =item L<Rose::HTML::Form::Field::PhoneNumber::US::Split>
172              
173             A simple compound field that coalesces multiple subfields into a single value.
174              
175             =item L<Rose::HTML::Form::Field::DateTime::Split::MonthDayYear>
176              
177             A compound field that uses inflate/deflate convert input from multiple subfields into a L<DateTime> object.
178              
179             =item L<Rose::HTML::Form::Field::DateTime::Split::MDYHMS>
180              
181             A compound field that includes other compound fields and uses inflate/deflate convert input from multiple subfields into a L<DateTime> object.
182              
183             =back
184              
185             =head1 AUTHOR
186              
187             John C. Siracusa (siracusa@gmail.com)
188              
189             =head1 LICENSE
190              
191             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.