package HTML::Widget::Container; use warnings; use strict; use base 'Class::Accessor::Fast'; __PACKAGE__->mk_accessors(qw/element label error javascript passive name/); use overload '""' => sub { return shift->as_xml }, fallback => 1; *js = \&javascript; *js_xml = \&javascript_xml; *field = \&element; *field_xml = \&element_xml; =head1 NAME HTML::Widget::Container - Container =head1 SYNOPSIS my $container = $form->element('foo'); my $field = $container->field; my $error = $container->error; my $label = $container->label; my $field_xml = $container->field_xml; my $error_xml = $container->error_xml; my $javascript_xml = $container->javascript_xml; my $xml = $container->as_xml; # $xml eq "$container" my $javascript = $container->javascript; =head1 DESCRIPTION Container. =head1 METHODS =head2 as_xml Return Value: $xml =cut sub as_xml { my $self = shift; my $xml = ''; $xml .= $self->element_xml if $self->element; $xml .= $self->javascript_xml if $self->javascript; $xml .= $self->error_xml if $self->error; return $xml; } =head2 _build_element Arguments: $element Return Value: @elements Convert $element to L object. Accepts arrayref. If you wish to change the rendering behaviour of HTML::Widget; specifically, the handling of elements which are array-refs, you can specify L to a custom class which just overrides this function. =cut sub _build_element { my ( $self, $element ) = @_; return () unless $element; if ( ref $element eq 'ARRAY' ) { return map { $self->_build_element($_) } @{$element}; } return $self->build_single_element( $element->clone ); } =head2 build_single_element Arguments: $element Return Value: $element Convert $element to L object. Called by L. If you wish to change the rendering behaviour of HTML::Widget; specifically, the handling of an individual element, you can override this function. =cut sub build_single_element { my ( $self, $element ) = @_; my $class = $element->attr('class') || ''; $element = $self->build_element_error($element); $element = $self->build_element_label( $element, $class ); return $element; } =head2 build_element_error Arguments: $element Return Value: $element Called by L. If you wish to change how an error is rendered, override this function. =cut sub build_element_error { my ( $self, $element ) = @_; if ( $self->error && $element->tag eq 'input' ) { $element = HTML::Element->new( 'span', class => 'fields_with_errors' ) ->push_content($element); } return $element; } =head2 build_element_label Arguments: $element, $class Return Value: $element Called by L. If you wish to change how an element's label is rendered, override this function. The $class argument is the original class of the element, before L was called. =cut sub build_element_label { my ( $self, $element, $class ) = @_; return $element unless defined $self->label; my $l = $self->label->clone; my $radiogroup; if ( $class eq 'radiogroup_fieldset' ) { $element->unshift_content($l); $radiogroup = 1; } elsif ( $self->error && $element->tag eq 'span' ) { # it might still be a radiogroup wrapped in an error span for my $elem ( $element->content_refs_list ) { next unless ref $$elem; if ( $$elem->attr('class') eq 'radiogroup_fieldset' ) { $$elem->unshift_content($l); $radiogroup = 1; } } } if ( !$radiogroup ) { # Do we prepend or append input to label? $element = ( $class eq 'checkbox' or $class eq 'radio' ) ? $l->unshift_content($element) : $l->push_content($element); } return $element; } =head2 as_list Return Value: @elements Returns a list of L objects. =cut sub as_list { my $self = shift; my @list; push @list, $self->_build_element( $self->element ); push @list, $self->javascript_element if $self->javascript; push @list, $self->error if $self->error; return @list; } =head2 element =head2 field Arguments: $element L is an alias for L. =head2 element_xml =head2 field_xml Return Value: $xml L is an alias for L. =cut sub element_xml { my $self = shift; my @e = $self->_build_element; return join( '', map( { $_->as_XML } $self->_build_element( $self->element ) ) ) || ''; } =head2 error Arguments: $error Return Value: $error =head2 error_xml Return Value: $xml =cut sub error_xml { my $self = shift; return $self->error ? $self->error->as_XML : ''; } =head2 javascript =head2 js Arguments: $javascript Return Value: $javascript L is an alias for L. =head2 javascript_element Return Value: $javascript_element Returns javascript in a script L. =cut sub javascript_element { my $self = shift; my $script = HTML::Element->new( 'script', type => 'text/javascript' ); my $content = "\n\n"; my $literal = HTML::Element->new( '~literal', text => $content ); $script->push_content($literal); return $script; } =head2 javascript_xml =head2 js_xml Return Value: $javascript_xml Returns javascript in a script block. L is an alias for L. =cut sub javascript_xml { my $self = shift; return $self->javascript_element->as_HTML('<>&'); } =head1 AUTHOR Sebastian Riedel, C =head1 LICENSE This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1;