webgui/lib/WebGUI/FormBuilder/Role/HasObjects.pm
2011-12-28 11:30:38 -08:00

181 lines
5.2 KiB
Perl

package WebGUI::FormBuilder::Role::HasObjects;
=head1 LEGAL
-------------------------------------------------------------------
WebGUI is Copyright 2001-2012 Plain Black Corporation.
-------------------------------------------------------------------
Please read the legal notices (docs/legal.txt) and the license
(docs/license.txt) that came with this distribution before using
this software.
-------------------------------------------------------------------
http://www.plainblack.com info@plainblack.com
-------------------------------------------------------------------
=cut
use WebGUI::BestPractices;
use Moose::Role;
has 'objects' => (
is => 'rw',
isa => 'ArrayRef',
default => sub { [] },
);
# Objects combines "fields", "fieldsets", and "tabsets"
=head1 NAME
Package WebGUI::FormBuilder::Role::HasObjects
=head1 DESCRIPTION
Role that provides an attribute for holding a set of objects.
=head1 SYNOPSIS
This method is used by several FormBuilder packages that need to nest objects. For example, a FormBuilder object
can have multiple tabs, each of which can contain multiple form fields. The role provides an objects attribute,
and an addObject method for pushing an object onto the list of objects.
with 'WebGUI::FormBuilder::Role::HasObjects';
=head1 METHODS
=head2 addObject ($object)
Adds $object to the list of objects for the consumer.
=head3 $object
Some variable, or data. It really can be anything.
=cut
sub addObject {
my ( $self, $object ) = @_;
push @{$self->objects}, $object;
return $object;
}
=head2 addObjectAt ( $object, $position )
Adds $object to the list of objects at a certain position, pushing all other
objects down.
=head3 $object
Some object
=head3 $position
The numeric index. 0 is the first object.
=cut
sub addObjectAt {
my ( $self, $object, $position ) = @_;
splice @{$self->objects}, $position, 0, $object;
return $object;
}
=head2 process ( )
Process the form and return a hashref of values.
=cut
sub process {
my ( $self ) = @_;
my $values = {};
for my $obj ( @{$self->objects} ) {
if ( $obj->isa( 'WebGUI::Form::Control' ) ) {
$values->{ $obj->get('name') } = $obj->getValue;
}
elsif ( $obj->does( 'WebGUI::FormBuilder::Role::HasObjects' ) ) {
my $merge = $obj->process;
for my $key ( keys %$merge ) {
if ( $values->{ $key } ) {
if ( !ref $values->{ $key } ) {
$values->{ $key } = [ $values->{ $key } ];
}
push @{ $values->{ $key } }, $merge->{ $key };
}
else {
$values->{ $key } = $merge->{ $key };
}
}
}
}
return $values;
}
=head2 toTemplateVars ( prefix, var )
Get all the objects as a set of template vars with the given prefix. $var is
an optional hashref to add the variables to.
=cut
sub toTemplateVars {
my ( $self, $prefix, $var ) = @_;
$prefix ||= "";
$var ||= {};
# Loop over all objects, adding to appropriate template loops
for my $obj ( @{ $self->objects } ) {
# Prepare our object's variables and add to object type loop
my $props = {};
given ( blessed $obj ) {
when ( undef ) {
# Treat as raw template properties
$props = $obj;
}
when ( $_->isa( 'WebGUI::FormBuilder::Tabset' ) ) {
my $name = $obj->name;
$props = $obj->toTemplateVars;
$props->{ isTabset } = 1;
for my $key ( keys %{$props} ) {
$var->{ "${prefix}tabset_${name}_${key}" } = $props->{$key};
}
push @{$var->{ "${prefix}tabsetloop" }}, $props;
}
when ( $_->isa( 'WebGUI::FormBuilder::Fieldset' ) ) {
my $name = $obj->name;
$props = $obj->toTemplateVars;
$props->{ isFieldset } = 1;
for my $key ( keys %{$props} ) {
$var->{ "${prefix}fieldset_${name}_${key}" } = $props->{$key};
}
push @{$var->{ "${prefix}fieldsetloop" }}, $props;
}
# Form field objects
when ( $_->isa( 'WebGUI::Form::Control' ) ) {
my $name = $obj->get('name') || '';
$props = $obj->toTemplateVars;
# Add the whole field to the vars
$props->{ field } = $obj->toHtmlWithWrapper;
$props->{ field_input } = $obj->toHtml;
$var->{ "${prefix}field_${name}" } = $props->{ field };
# Add to fieldloop
push @{$var->{"${prefix}fieldloop"}}, $props;
# Individual accessors
for my $key ( keys %{$props} ) {
$var->{ "${prefix}field_${name}_${key}" } = $props->{$key};
}
# Loop accessor
push @{$var->{ "${prefix}field_${name}_loop" }}, $props;
}
}
# Add to the global object loop
push @{ $var->{ "${prefix}objects" } }, $props;
}
return $var;
}
1;