File Coverage

blib/lib/HTML/Widget/Element.pm
Criterion Covered Total %
statement 85 86 98.8
branch 20 22 90.9
condition 26 35 74.2
subroutine 18 19 94.7
pod 12 12 100.0
total 161 174 92.5


line stmt bran cond sub pod time code
1             package HTML::Widget::Element;
2              
3 88     88   580 use warnings;
  88         177  
  88         2578  
4 88     88   441 use strict;
  88         215  
  88         3160  
5 88     88   446 use base qw/HTML::Widget::Accessor Class::Data::Accessor/;
  88         171  
  88         100431  
6 88     88   88470 use HTML::Element;
  88         210  
  88         855  
7 88     88   2403 use HTML::Widget::Container;
  88         317  
  88         1172  
8 88     88   99661 use NEXT;
  88         269529  
  88         1013  
9 88     88   3624 use Carp qw/croak/;
  88         200  
  88         129045  
10              
11             __PACKAGE__->mk_classaccessor( container_class => 'HTML::Widget::Container' );
12              
13             __PACKAGE__->mk_accessors(qw/name passive allow_filter allow_constraint/);
14             __PACKAGE__->mk_attr_accessors(qw/class/);
15              
16             =head1 NAME
17              
18             HTML::Widget::Element - Element Base Class
19              
20             =head1 SYNOPSIS
21              
22             my $e = $widget->element( $type, $name, {disabled => 'disabled'} );
23             $e->name('bar');
24             $e->class('foo');
25              
26             =head1 DESCRIPTION
27              
28             Element Base Class.
29              
30             =head1 METHODS
31              
32             =head2 new
33              
34             =head2 attributes
35              
36             =head2 attrs
37              
38             Arguments: %attributes
39              
40             Arguments: \%attributes
41              
42             Return Value: $element
43              
44             Arguments: none
45              
46             Return Value: \%attributes
47              
48             Accepts either a list of key/value pairs, or a hash-ref.
49              
50             $e->attributes( $key => $value );
51             $e->attributes( { $key => $value } );
52              
53             Returns the C<$element> object, to allow method chaining.
54              
55             As of v1.10, passing a hash-ref no longer deletes current
56             attributes, instead the attributes are added to the current attributes
57             hash.
58              
59             This means the attributes hash-ref can no longer be emptied using
60             C<< $e->attributes( { } ); >>. Instead, you may use
61             C<< %{ $e->attributes } = (); >>.
62              
63             As a special case, if no arguments are passed, the return value is a
64             hash-ref of attributes instead of the object reference. This provides
65             backwards compatability to support:
66              
67             $e->attributes->{key} = $value;
68              
69             L is an alias for L.
70              
71             =head2 container
72              
73             Arguments: \%attributes
74              
75             Return Value: $container
76              
77             Creates a new $container_class. Defaults to L.
78              
79             =cut
80              
81             sub container {
82 273     273 1 566 my ( $self, $attributes ) = @_;
83 273   100     1379 my $class = $self->container_class || 'HTML::Widget::Container';
84 273         3907 my $file = $class . ".pm";
85 273         1442 $file =~ s{::}{/}g;
86 273         544 eval { require $file };
  273         2994  
87 273 50       1103 croak "Unable to load element container class $class: $@" if $@;
88 273         1458 return $class->new( { passive => $self->passive, %$attributes } );
89             }
90              
91             =head2 id
92              
93             Arguments: $widget
94              
95             Return Value: $id
96              
97             Creates a element id.
98              
99             =cut
100              
101             sub id {
102 430     430 1 736 my ( $self, $w, $id ) = @_;
103 430         1357 my $name = $self->name;
104              
105 430 100 66     3149 return unless defined($name) || defined($id);
106              
107 429   100     1339 return $w->name . '_' . ( $id || $self->name );
108             }
109              
110             =head2 init
111              
112             Arguments: $widget
113              
114             Called once when process() gets called for the first time.
115              
116             =cut
117              
118 197     197 1 472 sub init { }
119              
120             =head2 mk_error
121              
122             Arguments: $widget, \@errors
123              
124             Return Value: $error
125              
126             Creates a new L.
127              
128             =cut
129              
130             sub mk_error {
131 203     203 1 573 my ( $self, $w, $errors ) = @_;
132              
133             return
134 203 100 66     1532 if ( !$w->{empty_errors}
      66        
135             && ( !defined($errors) || !scalar(@$errors) ) );
136              
137 33         68 my $no_render_count = 0;
138 33 100       195 $no_render_count += $_->no_render ? 1 : 0 for @$errors;
139 33 100 100     611 return if !$w->{empty_errors} && $no_render_count == scalar @$errors;
140              
141 29   33     146 my $id = $self->attributes->{id} || $self->id($w);
142 29         340 my $cont_id = $id . '_errors';
143 29         141 my $container = HTML::Element->new(
144             'span',
145             id => $cont_id,
146             class => 'error_messages'
147             );
148 29         983 for my $error (@$errors) {
149 28 50 33     185 next if !$w->{empty_errors} && $error->no_render;
150 28         265 my $e_id = $id . '_error_' . lc( $error->{type} );
151 28         82 my $e_class = lc( $error->{type} . '_errors' );
152 28         118 my $e = HTML::Element->new( 'span', id => $e_id, class => $e_class );
153 28         927 $e->push_content( $error->{message} );
154 28         599 $container->push_content($e);
155             }
156 29         661 return $container;
157             }
158              
159             =head2 mk_input
160              
161             Arguments: $widget, \%attributes, \@errors
162              
163             Return Value: $input_tag
164              
165             Creates a new input tag.
166              
167             =cut
168              
169             sub mk_input {
170 260     260 1 493 my ( $self, $w, $attrs, $errors ) = @_;
171              
172 260         1373 return $self->mk_tag( $w, 'input', $attrs, $errors );
173             }
174              
175             =head2 mk_tag
176              
177             Arguments: $widget, $tagtype, \%attributes, \@errors
178              
179             Return Value: $element_tag
180              
181             Creates a new tag.
182              
183             =cut
184              
185             sub mk_tag {
186 264     264 1 490 my ( $self, $w, $tag, $attrs, $errors ) = @_;
187 264         1079 my $e = HTML::Element->new($tag);
188 264   100     6212 my $id = $self->attributes->{id} || $self->id($w);
189 264         2116 my $type = ref $self;
190 264         1535 $type =~ s/^HTML::Widget::Element:://;
191 264         631 $type =~ s/::/_/g;
192 264   66     797 $self->attributes->{class} ||= lc($type);
193 264 100 100     1361 $e->attr( id => $id ) unless $self->attributes->{id} || $w->{explicit_ids};
194 264         3248 $e->attr( name => $self->name );
195              
196 264         4478 for my $key ( keys %$attrs ) {
197 599         4004 my $value = $attrs->{$key};
198 599 100       2774 $e->attr( $key, $value ) if defined $value;
199             }
200 264         895 $e->attr( $_ => ${ $self->attributes }{$_} )
  346         1698  
201 264         2982 for ( keys %{ $self->attributes } );
202              
203 264         3939 return $e;
204             }
205              
206             =head2 mk_label
207              
208             Arguments: $widget, $name, $comment, \@errors
209              
210             Return Value: $label_tag
211              
212             Creates a new label tag.
213              
214             =cut
215              
216             sub mk_label {
217 240     240 1 2309 my ( $self, $w, $name, $comment, $errors ) = @_;
218 240 100       789 return unless defined $name;
219 102   66     452 my $for = $self->attributes->{id} || $self->id($w);
220 102         787 my $id = $for . '_label';
221 102         598 my $e = HTML::Element->new( 'label', for => $for, id => $id );
222 102 100       3837 if ($errors) {
223 16         75 $e->attr( 'class' => 'labels_with_errors' );
224             }
225 102         720 $e->push_content($name);
226 102 100       2052 if ($comment) {
227 2         9 my $c = HTML::Element->new(
228             'span',
229             id => "$for\_comment",
230             class => 'label_comments'
231             );
232 2         51 $c->push_content($comment);
233 2         24 $e->push_content($c);
234             }
235 102         422 return $e;
236             }
237              
238             =head2 name
239              
240             Arguments: $name
241              
242             Return Value: $name
243              
244             Contains the element name.
245              
246             =head2 passive
247              
248             Arguments: $bool
249              
250             Return Value: $bool
251              
252             Defines if element gets automatically rendered.
253              
254             =head2 prepare
255              
256             Arguments: $widget
257              
258             Called whenever C<< $widget->process >> gets called, before
259             C<< $element->process >>.
260              
261             =cut
262              
263 428     428 1 1316 sub prepare { }
264              
265             =head2 process
266              
267             Arguments: \%params, \@uploads
268              
269             Return Value: \@errors
270              
271             Called whenever C<< $widget->process >> is called.
272              
273             Returns an arrayref of L objects.
274              
275             =cut
276              
277 322     322 1 695 sub process { }
278              
279             =head2 containerize
280              
281             Arguments: $widget, $value, \@errors
282              
283             Return Value: $container_tag
284              
285             Containerize the element, label and error for later rendering.
286             Uses L by default, but this can be over-ridden on
287             a class or instance basis via L.
288              
289             =cut
290              
291 0     0 1 0 sub containerize { }
292              
293             =head2 container_class
294              
295             Arguments: $class
296              
297             Return Value: $class
298              
299             Contains the class to use for contain the element which then get rendered. Defaults to L. C can be set at a class or instance level:
300              
301             HTML::Widget::Element->container_class('My::Container');
302             # Override default to custom class
303            
304             HTML::Widget::Element::Password->container_class(undef);
305             # Passwords use the default class
306            
307             $w->element('Textfield')->name('foo')->container_class->('My::Other::Container');
308             # This element only will use My::Other::Container to render
309              
310             =cut
311              
312             sub container_class {
313             my ($self) = shift;
314              
315             if ( not $_[0] and @_ >= 1 ) {
316             delete $self->{container_class};
317             }
318              
319             return $self->_container_class_accessor(@_);
320             }
321              
322             =head2 find_elements
323              
324             Return Value: \@elements
325              
326             For non-block-container elements, simply returns a one-element list
327             containing this element.
328              
329             =cut
330              
331 412     412 1 1051 sub find_elements { return (shift); }
332              
333             =head2 new
334              
335             =cut
336              
337             sub new {
338 314     314 1 45976 return shift->NEXT::new(@_)->allow_filter(1)->allow_constraint(1);
339             }
340              
341             =head2 allow_filter
342              
343             Used by C<< $widget->filter_all >>. If false, the filter won't be added.
344              
345             Default true.
346              
347             =head2 allow_constraint
348              
349             Used by C<< $widget->constraint_all >>. If false, the filter won't be added.
350              
351             Default true.
352              
353             =head1 AUTHOR
354              
355             Sebastian Riedel, C
356              
357             =head1 LICENSE
358              
359             This library is free software, you can redistribute it and/or modify it under
360             the same terms as Perl itself.
361              
362             =cut
363              
364             1;