File Coverage

blib/lib/HTML/FormHandler.pm
Criterion Covered Total %
statement 1 3 33.3
branch n/a
condition n/a
subroutine 1 1 100.0
pod n/a
total 2 4 50.0


line stmt bran cond sub pod time code
1             package HTML::FormHandler;
2             # ABSTRACT: HTML forms using Moose
3              
4 3     3   53810 use Moose;
  0            
  0            
5             extends 'HTML::FormHandler::Base'; # to make some methods overridable by roles
6             with 'HTML::FormHandler::Model', 'HTML::FormHandler::Fields',
7             'HTML::FormHandler::BuildFields',
8             'HTML::FormHandler::TraitFor::I18N';
9             with 'HTML::FormHandler::InitResult';
10             with 'HTML::FormHandler::Widget::ApplyRole';
11             with 'HTML::FormHandler::Traits';
12             with 'HTML::FormHandler::Blocks';
13              
14             use Carp;
15             use Class::MOP;
16             use HTML::FormHandler::Result;
17             use HTML::FormHandler::Field;
18             use Try::Tiny;
19             use MooseX::Types::LoadableClass qw/ LoadableClass /;
20             use namespace::autoclean;
21             use HTML::FormHandler::Merge ('merge');
22             use Sub::Name;
23             use Data::Clone;
24              
25             use 5.008;
26              
27             # always use 5 digits after decimal because of toolchain issues
28             our $VERSION = '0.40057';
29              
30              
31             # for consistency in api with field nodes
32             sub form { shift }
33             sub is_form { 1 }
34             sub has_form { 1 }
35              
36             # Moose attributes
37             has 'name' => (
38             isa => 'Str',
39             is => 'rw',
40             default => sub { return 'form' . int( rand 1000 ) }
41             );
42             sub full_name { '' }
43             sub full_accessor { '' }
44             has 'parent' => ( is => 'rw' );
45             has 'result' => (
46             isa => 'HTML::FormHandler::Result',
47             is => 'ro',
48             writer => '_set_result',
49             clearer => 'clear_result',
50             lazy => 1,
51             builder => 'build_result',
52             predicate => 'has_result',
53             handles => [
54             'input', '_set_input', '_clear_input', 'has_input',
55             'value', '_set_value', '_clear_value', 'has_value',
56             'add_result', 'results', 'validated', 'ran_validation',
57             'is_valid',
58             'form_errors', 'all_form_errors', 'push_form_errors', 'clear_form_errors',
59             'has_form_errors', 'num_form_errors',
60             ],
61             );
62              
63             sub build_result {
64             my $self = shift;
65             my $result_class = 'HTML::FormHandler::Result';
66             if ( $self->widget_form ) {
67             my $role = $self->get_widget_role( $self->widget_form, 'Form' );
68             $result_class = $result_class->with_traits( $role );
69             }
70             my $result = $result_class->new( name => $self->name, form => $self );
71             return $result;
72             }
73              
74             has 'index' => (
75             is => 'ro', isa => 'HashRef[HTML::FormHandler::Field]', traits => ['Hash'],
76             default => sub {{}},
77             handles => {
78             add_to_index => 'set',
79             field_from_index => 'get',
80             field_in_index => 'exists',
81             }
82             );
83             has '_repeatable_fields' => ( is => 'rw', isa => 'ArrayRef',
84             traits => ['Array'], default => sub {[]},
85             handles => {
86             add_repeatable_field => 'push',
87             has_repeatable_fields => 'count',
88             all_repeatable_fields => 'elements',
89             },
90             );
91              
92             has 'field_traits' => ( is => 'ro', traits => ['Array'], isa => 'ArrayRef',
93             default => sub {[]}, handles => { 'has_field_traits' => 'count' } );
94             has 'widget_name_space' => (
95             is => 'ro',
96             isa => 'HFH::ArrayRefStr',
97             traits => ['Array'],
98             default => sub {[]},
99             coerce => 1,
100             handles => {
101             add_widget_name_space => 'push',
102             },
103             );
104             # it only really makes sense to set these before widget_form is applied in BUILD
105             has 'widget_form' => ( is => 'ro', isa => 'Str', default => 'Simple', writer => 'set_widget_form' );
106             has 'widget_wrapper' => ( is => 'ro', isa => 'Str', default => 'Simple', writer => 'set_widget_wrapper' );
107             has 'do_form_wrapper' => ( is => 'rw', builder => 'build_do_form_wrapper' );
108             sub build_do_form_wrapper { 0 }
109             has 'no_widgets' => ( is => 'ro', isa => 'Bool' );
110             has 'no_preload' => ( is => 'ro', isa => 'Bool' );
111             has 'no_update' => ( is => 'rw', isa => 'Bool', clearer => 'clear_no_update' );
112             has 'active' => (
113             is => 'rw',
114             traits => ['Array'],
115             isa => 'ArrayRef[Str]',
116             default => sub {[]},
117             handles => {
118             add_active => 'push',
119             has_active => 'count',
120             clear_active => 'clear',
121             }
122             );
123             has 'inactive' => (
124             is => 'rw',
125             traits => ['Array'],
126             isa => 'ArrayRef[Str]',
127             default => sub {[]},
128             handles => {
129             add_inactive => 'push',
130             has_inactive => 'count',
131             clear_inactive => 'clear',
132             }
133             );
134              
135              
136             # object with which to initialize
137             has 'init_object' => ( is => 'rw', clearer => 'clear_init_object' );
138             has 'update_field_list' => ( is => 'rw',
139             isa => 'HashRef',
140             default => sub {{}},
141             traits => ['Hash'],
142             handles => {
143             clear_update_field_list => 'clear',
144             has_update_field_list => 'count',
145             set_update_field_list => 'set',
146             },
147             );
148             has 'defaults' => ( is => 'rw', isa => 'HashRef', default => sub {{}}, traits => ['Hash'],
149             handles => { has_defaults => 'count', clear_defaults => 'clear' },
150             );
151             has 'use_defaults_over_obj' => ( is => 'rw', isa => 'Bool', clearer => 'clear_use_defaults_over_obj' );
152             has 'use_init_obj_over_item' => ( is => 'rw', isa => 'Bool', clearer => 'clear_use_init_obj_over_item' );
153             has 'use_init_obj_when_no_accessor_in_item' => ( is => 'rw', isa => 'Bool' );
154             has 'use_fields_for_input_without_param' => ( is => 'rw', isa => 'Bool' );
155             # flags
156             has [ 'verbose', 'processed', 'did_init_obj' ] => ( isa => 'Bool', is => 'rw' );
157             has 'user_data' => ( isa => 'HashRef', is => 'rw' );
158             has 'ctx' => ( is => 'rw', weak_ref => 1, clearer => 'clear_ctx' );
159             has 'html_prefix' => ( isa => 'Bool', is => 'ro' );
160             has 'active_column' => ( isa => 'Str', is => 'ro' );
161             has 'http_method' => ( isa => 'Str', is => 'ro', default => 'post' );
162             has 'enctype' => ( is => 'rw', isa => 'Str' );
163             has 'error_message' => ( is => 'rw', predicate => 'has_error_message', clearer => 'clear_error_message' );
164             has 'success_message' => ( is => 'rw', predicate => 'has_success_message', clearer => 'clear_success_message' );
165             has 'info_message' => ( is => 'rw', predicate => 'has_info_message', clearer => 'clear_info_message' );
166             # deprecated
167             has 'style' => ( isa => 'Str', is => 'rw' );
168              
169             has 'is_html5' => ( isa => 'Bool', is => 'ro', default => 0 );
170             # deprecated. use form_element_attr instead
171             has 'html_attr' => ( is => 'rw', traits => ['Hash'],
172             default => sub { {} }, handles => { has_html_attr => 'count',
173             set_html_attr => 'set', delete_html_attr => 'delete' },
174             trigger => \&_html_attr_set,
175             );
176             sub _html_attr_set {
177             my ( $self, $value ) = @_;
178             my $class = delete $value->{class};
179             $self->form_element_attr($value);
180             $self->add_form_element_class if $class;
181             }
182              
183             {
184             # create the attributes and methods for
185             # form_element_attr, build_form_element_attr, form_element_class,
186             # form_wrapper_attr, build_form_wrapper_atrr, form_wrapper_class
187             no strict 'refs';
188             foreach my $attr ('form_wrapper', 'form_element' ) {
189             my $add_meth = "add_${attr}_class";
190             has "${attr}_attr" => ( is => 'rw', traits => ['Hash'],
191             builder => "build_${attr}_attr",
192             handles => {
193             "has_${attr}_attr" => 'count',
194             "get_${attr}_attr" => 'get',
195             "set_${attr}_attr" => 'set',
196             "delete_${attr}_attr" => 'delete',
197             "exists_${attr}_attr" => 'exists',
198             },
199             );
200             # create builders for _attr
201             my $attr_builder = __PACKAGE__ . "::build_${attr}_attr";
202             *$attr_builder = subname $attr_builder, sub {{}};
203             # create the 'class' slots
204             has "${attr}_class" => ( is => 'rw', isa => 'HFH::ArrayRefStr',
205             traits => ['Array'],
206             coerce => 1,
207             builder => "build_${attr}_class",
208             handles => {
209             "has_${attr}_class" => 'count',
210             "_add_${attr}_class" => 'push',
211             },
212             );
213             # create builders for classes
214             my $class_builder = __PACKAGE__ . "::build_${attr}_class";
215             *$class_builder = subname $class_builder, sub {[]};
216             # create wrapper for add_to_ to accept arrayref
217             my $add_to_class = __PACKAGE__ . "::add_${attr}_class";
218             my $_add_meth = __PACKAGE__ . "::_add_${attr}_class";
219             # create add method that takes an arrayref
220             *$add_to_class = subname $add_to_class, sub { shift->$_add_meth((ref $_[0] eq 'ARRAY' ? @{$_[0]} : @_)); }
221             }
222             }
223              
224             sub attributes { shift->form_element_attributes(@_) }
225             sub form_element_attributes {
226             my ( $self, $result ) = @_;
227             $result ||= $self->result;
228             my $attr = {};
229             $attr->{id} = $self->name;
230             $attr->{action} = $self->action if $self->action;
231             $attr->{method} = $self->http_method if $self->http_method;
232             $attr->{enctype} = $self->enctype if $self->enctype;
233             $attr->{style} = $self->style if $self->style;
234             $attr = {%$attr, %{$self->form_element_attr}};
235             my $class = [@{$self->form_element_class}];
236             $attr->{class} = $class if @$class;
237             my $mod_attr = $self->html_attributes($self, 'form_element', $attr);
238             return ref $mod_attr eq 'HASH' ? $mod_attr : $attr;
239             }
240             sub form_wrapper_attributes {
241             my ( $self, $result ) = @_;
242             $result ||= $self->result;
243             my $attr = {%{$self->form_wrapper_attr}};
244             my $class = [@{$self->form_wrapper_class}];
245             $attr->{class} = $class if @$class;
246             my $mod_attr = $self->html_attributes($self, 'form_wrapper', $attr);
247             return ref $mod_attr eq 'HASH' ? $mod_attr : $attr;
248             }
249              
250             sub html_attributes {
251             my ( $self, $obj, $type, $attrs, $result ) = @_;
252             # deprecated 'field_html_attributes'; name changed, remove eventually
253             if( $self->can('field_html_attributes') ) {
254             $attrs = $self->field_html_attributes( $obj, $type, $attrs, $result );
255             }
256             return $attrs;
257             }
258              
259             sub has_flag {
260             my ( $self, $flag_name ) = @_;
261             return unless $self->can($flag_name);
262             return $self->$flag_name;
263             }
264              
265             has 'form_tags' => (
266             traits => ['Hash'],
267             isa => 'HashRef',
268             is => 'ro',
269             builder => 'build_form_tags',
270             handles => {
271             _get_tag => 'get',
272             set_tag => 'set',
273             tag_exists => 'exists',
274             has_tag => 'exists',
275             },
276             );
277             sub build_form_tags {{}}
278             sub get_tag {
279             my ( $self, $name ) = @_;
280             return '' unless $self->tag_exists($name);
281             my $tag = $self->_get_tag($name);
282             return $self->$tag if ref $tag eq 'CODE';
283             return $tag unless $tag =~ /^%/;
284             ( my $block_name = $tag ) =~ s/^%//;
285             return $self->form->block($block_name)->render
286             if ( $self->form && $self->form->block_exists($block_name) );
287             return '';
288             }
289             has 'for_js' => (
290             isa => 'HashRef',
291             traits => ['Hash'],
292             is => 'rw',
293             default => sub { {} },
294             handles => {
295             set_for_js => 'set',
296             has_for_js => 'count',
297             clear_for_js => 'clear',
298             }
299             );
300              
301             has 'action' => ( is => 'rw' );
302             has 'posted' => ( is => 'rw', isa => 'Bool', clearer => 'clear_posted', predicate => 'has_posted' );
303             has 'params' => (
304             traits => ['Hash'],
305             isa => 'HashRef',
306             is => 'rw',
307             default => sub { {} },
308             trigger => sub { shift->_munge_params(@_) },
309             handles => {
310             set_param => 'set',
311             get_param => 'get',
312             clear_params => 'clear',
313             has_params => 'count',
314             },
315             );
316             sub submitted { shift->has_params }
317             has 'dependency' => ( isa => 'ArrayRef', is => 'rw' );
318             has '_required' => (
319             traits => ['Array'],
320             isa => 'ArrayRef[HTML::FormHandler::Field]',
321             is => 'rw',
322             default => sub { [] },
323             handles => {
324             clear_required => 'clear',
325             add_required => 'push',
326             }
327             );
328              
329             # these messages could apply to either fields or form
330             has 'messages' => ( is => 'rw',
331             isa => 'HashRef',
332             traits => ['Hash'],
333             builder => 'build_messages',
334             handles => {
335             '_get_form_message' => 'get',
336             '_has_form_message' => 'exists',
337             'set_message' => 'set',
338             },
339             );
340             sub build_messages { {} }
341              
342             my $class_messages = {};
343             sub get_class_messages {
344             return $class_messages;
345             }
346              
347             sub get_message {
348             my ( $self, $msg ) = @_;
349             return $self->_get_form_message($msg) if $self->_has_form_message($msg);
350             return $self->get_class_messages->{$msg};
351             }
352             sub all_messages {
353             my $self = shift;
354             return { %{$self->get_class_messages}, %{$self->messages} };
355             }
356              
357             has 'params_class' => (
358             is => 'ro',
359             isa => LoadableClass,
360             coerce => 1,
361             default => 'HTML::FormHandler::Params',
362             );
363              
364             has 'params_args' => ( is => 'ro', isa => 'ArrayRef' );
365              
366             sub BUILDARGS {
367             my $class = shift;
368              
369             if ( scalar @_ == 1 && ref( $_[0]) ne 'HASH' ) {
370             my $arg = $_[0];
371             return blessed($arg) ? { item => $arg } : { item_id => $arg };
372             }
373             return $class->SUPER::BUILDARGS(@_);
374             }
375              
376             sub BUILD {
377             my $self = shift;
378              
379             $self->before_build; # hook to allow customizing forms
380             # HTML::FormHandler::Widget::Form::Simple is applied in Base
381             $self->apply_widget_role( $self, $self->widget_form, 'Form' )
382             unless ( $self->no_widgets || $self->widget_form eq 'Simple' );
383             $self->_build_fields; # create the form fields (BuildFields.pm)
384             $self->build_active if $self->has_active || $self->has_inactive || $self->has_flag('is_wizard');
385             $self->after_build; # hook for customizing
386             return if defined $self->item_id && !$self->item;
387             # Load values from object (if any)
388             # Would rather not load results at all here, but skipping it breaks
389             # existing apps that perform certain actions between 'new' and 'process'.
390             # Added fudge flag no_preload to enable skipping.
391             # A well-behaved program that always does ->process shouldn't need this preloading.
392             unless( $self->no_preload ) {
393             if ( my $init_object = $self->use_init_obj_over_item ?
394             ($self->init_object || $self->item) : ( $self->item || $self->init_object ) ) {
395             $self->_result_from_object( $self->result, $init_object );
396             }
397             else {
398             $self->_result_from_fields( $self->result );
399             }
400             }
401             $self->dump_fields if $self->verbose;
402             return;
403             }
404             sub before_build {}
405             sub after_build {}
406              
407             sub process {
408             my $self = shift;
409              
410             warn "HFH: process ", $self->name, "\n" if $self->verbose;
411             $self->clear if $self->processed;
412             $self->setup_form(@_);
413             $self->validate_form if $self->posted;
414             $self->update_model if ( $self->validated && !$self->no_update );
415             $self->after_update_model if ( $self->validated && !$self->no_update );
416             $self->dump_fields if $self->verbose;
417             $self->processed(1);
418             return $self->validated;
419             }
420              
421             sub run {
422             my $self = shift;
423             $self->setup_form(@_);
424             $self->validate_form if $self->posted;
425             $self->update_model if ( $self->validated && !$self->no_update );;
426             my $result = $self->result;
427             $self->clear;
428             return $result;
429             }
430              
431             sub after_update_model {
432             my $self = shift;
433             # This an attempt to reload the repeatable
434             # relationships after the database is updated, so that we get the
435             # primary keys of the repeatable elements. Otherwise, if a form
436             # is re-presented, repeatable elements without primary keys may
437             # be created again. There is no reliable way to connect up
438             # existing repeatable elements with their db-created primary keys.
439             if ( $self->has_repeatable_fields && $self->item ) {
440             foreach my $field ( $self->all_repeatable_fields ) {
441             next unless $field->is_active;
442             # Check to see if there are any repeatable subfields with
443             # null primary keys, so we can skip reloading for the case
444             # where all repeatables have primary keys.
445             my $needs_reload = 0;
446             foreach my $sub_field ( $field->fields ) {
447             if ( $sub_field->has_flag('is_compound') && $sub_field->has_primary_key ) {
448             foreach my $pk_field ( @{ $sub_field->primary_key } ) {
449             $needs_reload++ unless $pk_field->fif;
450             }
451             last if $needs_reload;
452             }
453             }
454             next unless $needs_reload;
455             my @names = split( /\./, $field->full_name );
456             my $rep_item = $self->find_sub_item( $self->item, \@names );
457             # $rep_item is a single row or an array of rows or undef
458             # If we found a database item for the repeatable, replace
459             # the existing result with a result derived from the item.
460             if ( ref $rep_item ) {
461             my $parent = $field->parent;
462             my $result = $field->result;
463             $field->init_state;
464             my $new_result = $field->_result_from_object( $result, $rep_item );
465             # find index of existing result
466             my $index = $parent->result->find_result_index( sub { $_ == $result } );
467             # replace existing result with new result
468             $parent->result->set_result_at_index( $index, $new_result );
469             }
470             }
471             }
472             }
473              
474              
475             sub db_validate {
476             my $self = shift;
477             my $fif = $self->fif;
478             $self->process($fif);
479             return $self->validated;
480             }
481              
482             sub clear {
483             my $self = shift;
484             $self->clear_data;
485             $self->clear_params;
486             $self->clear_posted;
487             $self->clear_item;
488             $self->clear_init_object;
489             $self->clear_ctx;
490             $self->processed(0);
491             $self->did_init_obj(0);
492             $self->clear_result;
493             $self->clear_use_defaults_over_obj;
494             $self->clear_use_init_obj_over_item;
495             $self->clear_no_update;
496             $self->clear_info_message;
497             $self->clear_for_js;
498             }
499              
500             sub values { shift->value }
501              
502             # deprecated?
503             sub error_field_names {
504             my $self = shift;
505             my @error_fields = $self->error_fields;
506             return map { $_->name } @error_fields;
507             }
508              
509             sub errors {
510             my $self = shift;
511             my @error_fields = $self->error_fields;
512             my @errors = $self->all_form_errors;
513             push @errors, map { $_->all_errors } @error_fields;
514             return @errors;
515             }
516              
517             sub errors_by_id {
518             my $self = shift;
519             my %errors;
520             $errors{$_->id} = [$_->all_errors] for $self->error_fields;
521             return \%errors;
522             }
523              
524             sub errors_by_name {
525             my $self = shift;
526             my %errors;
527             $errors{$_->html_name} = [$_->all_errors] for $self->error_fields;
528             return \%errors;
529             }
530              
531             sub build_errors {
532             my $self = shift;
533             # this puts the errors in the result
534             foreach my $err_res (@{$self->result->error_results}) {
535             $self->result->_push_errors($err_res->all_errors);
536             }
537             }
538              
539             sub uuid {
540             my $form = shift;
541             require Data::UUID;
542             my $uuid = Data::UUID->new->create_str;
543             return qq[<input type="hidden" name="form_uuid" value="$uuid">];
544             }
545              
546             sub validate_form {
547             my $self = shift;
548             my $params = $self->params;
549             $self->_set_dependency; # set required dependencies
550             $self->_fields_validate;
551             $self->validate; # empty method for users
552             $self->validate_model; # model specific validation
553             $self->fields_set_value;
554             $self->build_errors; # move errors to result
555             $self->_clear_dependency;
556             $self->clear_posted;
557             $self->ran_validation(1);
558             $self->dump_validated if $self->verbose;
559             return $self->validated;
560             }
561              
562             sub validate { 1 }
563              
564             sub has_errors {
565             my $self = shift;
566             return $self->has_error_fields || $self->has_form_errors;
567             }
568             sub num_errors {
569             my $self = shift;
570             return $self->num_error_fields + $self->num_form_errors;
571             }
572              
573             sub setup_form {
574             my ( $self, @args ) = @_;
575             if ( @args == 1 ) {
576             $self->params( $args[0] );
577             }
578             elsif ( @args > 1 ) {
579             my $hashref = {@args};
580             while ( my ( $key, $value ) = each %{$hashref} ) {
581             confess "invalid attribute '$key' passed to setup_form"
582             unless $self->can($key);
583             $self->$key($value);
584             }
585             }
586             if ( $self->item_id && !$self->item ) {
587             $self->item( $self->build_item );
588             }
589             $self->clear_result;
590             $self->set_active;
591             $self->update_fields;
592             # initialization of Repeatable fields and Select options
593             # will be done in _result_from_object when there's an initial object
594             # in _result_from_input when there are params
595             # and by _result_from_fields for empty forms
596             $self->posted(1) if ( $self->has_params && !$self->has_posted );
597             if ( !$self->did_init_obj ) {
598             if ( my $init_object = $self->use_init_obj_over_item ?
599             ($self->init_object || $self->item) : ( $self->item || $self->init_object ) ) {
600             $self->_result_from_object( $self->result, $init_object );
601             }
602             elsif ( !$self->posted ) {
603             # no initial object. empty form must be initialized
604             $self->_result_from_fields( $self->result );
605             }
606             }
607             # if params exist and if posted flag is either not set or set to true
608             my $params = clone( $self->params );
609             if ( $self->posted ) {
610             $self->clear_result;
611             $self->_result_from_input( $self->result, $params, 1 );
612             }
613              
614             }
615              
616             # if active => [...] is set at process time, set 'active' flag
617             sub set_active {
618             my $self = shift;
619             if( $self->has_active ) {
620             foreach my $fname (@{$self->active}) {
621             my $field = $self->field($fname);
622             if ( $field ) {
623             $field->_active(1);
624             }
625             else {
626             warn "field $fname not found to set active";
627             }
628             }
629             $self->clear_active;
630             }
631             if( $self->has_inactive ) {
632             foreach my $fname (@{$self->inactive}) {
633             my $field = $self->field($fname);
634             if ( $field ) {
635             $field->_active(0);
636             }
637             else {
638             warn "field $fname not found to set inactive";
639             }
640             }
641             $self->clear_inactive;
642             }
643             }
644              
645             # if active => [...] is set at build time, remove 'inactive' flags
646             sub build_active {
647             my $self = shift;
648             if( $self->has_active ) {
649             foreach my $fname (@{$self->active}) {
650             my $field = $self->field($fname);
651             if( $field ) {
652             $field->clear_inactive;
653             }
654             else {
655             warn "field $fname not found to set active";
656             }
657             }
658             $self->clear_active;
659             }
660             if( $self->has_inactive ) {
661             foreach my $fname (@{$self->inactive}) {
662             my $field = $self->field($fname);
663             if( $field ) {
664             $field->inactive(1);
665             }
666             else {
667             warn "field $fname not found to set inactive";
668             }
669             }
670             $self->clear_inactive;
671             }
672             }
673              
674             sub fif { shift->fields_fif(@_) }
675              
676             # this is subclassed by the model, which may
677             # do a lot more than this
678             sub init_value {
679             my ( $self, $field, $value ) = @_;
680             $field->init_value($value);
681             $field->_set_value($value);
682             }
683              
684             sub _set_dependency {
685             my $self = shift;
686              
687             my $depends = $self->dependency || return;
688             my $params = $self->params;
689             for my $group (@$depends) {
690             next if @$group < 2;
691             # process a group of fields
692             for my $name (@$group) {
693             # is there a value?
694             my $value = $params->{$name};
695             next unless defined $value;
696             # The exception is a boolean can be zero which we count as not set.
697             # This is to allow requiring a field when a boolean is true.
698             my $field = $self->field($name);
699             next if $self->field($name)->type eq 'Boolean' && $value == 0;
700             next unless HTML::FormHandler::Field::has_some_value($value);
701             # one field was found non-blank, so set all to required
702             for (@$group) {
703             my $field = $self->field($_);
704             next unless $field && !$field->required;
705             $self->add_required($field); # save for clearing later.
706             $field->required(1);
707             }
708             last;
709             }
710             }
711             }
712              
713             sub _clear_dependency {
714             my $self = shift;
715              
716             $_->required(0) for @{$self->_required};
717             $self->clear_required;
718             }
719              
720             sub peek {
721             my $self = shift;
722             my $string = "Form " . $self->name . "\n";
723             my $indent = ' ';
724             foreach my $field ( $self->sorted_fields ) {
725             $string .= $field->peek( $indent );
726             }
727             return $string;
728             }
729              
730             sub _munge_params {
731             my ( $self, $params, $attr ) = @_;
732             my $_fix_params = $self->params_class->new( @{ $self->params_args || [] } );
733             my $new_params = $_fix_params->expand_hash($params);
734             if ( $self->html_prefix ) {
735             $new_params = $new_params->{ $self->name };
736             }
737             $new_params = {} if !defined $new_params;
738             $self->{params} = $new_params;
739             }
740              
741             sub params_to_values {
742             my ( $self, $params ) = @_;
743             my $_fix_params = $self->params_class->new( @{ $self->params_args || [] } );
744             my $new_params = $_fix_params->expand_hash($params);
745             return $new_params;
746             }
747              
748             sub add_form_error {
749             my ( $self, @message ) = @_;
750              
751             unless ( defined $message[0] ) {
752             @message = ('form is invalid');
753             }
754             my $out;
755             try {
756             $out = $self->_localize(@message);
757             }
758             catch {
759             die "Error occurred localizing error message for " . $self->name . ". $_";
760             };
761             $self->push_form_errors($out);
762             return;
763             }
764              
765             sub get_default_value { }
766             sub _can_deflate { }
767              
768             sub update_fields {
769             my $self = shift;
770             if( $self->has_update_field_list ) {
771             my $updates = $self->update_field_list;
772             foreach my $field_name ( keys %{$updates} ) {
773             $self->update_field($field_name, $updates->{$field_name} );
774             }
775             $self->clear_update_field_list;
776             }
777             if( $self->has_defaults ) {
778             my $defaults = $self->defaults;
779             foreach my $field_name ( keys %{$defaults} ) {
780             $self->update_field($field_name, { default => $defaults->{$field_name} } );
781             }
782             $self->clear_defaults;
783             }
784             }
785              
786             sub update_field {
787             my ( $self, $field_name, $updates ) = @_;
788              
789             my $field = $self->field($field_name);
790             unless( $field ) {
791             die "Field $field_name is not found and cannot be updated by update_fields";
792             }
793             while ( my ( $attr_name, $attr_value ) = each %{$updates} ) {
794             confess "invalid attribute '$attr_name' passed to update_field"
795             unless $field->can($attr_name);
796             if( $attr_name eq 'tags' ) {
797             $field->set_tag(%$attr_value);
798             }
799             else {
800             $field->$attr_name($attr_value);
801             }
802             }
803             }
804              
805              
806             __PACKAGE__->meta->make_immutable;
807             use namespace::autoclean;
808             1;
809              
810             __END__
811              
812             =pod
813              
814             =encoding UTF-8
815              
816             =head1 NAME
817              
818             HTML::FormHandler - HTML forms using Moose
819              
820             =head1 VERSION
821              
822             version 0.40057
823              
824             =head1 SYNOPSIS
825              
826             See the manual at L<HTML::FormHandler::Manual>.
827              
828             use HTML::FormHandler; # or a custom form: use MyApp::Form::User;
829             my $form = HTML::FormHandler->new( .... );
830             $form->process( params => $params );
831             my $rendered_form = $form->render;
832             if( $form->validated ) {
833             # perform validated form actions
834             }
835             else {
836             # perform non-validated actions
837             }
838              
839             Or, if you want to use a form 'result' (which contains only the form
840             values and error messages) instead:
841              
842             use MyApp::Form; # or a generic form: use HTML::FormHandler;
843             my $form = MyApp::Form->new( .... );
844             my $result = $form->run( params => $params );
845             if( $result->validated ) {
846             # perform validated form actions
847             }
848             else {
849             # perform non-validated actions
850             $result->render;
851             }
852              
853             An example of a custom form class:
854              
855             package MyApp::Form::User;
856              
857             use HTML::FormHandler::Moose;
858             extends 'HTML::FormHandler';
859             use Moose::Util::TypeConstraints;
860              
861             has '+item_class' => ( default => 'User' );
862              
863             has_field 'name' => ( type => 'Text' );
864             has_field 'age' => ( type => 'PosInteger', apply => [ 'MinimumAge' ] );
865             has_field 'birthdate' => ( type => 'DateTime' );
866             has_field 'birthdate.month' => ( type => 'Month' );
867             has_field 'birthdate.day' => ( type => 'MonthDay' );
868             has_field 'birthdate.year' => ( type => 'Year' );
869             has_field 'hobbies' => ( type => 'Multiple' );
870             has_field 'address' => ( type => 'Text' );
871             has_field 'city' => ( type => 'Text' );
872             has_field 'state' => ( type => 'Select' );
873             has_field 'email' => ( type => 'Email' );
874              
875             has '+dependency' => ( default => sub {
876             [ ['address', 'city', 'state'], ]
877             }
878             );
879              
880             subtype 'MinimumAge'
881             => as 'Int'
882             => where { $_ > 13 }
883             => message { "You are not old enough to register" };
884              
885             no HTML::FormHandler::Moose;
886             1;
887              
888             A dynamic form - one that does not use a custom form class - may be
889             created using the 'field_list' attribute to set fields:
890              
891             my $form = HTML::FormHandler->new(
892             name => 'user_form',
893             item => $user,
894             field_list => [
895             'username' => {
896             type => 'Text',
897             apply => [ { check => qr/^[0-9a-z]*\z/,
898             message => 'Contains invalid characters' } ],
899             },
900             'select_bar' => {
901             type => 'Select',
902             options => \@select_options,
903             multiple => 1,
904             size => 4,
905             },
906             ],
907             );
908              
909             FormHandler does not provide a custom controller for Catalyst because
910             it isn't necessary. Interfacing to FormHandler is only a couple of
911             lines of code. See L<HTML::FormHandler::Manual::Catalyst> for more
912             details, or L<Catalyst::Manual::Tutorial::09_AdvancedCRUD::09_FormHandler>.
913              
914             =head1 DESCRIPTION
915              
916             *** Although documentation in this file provides some overview, it is mainly
917             intended for API documentation. See L<HTML::FormHandler::Manual::Intro>
918             for an introduction, with links to other documentation.
919              
920             HTML::FormHandler maintains a clean separation between form construction
921             and form rendering. It allows you to define your forms and fields in a
922             number of flexible ways. Although it provides renderers for HTML, you
923             can define custom renderers for any kind of presentation.
924              
925             HTML::FormHandler allows you to define form fields and validators. It can
926             be used for both database and non-database forms, and will
927             automatically update or create rows in a database. It can be used
928             to process structured data that doesn't come from an HTML form.
929              
930             One of its goals is to keep the controller/application program interface as
931             simple as possible, and to minimize the duplication of code. In most cases,
932             interfacing your controller to your form is only a few lines of code.
933              
934             With FormHandler you shouldn't have to spend hours trying to figure out how to make a
935             simple HTML change that would take one minute by hand. Because you _can_ do it
936             by hand. Or you can automate HTML generation as much as you want, with
937             template widgets or pure Perl rendering classes, and stay completely in
938             control of what, where, and how much is done automatically. You can define
939             custom renderers and display your rendered forms however you want.
940              
941             You can split the pieces of your forms up into logical parts and compose
942             complete forms from FormHandler classes, roles, fields, collections of
943             validations, transformations and Moose type constraints.
944             You can write custom methods to process forms, add any attribute you like,
945             and use Moose method modifiers. FormHandler forms are Perl classes, so there's
946             a lot of flexibility in what you can do.
947              
948             HTML::FormHandler provides rendering through roles which are applied to
949             form and field classes (although there's no reason you couldn't write
950             a renderer as an external object either). There are currently two flavors:
951             all-in-one solutions like L<HTML::FormHandler::Render::Simple> and
952             L<HTML::FormHandler::Render::Table> that contain methods for rendering
953             field widget classes, and the L<HTML::FormHandler::Widget> roles, which are
954             more atomic roles which are automatically applied to fields and form. See
955             L<HTML::FormHandler::Manual::Rendering> for more details.
956             (And you can easily use hand-built forms - FormHandler doesn't care.)
957              
958             The typical application for FormHandler would be in a Catalyst, DBIx::Class,
959             Template Toolkit web application, but use is not limited to that. FormHandler
960             can be used in any Perl application.
961              
962             More Formhandler documentation and a tutorial can be found in the manual
963             at L<HTML::FormHandler::Manual>.
964              
965             =head1 ATTRIBUTES and METHODS
966              
967             =head2 Creating a form with 'new'
968              
969             The new constructor takes name/value pairs:
970              
971             MyForm->new(
972             item => $item,
973             );
974              
975             No attributes are required on new. The form's fields will be built from
976             the form definitions. If no initial data object or defaults have been provided, the form
977             will be empty. Most attributes can be set on either 'new' or 'process'.
978             The common attributes to be passed in to the constructor for a database form
979             are either item_id and schema or item:
980              
981             item_id - database row primary key
982             item - database row object
983             schema - (for DBIC) the DBIx::Class schema
984              
985             The following are sometimes passed in, but are also often set
986             in the form class:
987              
988             item_class - source name of row
989             dependency - (see dependency)
990             field_list - an array of field definitions
991             init_object - a hashref or object to provide initial values
992              
993             Examples of creating a form object with new:
994              
995             my $form = MyApp::Form::User->new;
996              
997             # database form using a row object
998             my $form = MyApp::Form::Member->new( item => $row );
999              
1000             # a dynamic form (no form class has been defined)
1001             my $form = HTML::FormHandler::Model::DBIC->new(
1002             item_id => $id,
1003             item_class => 'User',
1004             schema => $schema,
1005             field_list => [
1006             name => 'Text',
1007             active => 'Boolean',
1008             submit_btn => 'Submit',
1009             ],
1010             );
1011              
1012             See the model class for more information about 'item', 'item_id',
1013             'item_class', and 'schema' (for the DBIC model).
1014             L<HTML::FormHandler::Model::DBIC>.
1015              
1016             FormHandler forms are handled in two steps: 1) create with 'new',
1017             2) handle with 'process'. FormHandler doesn't
1018             care whether most parameters are set on new or process or update,
1019             but a 'field_list' argument must be passed in on 'new' since the
1020             fields are built at construction time.
1021              
1022             If you want to update field attributes on the 'process' call, you can
1023             use an 'update_field_list' or 'defaults' hashref attribute , or subclass
1024             update_fields in your form. The 'update_field_list' hashref can be used
1025             to set any field attribute. The 'defaults' hashref will update only
1026             the 'default' attribute in the field. (There are a lot of ways to
1027             set defaults. See L<HTML::FormHandler::Manual::Defaults>.)
1028              
1029             $form->process( defaults => { foo => 'foo_def', bar => 'bar_def' } );
1030             $form->process( update_field_list => { foo => { label => 'New Label' } });
1031              
1032             Field results are built on the 'new' call, but will then be re-built
1033             on the process call. If you always use 'process' before rendering the form,
1034             accessing fields, etc, you can set the 'no_preload' flag to skip this step.
1035              
1036             =head2 Processing the form
1037              
1038             =head3 process
1039              
1040             Call the 'process' method on your form to perform validation and
1041             update. A database form must have either an item (row object) or
1042             a schema, item_id (row primary key), and item_class (usually set in the form).
1043             A non-database form requires only parameters.
1044              
1045             $form->process( item => $book, params => $c->req->parameters );
1046             $form->process( item_id => $item_id,
1047             schema => $schema, params => $c->req->parameters );
1048             $form->process( params => $c->req->parameters );
1049              
1050             This process method returns the 'validated' flag (C<< $form->validated >>).
1051             If it is a database form and the form validates, the database row
1052             will be updated.
1053              
1054             After the form has been processed, you can get a parameter hashref suitable
1055             for using to fill in the form from C<< $form->fif >>.
1056             A hash of inflated values (that would be used to update the database for
1057             a database form) can be retrieved with C<< $form->value >>.
1058              
1059             If you don't want to update the database on this process call, you can
1060             set the 'no_update' flag:
1061              
1062             $form->process( item => $book, params => $params, no_update => 1 );
1063              
1064             =head3 params
1065              
1066             Parameters are passed in when you call 'process'.
1067             HFH gets data to validate and store in the database from the params hash.
1068             If the params hash is empty, no validation is done, so it is not necessary
1069             to check for POST before calling C<< $form->process >>. (Although see
1070             the 'posted' option for complications.)
1071              
1072             Params can either be in the form of CGI/HTTP style params:
1073              
1074             {
1075             user_name => "Joe Smith",
1076             occupation => "Programmer",
1077             'addresses.0.street' => "999 Main Street",
1078             'addresses.0.city' => "Podunk",
1079             'addresses.0.country' => "UT",
1080             'addresses.0.address_id' => "1",
1081             'addresses.1.street' => "333 Valencia Street",
1082             'addresses.1.city' => "San Francisco",
1083             'addresses.1.country' => "UT",
1084             'addresses.1.address_id' => "2",
1085             }
1086              
1087             or as structured data in the form of hashes and lists:
1088              
1089             {
1090             addresses => [
1091             {
1092             city => 'Middle City',
1093             country => 'GK',
1094             address_id => 1,
1095             street => '101 Main St',
1096             },
1097             {
1098             city => 'DownTown',
1099             country => 'UT',
1100             address_id => 2,
1101             street => '99 Elm St',
1102             },
1103             ],
1104             'occupation' => 'management',
1105             'user_name' => 'jdoe',
1106             }
1107              
1108             CGI style parameters will be converted to hashes and lists for HFH to
1109             operate on.
1110              
1111             =head3 posted
1112              
1113             Note that FormHandler by default uses empty params as a signal that the
1114             form has not actually been posted, and so will not attempt to validate
1115             a form with empty params. Most of the time this works OK, but if you
1116             have a small form with only the controls that do not return a post
1117             parameter if unselected (checkboxes and select lists), then the form
1118             will not be validated if everything is unselected. For this case you
1119             can either add a hidden field as an 'indicator', or use the 'posted' flag:
1120              
1121             $form->process( posted => ($c->req->method eq 'POST'), params => ... );
1122              
1123             The 'posted' flag also works to prevent validation from being performed
1124             if there are extra params in the params hash and it is not a 'POST' request.
1125              
1126             =head2 Getting data out
1127              
1128             =head3 fif (fill in form)
1129              
1130             If you don't use FormHandler rendering and want to fill your form values in
1131             using some other method (such as with HTML::FillInForm or using a template)
1132             this returns a hash of values that are equivalent to params which you may
1133             use to fill in your form.
1134              
1135             The fif value for a 'title' field in a TT form:
1136              
1137             [% form.fif.title %]
1138              
1139             Or you can use the 'fif' method on individual fields:
1140              
1141             [% form.field('title').fif %]
1142              
1143             If you use FormHandler to render your forms or field you probably won't use
1144             these methods.
1145              
1146             =head3 value
1147              
1148             Returns a hashref of all field values. Useful for non-database forms, or if
1149             you want to update the database yourself. The 'fif' method returns
1150             a hashref with the field names for the keys and the field's 'fif' for the
1151             values; 'value' returns a hashref with the field accessors for the keys, and the
1152             field's 'value' (possibly inflated) for the values.
1153              
1154             Forms containing arrays to be processed with L<HTML::FormHandler::Field::Repeatable>
1155             will have parameters with dots and numbers, like 'addresses.0.city', while the
1156             values hash will transform the fields with numbers to arrays.
1157              
1158             =head2 Accessing and setting up fields
1159              
1160             Fields are declared with a number of attributes which are defined in
1161             L<HTML::FormHandler::Field>. If you want additional attributes you can
1162             define your own field classes (or apply a role to a field class - see
1163             L<HTML::FormHandler::Manual::Cookbook>). The field 'type' (used in field
1164             definitions) is the short class name of the field class, used when
1165             searching the 'field_name_space' for the field class.
1166              
1167             =head3 has_field
1168              
1169             The most common way of declaring fields is the 'has_field' syntax.
1170             Using the 'has_field' syntax sugar requires C< use HTML::FormHandler::Moose; >
1171             or C< use HTML::FormHandler::Moose::Role; > in a role.
1172             See L<HTML::FormHandler::Manual::Intro>
1173              
1174             use HTML::FormHandler::Moose;
1175             has_field 'field_name' => ( type => 'FieldClass', .... );
1176              
1177             =head3 field_list
1178              
1179             A 'field_list' is an array of field definitions which can be used as an
1180             alternative to 'has_field' in small, dynamic forms to create fields.
1181              
1182             field_list => [
1183             field_one => {
1184             type => 'Text',
1185             required => 1
1186             },
1187             field_two => 'Text,
1188             ]
1189              
1190             The field_list array takes elements which are either a field_name key
1191             pointing to a 'type' string or a field_name key pointing to a
1192             hashref of field attributes. You can also provide an array of
1193             hashref elements with the name as an additional attribute.
1194             The field list can be set inside a form class, when you want to
1195             add fields to the form depending on some other state, although
1196             you can also create all the fields and set some of them inactive.
1197              
1198             sub field_list {
1199             my $self = shift;
1200             my $fields = $self->schema->resultset('SomeTable')->
1201             search({user_id => $self->user_id, .... });
1202             my @field_list;
1203             while ( my $field = $fields->next )
1204             {
1205             < create field list >
1206             }
1207             return \@field_list;
1208             }
1209              
1210             =head3 update_field_list
1211              
1212             Used to dynamically set particular field attributes on the 'process' (or
1213             'run') call. (Will not create fields.)
1214              
1215             $form->process( update_field_list => {
1216             foo_date => { format => '%m/%e/%Y', date_start => '10-01-01' } },
1217             params => $params );
1218              
1219             The 'update_field_list' is processed by the 'update_fields' form method,
1220             which can also be used in a form to do specific field updates:
1221              
1222             sub update_fields {
1223             my $self = shift;
1224             $self->field('foo')->temp( 'foo_temp' );
1225             $self->field('bar')->default( 'foo_value' );
1226             $self->next::method();
1227             }
1228              
1229             (Note that you although you can set a field's 'default', you can't set a
1230             field's 'value' directly here, since it will
1231             be overwritten by the validation process. Set the value in a field
1232             validation method.)
1233              
1234             =head3 update_subfields
1235              
1236             Yet another way to provide settings for the field, except this one is intended for
1237             use in roles and compound fields, and is only executed when the form is
1238             initially built. It takes the same field name keys as 'update_field_list', plus
1239             'all', 'by_flag', and 'by_type'.
1240              
1241             sub build_update_subfields {{
1242             all => { tags => { wrapper_tag => 'p' } },
1243             foo => { element_class => 'blue' },
1244             }}
1245              
1246             The 'all' hash key will apply updates to all fields. (Conflicting attributes
1247             in a field definition take precedence.)
1248              
1249             The 'by_flag' hash key will apply updates to fields with a particular flag.
1250             The currently supported subkeys are 'compound', 'contains', and 'repeatable'.
1251             (For repeatable instances, in addition to 'contains' you can also use the
1252             'repeatable' key and the 'init_contains' attribute.)
1253             This is useful for turning on the rendering
1254             wrappers for compounds and repeatables, which are off by default. (The
1255             repeatable instances are wrapped by default.)
1256              
1257             sub build_update_subfields {{
1258             by_flag => { compound => { do_wrapper => 1 } },
1259             by_type => { Select => { element_class => ['sel_elem'] } },
1260             }}
1261              
1262             The 'by_type' hash key will provide values to all fields of a particular
1263             type.
1264              
1265             =head3 defaults
1266              
1267             This is a more specialized version of the 'update_field_list'. It can be
1268             used to provide 'default' settings for fields, in a shorthand way (you don't
1269             have to say 'default' for every field).
1270              
1271             $form->process( defaults => { foo => 'this_foo', bar => 'this_bar' }, ... );
1272              
1273             =head3 active/inactive
1274              
1275             A field can be marked 'inactive' and set to active at new or process time
1276             by specifying the field name in the 'active' array:
1277              
1278             has_field 'foo' => ( type => 'Text', inactive => 1 );
1279             ...
1280             my $form = MyApp::Form->new( active => ['foo'] );
1281             ...
1282             $form->process( active => ['foo'] );
1283              
1284             Or a field can be a normal active field and set to inactive at new or process
1285             time:
1286              
1287             has_field 'bar';
1288             ...
1289             my $form = MyApp::Form->new( inactive => ['foo'] );
1290             ...
1291             $form->process( inactive => ['foo'] );
1292              
1293             Fields specified as active/inactive on new will have the form's inactive/active
1294             arrayref cleared and the field's inactive flag set appropriately, so that
1295             the state will be effective for the life of the form object. Fields specified as
1296             active/inactive on 'process' will have the field's '_active' flag set for the life
1297             of the request (the _active flag will be cleared when the form is cleared).
1298              
1299             The 'sorted_fields' method returns only active fields, sorted according to the
1300             'order' attribute. The 'fields' method returns all fields.
1301              
1302             foreach my $field ( $self->sorted_fields ) { ... }
1303              
1304             You can test whether a field is active by using the field 'is_active' and 'is_inactive'
1305             methods.
1306              
1307             =head3 field_name_space
1308              
1309             Use to look for field during form construction. If a field is not found
1310             with the field_name_space (or HTML::FormHandler/HTML::FormHandlerX),
1311             the 'type' must start with a '+' and be the complete package name.
1312              
1313             =head3 fields
1314              
1315             The array of fields, objects of L<HTML::FormHandler::Field> or its subclasses.
1316             A compound field will itself have an array of fields,
1317             so this is a tree structure.
1318              
1319             =head3 sorted_fields
1320              
1321             Returns those fields from the fields array which are currently active. This
1322             is the method that returns the fields that are looped through when rendering.
1323              
1324             =head3 field($name), subfield($name)
1325              
1326             'field' is the method that is usually called to access a field:
1327              
1328             my $title = $form->field('title')->value;
1329             [% f = form.field('title') %]
1330              
1331             my $city = $form->field('addresses.0.city')->value;
1332              
1333             Pass a second true value to die on errors.
1334              
1335             Since fields are searched for using the form as a base, if you want to find
1336             a sub field in a compound field method, the 'subfield' method may be more
1337             useful, since you can search starting at the current field. The 'chained'
1338             method also works:
1339              
1340             -- in a compound field --
1341             $self->field('media.caption'); # fails
1342             $self->field('media')->field('caption'); # works
1343             $self->subfield('media.caption'); # works
1344              
1345             =head2 Constraints and validation
1346              
1347             Most validation is performed on a per-field basis, and there are a number
1348             of different places in which validation can be performed.
1349              
1350             See also L<HTML::FormHandler::Manual::Validation>.
1351              
1352             =head3 Form class validation for individual fields
1353              
1354             You can define a method in your form class to perform validation on a field.
1355             This method is the equivalent of the field class validate method except it is
1356             in the form class, so you might use this
1357             validation method if you don't want to create a field subclass.
1358              
1359             It has access to the form ($self) and the field.
1360             This method is called after the field class 'validate' method, and is not
1361             called if the value for the field is empty ('', undef). (If you want an
1362             error message when the field is empty, use the 'required' flag and message
1363             or the form 'validate' method.)
1364             The name of this method can be set with 'set_validate' on the field. The
1365             default is 'validate_' plus the field name:
1366              
1367             sub validate_testfield { my ( $self, $field ) = @_; ... }
1368              
1369             If the field name has dots they should be replaced with underscores.
1370              
1371             Note that you can also provide a coderef which will be a method on the field:
1372              
1373             has_field 'foo' => ( validate_method => \&validate_foo );
1374              
1375             =head3 validate
1376              
1377             This is a form method that is useful for cross checking values after they have
1378             been saved as their final validated value, and for performing more complex
1379             dependency validation. It is called after all other field validation is done,
1380             and whether or not validation has succeeded, so it has access to the
1381             post-validation values of all the fields.
1382              
1383             This is the best place to do validation checks that depend on the values of
1384             more than one field.
1385              
1386             =head2 Accessing errors
1387              
1388             Also see L<HTML::FormHandler::Manual::Errors>.
1389              
1390             Set an error in a field with C<< $field->add_error('some error string'); >>.
1391             Set a form error not tied to a specific field with
1392             C<< $self->add_form_error('another error string'); >>.
1393             The 'add_error' and 'add_form_error' methods call localization. If you
1394             want to skip localization for a particular error, you can use 'push_errors'
1395             or 'push_form_errors' instead.
1396              
1397             has_errors - returns true or false
1398             error_fields - returns list of fields with errors
1399             errors - returns array of error messages for the entire form
1400             num_errors - number of errors in form
1401              
1402             Each field has an array of error messages. (errors, has_errors, num_errors,
1403             clear_errors)
1404              
1405             $form->field('title')->errors;
1406              
1407             Compound fields also have an array of error_fields.
1408              
1409             =head2 Clear form state
1410              
1411             The clear method is called at the beginning of 'process' if the form
1412             object is reused, such as when it is persistent in a Moose attribute,
1413             or in tests. If you add other attributes to your form that are set on
1414             each request, you may need to clear those yourself.
1415              
1416             If you do not call the form's 'process' method on a persistent form,
1417             such as in a REST controller's non-POST method, or if you only call
1418             process when the form is posted, you will also need to call C<< $form->clear >>.
1419              
1420             The 'run' method which returns a result object always performs 'clear', to
1421             keep the form object clean.
1422              
1423             =head2 Miscellaneous attributes
1424              
1425             =head3 name
1426              
1427             The form's name. Useful for multiple forms. Used for the form element 'id'.
1428             When 'html_prefix' is set it is used to construct the field 'id'
1429             and 'name'. The default is "form" + a one to three digit random number.
1430             Because the HTML standards have flip-flopped on whether the HTML
1431             form element can contain a 'name' attribute, please set a name attribute
1432             using 'form_element_attr'.
1433              
1434             =head3 init_object
1435              
1436             An 'init_object' may be used instead of the 'item' to pre-populate the values
1437             in the form. This can be useful when populating a form from default values
1438             stored in a similar but different object than the one the form is creating.
1439             The 'init_object' should be either a hash or the same type of object that
1440             the model uses (a DBIx::Class row for the DBIC model). It can be set in a
1441             variety of ways:
1442              
1443             my $form = MyApp::Form->new( init_object => { .... } );
1444             $form->process( init_object => {...}, ... );
1445             has '+init_object' => ( default => sub { { .... } } );
1446             sub init_object { my $self = shift; .... }
1447              
1448             The method version is useful if the organization of data in your form does
1449             not map to an existing or database object in an automatic way, and you need
1450             to create a different type of object for initialization. (You might also
1451             want to do 'update_model' yourself.)
1452              
1453             Also see the 'use_init_obj_over_item' and the 'use_init_obj_when_no_accessor_in_item'
1454             flags, if you want to provide both an item and an init_object, and use the
1455             values from the init_object.
1456              
1457             The 'use_init_obj_when_no_accessor_in_item' flag is particularly useful
1458             when some of the fields in your form come from the database and some
1459             are process or environment type flags that are not in the database. You
1460             can provide defaults from both a database row and an 'init_object.
1461              
1462             =head3 ctx
1463              
1464             Place to store application context for your use in your form's methods.
1465              
1466             =head3 language_handle
1467              
1468             See 'language_handle' and '_build_language_handle' in
1469             L<HTML::FormHandler::TraitFor::I18N>.
1470              
1471             =head3 dependency
1472              
1473             Arrayref of arrayrefs of fields. If one of a group of fields has a
1474             value, then all of the group are set to 'required'.
1475              
1476             has '+dependency' => ( default => sub { [
1477             ['street', 'city', 'state', 'zip' ],] }
1478             );
1479              
1480             =head2 Flags
1481              
1482             =head3 validated, is_valid
1483              
1484             Flag that indicates if form has been validated. You might want to use
1485             this flag if you're doing something in between process and returning,
1486             such as setting a stash key. ('is_valid' is a synonym for this flag)
1487              
1488             $form->process( ... );
1489             $c->stash->{...} = ...;
1490             return unless $form->validated;
1491              
1492             =head3 ran_validation
1493              
1494             Flag to indicate that validation has been run. This flag will be
1495             false when the form is initially loaded and displayed, since
1496             validation is not run until FormHandler has params to validate.
1497              
1498             =head3 verbose, dump, peek
1499              
1500             Flag to dump diagnostic information. See 'dump_fields' and
1501             'dump_validated'. 'Peek' can be useful in diagnosing bugs.
1502             It will dump a brief listing of the fields and results.
1503              
1504             $form->process( ... );
1505             $form->peek;
1506              
1507             =head3 html_prefix
1508              
1509             Flag to indicate that the form name is used as a prefix for fields
1510             in an HTML form. Useful for multiple forms
1511             on the same HTML page. The prefix is stripped off of the fields
1512             before creating the internal field name, and added back in when
1513             returning a parameter hash from the 'fif' method. For example,
1514             the field name in the HTML form could be "book.borrower", and
1515             the field name in the FormHandler form (and the database column)
1516             would be just "borrower".
1517              
1518             has '+name' => ( default => 'book' );
1519             has '+html_prefix' => ( default => 1 );
1520              
1521             Also see the Field attribute "html_name", a convenience function which
1522             will return the form name + "." + field full_name
1523              
1524             =head3 is_html5
1525              
1526             Flag to indicate the fields will render using specialized attributes for html5.
1527             Set to 0 by default.
1528              
1529             =head3 use_defaults_over_obj
1530              
1531             The 'normal' precedence is that if there is an accessor in the item/init_object
1532             that value is used and not the 'default'. This flag makes the defaults of higher
1533             precedence. Mainly useful if providing an empty row on create.
1534              
1535             =head3 use_init_obj_over_item
1536              
1537             If you are providing both an item and an init_object, and want the init_object
1538             to be used for defaults instead of the item.
1539              
1540             =head2 For use in HTML
1541              
1542             form_element_attr - hashref for setting arbitrary HTML attributes
1543             set in form with: sub build_form_element_attr {...}
1544             form_element_class - arrayref for setting form tag class
1545             form_wrapper_attr - hashref for form wrapper element attributes
1546             set in form with: sub build_form_wrapper_attr {...}
1547             form_wrapper_class - arrayref for setting wrapper class
1548             do_form_wrapper - flag to wrap the form
1549             http_method - For storing 'post' or 'get'
1550             action - Store the form 'action' on submission. No default value.
1551             uuid - generates a string containing an HTML field with UUID
1552             form_tags - hashref of tags for use in rendering code
1553             widget_tags - rendering tags to be transferred to fields
1554              
1555             Discouraged (use form_element_attr instead):
1556              
1557             style - adds a 'style' attribute to the form tag
1558             enctype - Request enctype
1559              
1560             Note that the form tag contains an 'id' attribute which is set to the
1561             form name. The standards have been flip-flopping over whether a 'name'
1562             attribute is valid. It can be set with 'form_element_attr'.
1563              
1564             The rendering of the HTML attributes is done using the 'process_attrs'
1565             function and the 'element_attributes' or 'wrapper_attributes' method,
1566             which adds other attributes in for backward compatibility, and calls
1567             the 'html_attributes' hook.
1568              
1569             For HTML attributes, there is a form method hook, 'html_attributes',
1570             which can be used to customize/modify/localize form & field HTML attributes.
1571             Types: element, wrapper, label, form_element, form_wrapper, checkbox_label
1572              
1573             sub html_attributes {
1574             my ( $self, $obj, $type, $attrs, $result ) = @_;
1575              
1576             # obj is either form or field
1577             $attr->{class} = 'label' if $type eq 'label';
1578             $attr->{placeholder} = $self->_localize($attr->{placeholder})
1579             if exists $attr->{placeholder};
1580             return $attr;
1581             }
1582              
1583             Also see the documentation in L<HTML::FormHandler::Field> and in
1584             L<HTML::FormHandler::Manual::Rendering>.
1585              
1586             =head1 SUPPORT
1587              
1588             IRC:
1589              
1590             Join #formhandler on irc.perl.org
1591              
1592             Mailing list:
1593              
1594             http://groups.google.com/group/formhandler
1595              
1596             Code repository:
1597              
1598             http://github.com/gshank/html-formhandler/tree/master
1599              
1600             Bug tracker:
1601              
1602             https://rt.cpan.org/Dist/Display.html?Name=HTML-FormHandler
1603              
1604             =head1 SEE ALSO
1605              
1606             L<HTML::FormHandler::Manual>
1607              
1608             L<HTML::FormHandler::Manual::Tutorial>
1609              
1610             L<HTML::FormHandler::Manual::Intro>
1611              
1612             L<HTML::FormHandler::Manual::Templates>
1613              
1614             L<HTML::FormHandler::Manual::Cookbook>
1615              
1616             L<HTML::FormHandler::Manual::Rendering>
1617              
1618             L<HTML::FormHandler::Manual::Reference>
1619              
1620             L<HTML::FormHandler::Field>
1621              
1622             L<HTML::FormHandler::Model::DBIC>
1623              
1624             L<HTML::FormHandler::Render::Simple>
1625              
1626             L<HTML::FormHandler::Render::Table>
1627              
1628             L<HTML::FormHandler::Moose>
1629              
1630             =head1 CONTRIBUTORS
1631              
1632             gshank: Gerda Shank E<lt>gshank@cpan.orgE<gt>
1633              
1634             zby: Zbigniew Lukasiak E<lt>zby@cpan.orgE<gt>
1635              
1636             t0m: Tomas Doran E<lt>bobtfish@bobtfish.netE<gt>
1637              
1638             augensalat: Bernhard Graf E<lt>augensalat@gmail.comE<gt>
1639              
1640             cubuanic: Oleg Kostyuk E<lt>cub.uanic@gmail.comE<gt>
1641              
1642             rafl: Florian Ragwitz E<lt>rafl@debian.orgE<gt>
1643              
1644             mazpe: Lester Ariel Mesa
1645              
1646             dew: Dan Thomas
1647              
1648             koki: Klaus Ita
1649              
1650             jnapiorkowski: John Napiorkowski
1651              
1652             lestrrat: Daisuke Maki
1653              
1654             hobbs: Andrew Rodland
1655              
1656             Andy Clayton
1657              
1658             boghead: Bryan Beeley
1659              
1660             Csaba Hetenyi
1661              
1662             Eisuke Oishi
1663              
1664             Lian Wan Situ
1665              
1666             Murray
1667              
1668             Nick Logan
1669              
1670             Vladimir Timofeev
1671              
1672             diegok: Diego Kuperman
1673              
1674             ijw: Ian Wells
1675              
1676             amiri: Amiri Barksdale
1677              
1678             ozum: Ozum Eldogan
1679              
1680             lukast: Lukas Thiemeier
1681              
1682             Initially based on the source code of L<Form::Processor> by Bill Moseley
1683              
1684             =head1 AUTHOR
1685              
1686             FormHandler Contributors - see HTML::FormHandler
1687              
1688             =head1 COPYRIGHT AND LICENSE
1689              
1690             This software is copyright (c) 2014 by Gerda Shank.
1691              
1692             This is free software; you can redistribute it and/or modify it under
1693             the same terms as the Perl 5 programming language system itself.
1694              
1695             =cut