File Coverage

blib/lib/Rose/HTML/Form/Field/PhoneNumber/US/Split.pm
Criterion Covered Total %
statement 31 33 93.9
branch 4 6 66.6
condition 0 6 0.0
subroutine 10 10 100.0
pod 5 5 100.0
total 50 60 83.3


line stmt bran cond sub pod time code
1             package Rose::HTML::Form::Field::PhoneNumber::US::Split;
2              
3 2     2   1632 use strict;
  2         6  
  2         58  
4              
5 2     2   10 use Carp();
  2         4  
  2         32  
6              
7 2     2   11 use Rose::HTML::Form::Field::Text;
  2         4  
  2         26  
8              
9 2         899 use base qw(Rose::HTML::Form::Field::Compound
10 2     2   11 Rose::HTML::Form::Field::PhoneNumber::US);
  2         4  
11              
12             # Multiple inheritence never quite works out the way I want it to...
13             Rose::HTML::Form::Field::PhoneNumber::US->import_methods
14             (
15             'validate',
16             'inflate_value',
17             'deflate_value',
18             );
19              
20             Rose::HTML::Form::Field::Compound->import_methods
21             (
22             'name',
23             );
24              
25             our $VERSION = '0.606';
26              
27             sub build_field
28             {
29 1     1 1 4 my($self) = shift;
30              
31 1         16 $self->add_fields
32             (
33             area_code => { type => 'text', size => 3, maxlength => 3, class => 'area-code' },
34             exchange => { type => 'text', size => 3, maxlength => 3, class => 'exchange' },
35             number => { type => 'text', size => 4, maxlength => 4, class => 'number' },
36             );
37             }
38              
39             sub decompose_value
40             {
41 17     17 1 34 my($self, $value) = @_;
42              
43 17 100       58 return undef unless(defined $value);
44              
45 5         18 my $phone = $self->inflate_value($value);
46              
47 5 50       16 unless($phone)
48             {
49 0         0 $phone =~ s/[- ]+//g;
50              
51 2     2   18 no warnings;
  2         4  
  2         694  
52             return
53             {
54 0   0     0 area_code => substr($phone, 0, 3) || '',
      0        
      0        
55             exchange => substr($phone, 3, 6) || '',
56             number => substr($phone, 6, 4) || '',
57             }
58             }
59              
60 5         19 $phone =~ /^(\d{3})-(\d{3})-(\d{4})$/;
61              
62              
63             return
64             {
65 5         54 area_code => $1,
66             exchange => $2,
67             number => $3,
68             };
69             }
70              
71             sub coalesce_value
72             {
73 1     1 1 3 my($self) = shift;
74 3 50       13 return join('-', map { defined($_) ? $_ : '' }
75 1         3 map { $self->field($_)->internal_value } qw(area_code exchange number));
  3         8  
76             }
77              
78             sub html_field
79             {
80 2     2 1 690 my($self) = shift;
81              
82 2         8 return '<span class="phone">' .
83             $self->field('area_code')->html_field . '-' .
84             $self->field('exchange')->html_field . '-' .
85             $self->field('number')->html_field .
86             '</span>';
87             }
88              
89             sub xhtml_field
90             {
91 1     1 1 4 my($self) = shift;
92              
93 1         4 return '<span class="phone">' .
94             $self->field('area_code')->xhtml_field . '-' .
95             $self->field('exchange')->xhtml_field . '-' .
96             $self->field('number')->xhtml_field .
97             '</span>';
98             }
99              
100             1;
101              
102             __END__
103              
104             =head1 NAME
105              
106             Rose::HTML::Form::Field::PhoneNumber::US::Split - Compound field for US phone numbers with separate fields for area code, exchange, and number.
107              
108             =head1 SYNOPSIS
109              
110             $field =
111             Rose::HTML::Form::Field::PhoneNumber::US::Split->new(
112             label => 'Phone',
113             name => 'phone',
114             default => '123-321-1234');
115              
116             print $field->field('area_code')->internal_value; # "123"
117              
118             $field->input_value('555-5555');
119              
120             # "Phone number must be 10 digits, including area code"
121             $field->validate or warn $field->error;
122              
123             $field->input_value('(555) 456-7890');
124              
125             print $field->field('exchange')->internal_value; # "456"
126             print $field->internal_value; # "555-456-7890"
127              
128             print $field->html;
129             ...
130              
131             =head1 DESCRIPTION
132              
133             L<Rose::HTML::Form::Field::PhoneNumber::US::Split> is a compound field that contains three separate text fields for US phone numbers: one each for area code, exchange, and number. It inherits from both L<Rose::HTML::Form::Field::PhoneNumber::US> and L<Rose::HTML::Form::Field::Compound>. It overrides the following methods: L<build_field()|Rose::HTML::Form::Field::Compound/build_field>, L<coalesce_value()|Rose::HTML::Form::Field::Compound/coalesce_value>, L<decompose_value()|Rose::HTML::Form::Field::Compound/decompose_value>, L<html_field()|Rose::HTML::Form::Field/html_field>, and L<xhtml_field()|Rose::HTML::Form::Field/xhtml_field>.
134              
135             This is a good example of a compound field that combines separate fields into a single value through simple concatenation (plus a separator character). By inheriting from L<Rose::HTML::Form::Field::PhoneNumber::US>, it gets the validation and inflate/deflate features "for free", leaving it to concentrate on the coalesce/decompose features and the building and printing of the separate fields that make up the compound field.
136              
137             It is important that this class inherits from L<Rose::HTML::Form::Field::Compound>. See the L<Rose::HTML::Form::Field::Compound> documentation for more information.
138              
139             =head1 SEE ALSO
140              
141             Other examples of custom fields:
142              
143             =over 4
144              
145             =item L<Rose::HTML::Form::Field::Email>
146              
147             A text field that only accepts valid email addresses.
148              
149             =item L<Rose::HTML::Form::Field::Time>
150              
151             Uses inflate/deflate to coerce input into a fixed format.
152              
153             =item L<Rose::HTML::Form::Field::DateTime>
154              
155             Uses inflate/deflate to convert input to a L<DateTime> object.
156              
157             =item L<Rose::HTML::Form::Field::DateTime::Range>
158              
159             A compound field whose internal value consists of more than one object.
160              
161             =item L<Rose::HTML::Form::Field::DateTime::Split::MonthDayYear>
162              
163             A compound field that uses inflate/deflate convert input from multiple subfields into a L<DateTime> object.
164              
165             =item L<Rose::HTML::Form::Field::DateTime::Split::MDYHMS>
166              
167             A compound field that includes other compound fields and uses inflate/deflate convert input from multiple subfields into a L<DateTime> object.
168              
169             =back
170              
171             =head1 AUTHOR
172              
173             John C. Siracusa (siracusa@gmail.com)
174              
175             =head1 LICENSE
176              
177             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.