package HTML::FormHandler::Widget::Block; # ABSTRACT: base block renderer $HTML::FormHandler::Widget::Block::VERSION = '0.40068'; use Moose; with 'HTML::FormHandler::TraitFor::Types'; use HTML::FormHandler::Render::Util ('process_attrs'); use HTML::FormHandler::Field; has 'name' => ( is => 'ro', isa => 'Str', required => 1 ); has 'form' => ( is => 'ro', isa => 'HTML::FormHandler', required => 1, weak_ref => 1, ); has 'class' => ( is => 'rw', isa => 'HFH::ArrayRefStr', traits => ['Array'], builder => 'build_class', handles => { has_class => 'count', add_class => 'push', } ); sub build_class { [] } has 'attr' => ( is => 'rw', traits => ['Hash'], builder => 'build_attr', handles => { has_attr => 'count', set__attr => 'set', delete__attr => 'delete' }, ); sub build_attr { {} } has 'wrapper' => ( is => 'rw', isa => 'Bool', default => 1 ); has 'tag' => ( is => 'rw', isa => 'Str', default => 'div' ); has 'label' => ( is => 'rw', isa => 'Str', predicate => 'has_label' ); has 'label_tag' => ( is => 'rw', isa => 'Str' ); has 'label_class' => ( is => 'rw', isa => 'HFH::ArrayRefStr', traits => ['Array'], builder => 'build_label_class', handles => { has_label_class => 'count', add_label_class => 'push', } ); sub build_label_class { [] } has 'render_list' => ( is => 'rw', isa => 'ArrayRef[Str]', lazy => 1, traits => ['Array'], builder => 'build_render_list', handles => { has_render_list => 'count', add_to_render_list => 'push', all_render_list => 'elements', get_render_list => 'get', } ); has 'build_render_list_method' => ( is => 'rw', isa => 'CodeRef', traits => ['Code'], handles => {'build_render_list' => 'execute_method'}, default => sub { \&default_build_render_list }, ); sub default_build_render_list { [] } has 'content' => ( is => 'rw' ); has 'after_plist' => ( is => 'rw' ); sub render { my ( $self, $result ) = @_; $result ||= $self->form->result; my $start_wrapper = ''; my $end_wrapper = ''; if( $self->wrapper ) { my $tag = $self->tag; # create attribute string my $attr_str = $self->render_attribute_string; $start_wrapper = qq{<$tag$attr_str>}; $end_wrapper = qq{}; } # get rendering of contained fields, if any my $rendered_fb = $self->render_from_list($result); my $content = $self->content || ''; my $after_plist = $self->after_plist || ''; # create label my $label = $self->render_label; my $block = qq{\n$start_wrapper$label$content$rendered_fb$after_plist$end_wrapper}; } sub render_attribute_string { my $self = shift; my $attr = { %{ $self->attr } }; $attr->{class} = $self->class if $self->has_class; my $attr_str = process_attrs($attr); return $attr_str; } sub render_label { my $self = shift; my $label = ''; if ( $self->has_label ) { my $label_tag = $self->label_tag || 'span'; $label_tag = 'legend' if lc $self->tag eq 'fieldset'; my $label_str = $self->form->_localize( $self->label ); my $attr_str = ''; $attr_str = process_attrs( { class => $self->label_class } ) if $self->has_label_class; $label = qq{<$label_tag$attr_str>$label_str}; } return $label; } sub render_from_list { my ( $self, $result ) = @_; my $output = ''; if ( $self->has_render_list ) { foreach my $fb ( @{ $self->render_list } ) { # it's a Field if ( $self->form->field_in_index($fb) ) { # find field result and use that my $fld_result = $result->get_result($fb); # if no result, then we shouldn't be rendering this field next unless $fld_result; $output .= $fld_result->render; } # it's a Block else { # block can't be called from a field, so this should # always be the for result my $block = $self->form->block($fb); die "found no form field or block named '$fb'\n" unless $block; $output .= $block->render($result); } } } # else nothing to render from render_list return $output; } 1; __END__ =pod =encoding UTF-8 =head1 NAME HTML::FormHandler::Widget::Block - base block renderer =head1 VERSION version 0.40068 =head1 SYNOPSIS Base block renderer to be used with L. has_block 'my_fieldset' => ( tag => 'fieldset', render_list => ['bar'], label => 'My Special Bar' ); =head1 ATTRIBUTES =over 4 =item render_list List of names of objects to render (fields and blocks) =item build_render_list_method Coderef for constructing the list of names of objects to render (fields and blocks) =item tag HTML tag for this block. Default 'div'. =item class Arrayref of classes for the HTML element. =item attr Other attributes for the HTML element. =item label_tag Tag to use for the label. Default: 'span'; default for 'fieldset' is 'legend'. =item label_class Classes for the label. =item label Label string. Will be localized. =back =head1 AUTHOR FormHandler Contributors - see HTML::FormHandler =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2017 by Gerda Shank. This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut