File Coverage

blib/lib/HTML/Widget/Element/Select.pm
Criterion Covered Total %
statement 57 58 98.2
branch 19 22 86.3
condition 11 11 100.0
subroutine 7 7 100.0
pod 3 3 100.0
total 97 101 96.0


line stmt bran cond sub pod time code
1             package HTML::Widget::Element::Select;
2              
3 88     88   72795 use warnings;
  88         189  
  88         2719  
4 88     88   481 use strict;
  88         185  
  88         3003  
5 88     88   629 use base 'HTML::Widget::Element';
  88         191  
  88         7498  
6 88     88   569 use HTML::Widget::Error;
  88         231  
  88         1296  
7              
8             *value = \&selected;
9             *constrain_values = \&constrain_options;
10              
11             __PACKAGE__->mk_accessors(
12             qw/comment label multiple options selected constrain_options
13             retain_default/
14             );
15              
16             __PACKAGE__->mk_attr_accessors(qw/size/);
17              
18             =head1 NAME
19              
20             HTML::Widget::Element::Select - Select Element
21              
22             =head1 SYNOPSIS
23              
24             my $e = $widget->element( 'Select', 'foo' );
25             $e->comment('(Required)');
26             $e->label('Foo');
27             $e->size(23);
28             $e->options( foo => 'Foo', bar => 'Bar' );
29             $e->selected(qw/foo bar/);
30             $e->constrain_options(1);
31              
32             =head1 DESCRIPTION
33              
34             Select Element.
35              
36             As of version 1.09, an L is no
37             longer automatically added to Select elements. Use L to
38             provide this functionality.
39              
40             =head1 METHODS
41              
42             =head2 comment
43              
44             Add a comment to this Element's label.
45              
46             =head2 label
47              
48             This label will be placed next to your Element.
49              
50             =head2 size
51              
52             If set to 1, the select element is displayed as a pop-up menu, otherwise the
53             element is displayed as a list box, with the size determining the display
54             height in rows. The default size is 1.
55              
56             =head2 multiple
57              
58             $widget->element( 'Select', 'foo' )->multiple( 1 );
59              
60             If the multiple attribute is set, the select element is rendered as a list
61             box, and the user may select multiple options.
62              
63             If the size is not set, the default size (height) is the number of elements.
64             If the size is set to 1, the element is rendered as a pop-up menu.
65              
66             =head2 options
67              
68             A list of options in key => value format. Each key is the unique id of an
69             option tag, and its corresponding value is the text displayed in the element.
70              
71             =head2 selected
72              
73             =head2 value
74              
75             A list of keys (unique option ids) which will be pre-set to "selected".
76             Can also be addressed as value for consistency with the other elements
77              
78             L is an alias for L.
79              
80             =head2 constrain_options
81              
82             =head2 constrain_values
83              
84             If true, an L will
85             automatically be added to the widget, using the key names from L.
86              
87             L is an alias for L.
88              
89             =head2 retain_default
90              
91             If true, overrides the default behaviour, so that after a field is missing
92             from the form submission, the xml output will contain the default value,
93             rather than be empty.
94              
95             =head2 prepare
96              
97             =cut
98              
99             sub prepare {
100 21     21 1 44 my ( $self, $w, $value ) = @_;
101              
102 21 100       97 if ( $self->constrain_values ) {
103 3         37 my $name = $self->name;
104              
105 3 50       24 my %options = @{ $self->options } if ( ref $self->options );
  3         138  
106              
107 3         43 my @uniq = keys %options;
108              
109 3 50       24 $w->constraint( 'In', $name )->in(@uniq)
110             if @uniq;
111             }
112              
113 21         206 return;
114             }
115              
116             =head2 process
117              
118             =cut
119              
120             sub process {
121 10     10 1 36 my ( $self, $params, $uploads ) = @_;
122              
123 10         17 my $errors;
124 10         55 my $name = $self->name;
125              
126             # only allow multiple values is multiple() is true
127 10 100 100     98 if ( !$self->multiple() && ref $params->{$name} eq 'ARRAY' ) {
128 1         30 push @$errors,
129             HTML::Widget::Error->new( {
130             name => $name,
131             type => 'Multiple',
132             message => 'Multiple Selections Not Allowed',
133             } );
134             }
135 10         152 return $errors;
136             }
137              
138             =head2 containerize
139              
140             =cut
141              
142             sub containerize {
143 18     18 1 43 my ( $self, $w, $value, $errors, $args ) = @_;
144              
145 18         65 my $options = $self->options;
146 18 100       171 my @options = ref $options eq 'ARRAY' ? @$options : ();
147 18         31 my @o;
148             my @values;
149 18 100 100     72 if ( defined $value ) {
    100          
150 7 100       29 @values = ref $value eq 'ARRAY' ? @$value : ($value);
151             }
152             elsif ( $self->retain_default || !$args->{submitted} ) {
153 0         0 @values =
154             ref $self->selected eq 'ARRAY'
155 10 50       119 ? @{ $self->selected }
156             : ( $self->selected );
157             }
158              
159             # You might be tempted to say 'while ( my $key = shift( @temp_options ) )'
160             # here, but then that falls if the first element is a 0 :-) So we do the
161             # following bit of nastiness instead:
162              
163 18         171 my @temp_options = @options;
164 18         57 while ( scalar @temp_options ) {
165              
166 33         53 my $key = shift(@temp_options);
167 33         52 my $value = shift(@temp_options);
168 33         120 my $option = HTML::Element->new( 'option', value => $key );
169 33         911 for my $val (@values) {
170 33 100 100     187 if ( ( defined $val ) && ( $val eq $key ) ) {
171 14         47 $option->attr( selected => 'selected' );
172 14         169 last;
173             }
174             }
175 33         107 $option->push_content($value);
176 33         495 push @o, $option;
177             }
178              
179 18         72 my $label = $self->mk_label( $w, $self->label, $self->comment, $errors );
180              
181 18   100     78 $self->attributes->{class} ||= 'select';
182 18         64 my $selectelm = HTML::Element->new('select');
183 18         376 $selectelm->push_content(@o);
184              
185             # if ($label) {
186             # $label->push_content($selectelm);
187             # }
188             #
189             # $l ? ( $l->push_content($i) ) : ( $l = $i );
190              
191 18         405 my $id = $self->id($w);
192 18         181 $selectelm->attr( id => $id );
193 18         238 $selectelm->attr( name => $self->name );
194              
195 18 100       290 $selectelm->attr( multiple => 'multiple' )
196             if $self->multiple;
197              
198 18         56 $selectelm->attr( $_ => ${ $self->attributes }{$_} )
  20         82  
199 18         138 for ( keys %{ $self->attributes } );
200              
201             # $l->push_content($i);
202              
203 18         737 my $e = $self->mk_error( $w, $errors );
204              
205 18         139 return $self->container(
206             { element => $selectelm, error => $e, label => $label } );
207             }
208              
209             =head1 SEE ALSO
210              
211             L
212              
213             =head1 AUTHOR
214              
215             Sebastian Riedel, C
216              
217             =head1 LICENSE
218              
219             This library is free software, you can redistribute it and/or modify it under
220             the same terms as Perl itself.
221              
222             =cut
223              
224             1;