HTML-FormHandler
view release on metacpan or search on metacpan
lib/HTML/FormHandler.pm view on Meta::CPAN
with 'HTML::FormHandler::Blocks';
use Carp;
use Class::MOP;
use HTML::FormHandler::Result;
use HTML::FormHandler::Field;
use Try::Tiny;
use MooseX::Types::LoadableClass qw/ LoadableClass /;
use namespace::autoclean;
use HTML::FormHandler::Merge ('merge');
use Sub::Name;
use Data::Clone;
use 5.008;
# for consistency in api with field nodes
sub form { shift }
sub is_form { 1 }
sub has_form { 1 }
# Moose attributes
has 'name' => (
isa => 'Str',
is => 'rw',
default => sub { return 'form' . int( rand 1000 ) }
);
sub full_name { '' }
sub full_accessor { '' }
has 'parent' => ( is => 'rw' );
has 'result' => (
isa => 'HTML::FormHandler::Result',
is => 'ro',
writer => '_set_result',
clearer => 'clear_result',
lazy => 1,
builder => 'build_result',
predicate => 'has_result',
handles => [
'input', '_set_input', '_clear_input', 'has_input',
'value', '_set_value', '_clear_value', 'has_value',
'add_result', 'results', 'validated', 'ran_validation',
'is_valid',
'form_errors', 'all_form_errors', 'push_form_errors', 'clear_form_errors',
'has_form_errors', 'num_form_errors',
],
);
sub build_result {
my $self = shift;
my $result_class = 'HTML::FormHandler::Result';
if ( $self->widget_form ) {
my $role = $self->get_widget_role( $self->widget_form, 'Form' );
$result_class = $result_class->with_traits( $role );
}
my $result = $result_class->new( name => $self->name, form => $self );
return $result;
}
has 'index' => (
is => 'ro', isa => 'HashRef[HTML::FormHandler::Field]', traits => ['Hash'],
default => sub {{}},
handles => {
add_to_index => 'set',
field_from_index => 'get',
field_in_index => 'exists',
}
);
has '_repeatable_fields' => ( is => 'rw', isa => 'ArrayRef',
traits => ['Array'], default => sub {[]},
handles => {
add_repeatable_field => 'push',
has_repeatable_fields => 'count',
all_repeatable_fields => 'elements',
},
);
has 'field_traits' => ( is => 'ro', traits => ['Array'], isa => 'ArrayRef',
default => sub {[]}, handles => { 'has_field_traits' => 'count' } );
has 'widget_name_space' => (
is => 'ro',
isa => 'HFH::ArrayRefStr',
traits => ['Array'],
default => sub {[]},
coerce => 1,
handles => {
add_widget_name_space => 'push',
},
);
# it only really makes sense to set these before widget_form is applied in BUILD
has 'widget_form' => ( is => 'ro', isa => 'Str', default => 'Simple', writer => 'set_widget_form' );
has 'widget_wrapper' => ( is => 'ro', isa => 'Str', default => 'Simple', writer => 'set_widget_wrapper' );
has 'do_form_wrapper' => ( is => 'rw', builder => 'build_do_form_wrapper' );
sub build_do_form_wrapper { 0 }
has 'no_widgets' => ( is => 'ro', isa => 'Bool' );
has 'no_preload' => ( is => 'ro', isa => 'Bool' );
has 'no_update' => ( is => 'rw', isa => 'Bool', clearer => 'clear_no_update' );
has 'active' => (
is => 'rw',
traits => ['Array'],
isa => 'ArrayRef[Str]',
default => sub {[]},
handles => {
add_active => 'push',
has_active => 'count',
clear_active => 'clear',
}
);
has 'inactive' => (
is => 'rw',
traits => ['Array'],
isa => 'ArrayRef[Str]',
default => sub {[]},
handles => {
add_inactive => 'push',
has_inactive => 'count',
clear_inactive => 'clear',
}
);
# object with which to initialize
has 'init_object' => ( is => 'rw', clearer => 'clear_init_object' );
has 'update_field_list' => ( is => 'rw',
isa => 'HashRef',
default => sub {{}},
traits => ['Hash'],
handles => {
clear_update_field_list => 'clear',
has_update_field_list => 'count',
set_update_field_list => 'set',
},
);
has 'defaults' => ( is => 'rw', isa => 'HashRef', default => sub {{}}, traits => ['Hash'],
handles => { has_defaults => 'count', clear_defaults => 'clear' },
);
has 'use_defaults_over_obj' => ( is => 'rw', isa => 'Bool', clearer => 'clear_use_defaults_over_obj' );
has 'use_init_obj_over_item' => ( is => 'rw', isa => 'Bool', clearer => 'clear_use_init_obj_over_item' );
lib/HTML/FormHandler.pm view on Meta::CPAN
traits => ['Hash'],
isa => 'HashRef',
is => 'rw',
default => sub { {} },
trigger => sub { shift->_munge_params(@_) },
handles => {
set_param => 'set',
get_param => 'get',
clear_params => 'clear',
has_params => 'count',
},
);
sub submitted { shift->has_params }
has 'dependency' => ( isa => 'ArrayRef', is => 'rw' );
has '_required' => (
traits => ['Array'],
isa => 'ArrayRef[HTML::FormHandler::Field]',
is => 'rw',
default => sub { [] },
handles => {
clear_required => 'clear',
add_required => 'push',
}
);
# these messages could apply to either fields or form
has 'messages' => ( is => 'rw',
isa => 'HashRef',
traits => ['Hash'],
builder => 'build_messages',
handles => {
'_get_form_message' => 'get',
'_has_form_message' => 'exists',
'set_message' => 'set',
},
);
sub build_messages { {} }
my $class_messages = {};
sub get_class_messages {
return $class_messages;
}
sub get_message {
my ( $self, $msg ) = @_;
return $self->_get_form_message($msg) if $self->_has_form_message($msg);
return $self->get_class_messages->{$msg};
}
sub all_messages {
my $self = shift;
return { %{$self->get_class_messages}, %{$self->messages} };
}
has 'params_class' => (
is => 'ro',
isa => LoadableClass,
coerce => 1,
default => 'HTML::FormHandler::Params',
);
has 'params_args' => ( is => 'ro', isa => 'ArrayRef' );
sub BUILDARGS {
my $class = shift;
if ( scalar @_ == 1 && ref( $_[0]) ne 'HASH' ) {
my $arg = $_[0];
return blessed($arg) ? { item => $arg } : { item_id => $arg };
}
return $class->SUPER::BUILDARGS(@_);
}
sub BUILD {
my $self = shift;
$self->before_build; # hook to allow customizing forms
# HTML::FormHandler::Widget::Form::Simple is applied in Base
$self->apply_widget_role( $self, $self->widget_form, 'Form' )
unless ( $self->no_widgets || $self->widget_form eq 'Simple' );
$self->_build_fields; # create the form fields (BuildFields.pm)
$self->build_active if $self->has_active || $self->has_inactive || $self->has_flag('is_wizard');
$self->after_build; # hook for customizing
return if defined $self->item_id && !$self->item;
# Load values from object (if any)
# Would rather not load results at all here, but skipping it breaks
# existing apps that perform certain actions between 'new' and 'process'.
# Added fudge flag no_preload to enable skipping.
# A well-behaved program that always does ->process shouldn't need this preloading.
unless( $self->no_preload ) {
if ( my $init_object = $self->use_init_obj_over_item ?
($self->init_object || $self->item) : ( $self->item || $self->init_object ) ) {
$self->_result_from_object( $self->result, $init_object );
}
else {
$self->_result_from_fields( $self->result );
}
}
$self->dump_fields if $self->verbose;
return;
}
sub before_build {}
sub after_build {}
sub process {
my $self = shift;
warn "HFH: process ", $self->name, "\n" if $self->verbose;
$self->clear if $self->processed;
$self->setup_form(@_);
$self->validate_form if $self->posted;
$self->update_model if ( $self->validated && !$self->no_update );
$self->after_update_model if ( $self->validated && !$self->no_update );
$self->dump_fields if $self->verbose;
$self->processed(1);
return $self->validated;
}
sub run {
my $self = shift;
$self->setup_form(@_);
$self->validate_form if $self->posted;
( run in 0.865 second using v1.01-cache-2.11-cpan-39bf76dae61 )