File Coverage

blib/lib/Data/MuForm.pm
Criterion Covered Total %
statement 237 278 85.2
branch 55 80 68.7
condition 19 29 65.5
subroutine 71 83 85.5
pod 10 72 13.8
total 392 542 72.3


line stmt bran cond sub pod time code
1             package Data::MuForm;
2             # ABSTRACT: Data validator and form processor
3              
4 81     81   155551 use Moo;
  81         26163  
  81         447  
5 81     81   21057 use Data::MuForm::Meta;
  81         102  
  81         457  
6              
7             with 'Data::MuForm::Model';
8             with 'Data::MuForm::Fields';
9             with 'Data::MuForm::Common';
10              
11 81     81   48947 use Types::Standard -types;
  81         3033368  
  81         813  
12 81     81   246258 use Class::Load ('load_optional_class');
  81         789541  
  81         4508  
13 81     81   25519 use Data::Clone ('data_clone');
  81         67441  
  81         3590  
14 81     81   28073 use Data::MuForm::Params;
  81         389  
  81         2271  
15 81     81   28830 use Data::MuForm::Localizer;
  81         143  
  81         2838  
16 81     81   34545 use MooX::Aliases;
  81         187073  
  81         421  
17 81     81   44787 use Data::MuForm::Merge ('merge');
  81         131  
  81         197032  
18              
19             our $VERSION = '0.03';
20              
21              
22             has 'name' => ( is => 'ro', builder => 'build_name');
23             sub build_name {
24 109     109 0 2035 my $self = shift;
25 109         211 my $class = ref $self;
26 109         492 my ( $name ) = ( $class =~ /.*::(.*)$/ );
27 109   66     336 $name ||= $class;
28 109         1630 return $name;
29             }
30             has 'id' => ( is => 'ro', lazy => 1, builder => 'build_id' );
31 1     1 0 309 sub build_id { $_[0]->name }
32             has 'submitted' => ( is => 'rw', default => undef ); # three values: 0, 1, undef
33             has 'processed' => ( is => 'rw', default => 0 );
34             #has 'no_init_process' => ( is => 'rw', default => 0 );
35              
36             has 'ran_validation' => ( is => 'rw', default => 0 );
37             has '_params' => ( is => 'rw', isa => HashRef, default => sub {{}}, alias => 'data' );
38 71     71 0 139 sub clear_params { $_[0]->{_params} = {} }
39 170     170 0 215 sub has_params { my $self = shift; return scalar keys %{$self->{_params}}; }
  170         164  
  170         1196  
40             sub params {
41 314     314 1 360 my ( $self, $params ) = @_;
42 314 100       596 if ( $params ) {
43 145         520 $params = $self->munge_params($params);
44 145         255 $self->{_params} = $params;
45             }
46 314         1290 return $self->{_params};
47             }
48             has 'field_prefix' => ( is => 'rw' );
49              
50             has 'form_meta_fields' => ( is => 'rw', isa => ArrayRef, default => sub {[]} );
51             has 'index' => ( is => 'rw', isa => HashRef, default => sub {{}} );
52 566     566 0 895 sub add_to_index { my ( $self, $field_name, $field ) = @_; $self->{index}->{$field_name} = $field; }
  566         2400  
53 4453     4453 1 21848 sub form { shift }
54 586     586 0 1849 sub is_form {1}
55       65 0   sub parent { }
56             has 'ctx' => ( is => 'rw', weak_ref => 1 );
57             # init_values can be a blessed object or a hashref
58             has 'init_values' => ( is => 'rw', alias => 'init_object' );
59 71     71 0 120 sub clear_init_values { $_[0]->{init_values} = undef }
60             sub has_init_values {
61 23     23 0 1179 my $self = shift;
62 23         50 my $init_obj = $self->init_values;
63 23 100       92 return 0 unless defined $init_obj;
64 7 50 33     46 return 0 if ref $init_obj eq 'HASH' and ! scalar keys %$init_obj;
65 7         24 return 1;
66             }
67             has 'fill_from_object_source' => ( is => 'rw', );
68             has 'active' => ( is => 'rw', clearer => 'clear_active', predicate => 'has_active' );
69             has 'inactive' => ( is => 'rw', clearer => 'clear_inactive', predicate => 'has_inactive' );
70 1454     1454 0 7646 sub full_name { '' }
71 15     15 0 307 sub full_accessor { '' }
72 58     58 1 11238 sub fif { shift->fields_fif(@_) }
73              
74             has '_repeatable_fields' => (
75             is => 'rw',
76             default => sub {[]},
77             );
78             sub add_repeatable_field {
79 35     35 0 241 my ( $self, $field ) = @_;
80 35         49 push @{$self->_repeatable_fields}, $field;
  35         196  
81             }
82             sub has_repeatable_fields {
83 64     64 0 89 my ( $self, $field ) = @_;
84 64         64 return scalar @{$self->_repeatable_fields};
  64         454  
85             }
86             sub all_repeatable_fields {
87 3     3 0 11 my $self = shift;
88 3         5 return @{$self->_repeatable_fields};
  3         14  
89             }
90              
91             #========= Rendering ==========
92             has 'http_method' => ( is => 'ro', default => 'post' );
93             has 'action' => ( is => 'rw' );
94             has 'enctype' => ( is => 'rw' );
95             has 'renderer_class' => ( is => 'ro', builder => 'build_renderer_class' );
96 132     132 0 3779 sub build_renderer_class { 'Data::MuForm::Renderer::Base' }
97             has 'renderer' => ( is => 'rw', lazy => 1, builder => 'build_renderer' );
98             sub build_renderer {
99 132     132 0 24859 my $self = shift;
100 132 50       1097 my $renderer_class = load_optional_class($self->renderer_class) ? $self->renderer_class : 'Data::MuForm::Renderer::Base';
101             my $renderer = $renderer_class->new(
102             localizer => $self->localizer,
103             form => $self->form,
104 132         9624 %{$self->renderer_args},
  132         1769  
105             );
106 132         690 return $renderer;
107             }
108             has 'renderer_args' => ( is => 'ro', isa => HashRef, builder => 'build_renderer_args' );
109 131     131 0 3027 sub build_renderer_args {{}}
110             has 'render_args' => ( is => 'rw', lazy => 1, isa => HashRef, builder => 'build_render_args' );
111 7     7 0 3407 sub build_render_args {{}}
112             sub base_render_args {
113 7     7 0 12 my $self = shift;
114 7   50     96 my $args = {
115             name => $self->name,
116             id => $self->name,
117             form_errors => $self->form_errors || [],
118             method => $self->http_method,
119             };
120 7 50       2672 $args->{action} = $self->action if $self->action;
121 7 50       54 $args->{enctype} = $self->enctype if $self->enctype;
122 7         61 return $args;
123             }
124              
125              
126             #========= Errors ==========
127             has 'form_errors' => ( is => 'rw', isa => ArrayRef, default => sub {[]} );
128 71     71 0 162 sub clear_form_errors { $_[0]->{form_errors} = []; }
129 5     5 0 7 sub all_form_errors { return @{$_[0]->form_errors}; }
  5         36  
130 5     5 0 914 sub has_form_errors { scalar @{$_[0]->form_errors} }
  5         56  
131 7     7 0 220 sub num_form_errors { scalar @{$_[0]->form_errors} }
  7         89  
132 0     0 0 0 sub push_form_error { push @{$_[0]->form_errors}, $_[1] }
  0         0  
133             sub add_form_error {
134 0     0 0 0 my ( $self, @message ) = @_;
135 0         0 my $out;
136 0 0       0 if ( $message[0] !~ /{/ ) {
137 0         0 $out = $self->localizer->loc_($message[0]);
138             }
139             else {
140 0         0 $out = $self->localizer->loc_x(@message);
141             }
142 0         0 return $self->push_form_error($out);
143             }
144              
145             sub has_errors {
146 16     16 0 1457 my $self = shift;
147 16   66     52 return $self->has_error_fields || $self->has_form_errors;
148             }
149             sub num_errors {
150 7     7 0 1521 my $self = shift;
151 7         59 return $self->num_error_fields + $self->num_form_errors;
152             }
153 0     0 0 0 sub get_errors { shift->errors }
154              
155             sub all_errors {
156 5     5 0 394 my $self = shift;
157 5         35 my @errors = $self->all_form_errors;
158 5         2031 push @errors, map { $_->all_errors } $self->all_error_fields;
  11         188  
159 5         37 return @errors;
160             }
161 2     2 1 256 sub errors { [$_[0]->all_errors] }
162              
163             sub errors_by_id {
164 1     1 0 1 my $self = shift;
165 1         2 my %errors;
166 1         8 $errors{$_->id} = [$_->all_errors] for $self->all_error_fields;
167 1         5 return \%errors;
168             }
169              
170             sub errors_by_name {
171 1     1 0 2 my $self = shift;
172 1         2 my %errors;
173 1         3 $errors{$_->prefixed_name} = [$_->all_errors] for $self->all_error_fields;
174 1         20 return \%errors;
175             }
176              
177             #========= Localization ==========
178              
179             has 'language' => ( is => 'rw', builder => 'build_language' );
180 132     132 0 4142 sub build_language { 'en' }
181             has 'localizer' => ( is => 'rw', lazy => 1, builder => 'build_localizer' );
182             sub build_localizer {
183 132     132 0 25341 my $self = shift;
184 132         2471 return Data::MuForm::Localizer->new(
185             language => $self->language,
186             );
187             }
188              
189             #========= Messages ==========
190             has 'messages' => ( is => 'rw', isa => HashRef, builder => 'build_messages' );
191 131     131 0 2626 sub build_messages {{}}
192 1     1   429 sub _get_form_message { my ($self, $msgname) = @_; return $self->messages->{$msgname}; }
  1         17  
193 38     38   317 sub _has_form_message { my ($self, $msgname) = @_; return exists $self->messages->{$msgname}; }
  38         413  
194 0     0 0 0 sub set_message { my ( $self, $msgname, $msg) = @_; $self->messages->{$msgname} = $msg; }
  0         0  
195             my $class_messages = {};
196             sub get_class_messages {
197 0     0 0 0 return $class_messages;
198             }
199             sub get_message {
200 0     0 0 0 my ( $self, $msg ) = @_;
201 0 0       0 return $self->_get_form_message($msg) if $self->_has_form_message($msg);
202 0         0 return $self->get_class_messages->{$msg};
203             }
204             sub all_messages {
205 0     0 0 0 my $self = shift;
206 0         0 return { %{$self->get_class_messages}, %{$self->messages} };
  0         0  
  0         0  
207             }
208              
209              
210             #========= Methods ==========
211             sub BUILD {
212 132     132 0 697 my $self = shift;
213              
214             # instantiate
215 132         1253 $self->localizer;
216 132         56523 $self->renderer;
217 132         889 $self->build_fields;
218 131         1561 $self->after_build_fields;
219             # put various defaults into fields. Should this happen?
220             # it will be re-done on the first process call
221 131         1734 $self->fill_values;
222             }
223              
224             sub process {
225 169     169 1 55945 my $self = shift;
226              
227 169 100       1135 $self->clear if $self->processed;
228 169         633 $self->setup(@_);
229 169         604 $self->after_setup;
230 169 100       740 $self->validate_form if $self->submitted;
231              
232 169 100       513 $self->update_model if ( $self->validated );
233 169 100       1184 $self->after_update_model if ( $self->validated );
234              
235 169         1380 $self->processed(1);
236 169         296 return $self->validated;
237             }
238              
239             sub check {
240 0     0 1 0 my $self = shift;
241 0 0       0 $self->clear if $self->processed;
242 0         0 $self->setup(@_);
243 0         0 $self->after_setup;
244 0 0       0 $self->validate_form if $self->submitted;
245 0         0 $self->processed(1);
246 0         0 return $self->check_result;
247             }
248              
249             sub check_result {
250 0     0 0 0 my $self = shift;
251 0         0 return $self->validated;
252             }
253              
254             sub clear {
255 71     71 0 97 my $self = shift;
256 71         270 $self->clear_params;
257 71         334 $self->clear_filled_from;
258 71         11839 $self->submitted(undef);
259 71         204 $self->model(undef);
260 71         384 $self->clear_init_values;
261 71         200 $self->fill_from_object_source(undef);
262 71         755 $self->ctx(undef);
263 71         12232 $self->processed(0);
264 71         162 $self->ran_validation(0);
265              
266             # this will recursively clear field data
267 71         311 $self->clear_data;
268 71         3495 $self->clear_form_errors;
269 71         180 $self->clear_error_fields;
270             }
271              
272              
273             sub setup {
274 169     169 1 350 my ( $self, @args ) = @_;
275              
276 169 100       702 if ( @args == 1 ) {
    100          
277 38         166 $self->params( $args[0] );
278             }
279             elsif ( @args > 1 ) {
280 115         243 my $hashref = {@args};
281 115         148 while ( my ( $key, $value ) = each %{$hashref} ) {
  278         1488  
282 163 50       852 warn "invalid attribute '$key' passed to setup_form"
283             unless $self->can($key);
284 163         470 $self->$key($value);
285             }
286             }
287             # set_active
288 169         1396 $self->set_active;
289              
290             # customization hook
291 169         789 $self->in_setup;
292              
293             # set the submitted flag
294 169 100 100     497 $self->submitted(1) if ( $self->has_params && ! defined $self->submitted );
295              
296             # fill the 'value' attributes from model, init_values or fields
297 169         359 $self->fill_values;
298              
299             # fill in the input attribute
300 169         3068 my $params = data_clone( $self->params );
301 169 100       599 if ( $self->submitted ) {
302 105         585 $self->fill_from_params($params, 1 );
303             # if the params submitted don't match fields, it shouldn't count as 'submitted'
304 105 100       101 if ( ! scalar keys %{$self->input} ) {
  105         499  
305 2         8 $self->submitted(0);
306             }
307             }
308              
309             }
310              
311             sub fill_values {
312 300     300 0 337 my $self = shift;
313              
314             # these fill the 'value' attributes
315 300 100 66     1062 if ( $self->model && $self->use_model_for_defaults ) {
    100          
    100          
316 9         30 $self->fill_from_object_source('model');
317 9         20 $self->fill_from_object($self->model);
318             }
319             elsif ( $self->init_values ) {
320 41         923 $self->fill_from_object_source('init_values');
321 41         181 $self->fill_from_object($self->init_values );
322             }
323             elsif ( !$self->submitted ) {
324             # no initial object. empty form must be initialized
325 155         2360 $self->fill_from_fields;
326             }
327             }
328              
329       169 0   sub in_setup { }
330       169 0   sub after_setup { }
331       128 0   sub after_build_fields { }
332              
333             sub update_model {
334 62     62 0 14824 my $self = shift;
335             }
336              
337              
338             sub munge_params {
339 145     145 0 181 my ( $self, $params, $attr ) = @_;
340              
341 145         1985 my $_fix_params = Data::MuForm::Params->new;
342 145         40115 my $new_params = $_fix_params->expand_hash($params);
343 145 50       725 if ( $self->field_prefix ) {
344 0         0 $new_params = $new_params->{ $self->field_prefix };
345             }
346 145 50       327 $new_params = {} if !defined $new_params;
347 145         511 return $new_params;
348             }
349              
350             sub set_active {
351 169     169 0 973 my $self = shift;
352 169 100       672 if( $self->has_active ) {
353 1         2 foreach my $fname (@{$self->active}) {
  1         4  
354 1         4 my $field = $self->field($fname);
355 1 50       7 if ( $field ) {
356 1         6 $field->_active(1);
357             }
358             else {
359 0         0 warn "field $fname not found to set active";
360             }
361             }
362 1         10 $self->clear_active;
363             }
364 169 100       982 if( $self->has_inactive ) {
365 2         1 foreach my $fname (@{$self->inactive}) {
  2         8  
366 2         6 my $field = $self->field($fname);
367 2 50       10 if ( $field ) {
368 2         8 $field->_active(0);
369             }
370             else {
371 0         0 warn "field $fname not found to set inactive";
372             }
373             }
374 2         24 $self->clear_inactive;
375             }
376             }
377              
378             #====================================================================
379             # Validation
380             #====================================================================
381              
382             sub validate_form {
383 103     103 0 116 my $self = shift;
384              
385 103         400 $self->fields_validate;
386 103         387 $self->validate; # hook
387 103         387 $self->validate_model; # hook
388 103         554 $self->fields_set_value;
389             # $self->build_errors;
390              
391             # 'validated' depends on no errors...
392              
393 103         261 $self->submitted(undef);
394 103         410 $self->ran_validation(1);
395             }
396              
397             # hook for child forms
398       98 1   sub validate { }
399              
400             # hook for model validation
401       103 0   sub validate_model { }
402              
403 564   100 564 1 2172 sub validated { my $self = shift; return $self->ran_validation && ! $self->has_error_fields; }
  564         2070  
404              
405       155 0   sub get_default_value { }
406              
407             sub transform_and_set_input {
408 105     105 0 165 my ($self, $input) = @_;
409 105         419 $self->input($input);
410             }
411              
412             sub get_result {
413 1     1 0 1 my $self = shift;
414 1         13 my $result = {
415             method => $self->http_method,
416             action => $self->action,
417             name => $self->name,
418             id => $self->id,
419             submitted => $self->submitted,
420             validated => $self->validated,
421             };
422 1 50       5 $result->{form_errors} = $self->form_errors if $self->has_form_errors;
423 1 50       470 $result->{errors} = $self->errors if $self->has_errors;
424 1         8 return $result;
425             }
426              
427 1     1 0 693 sub results { shift->fields_get_results }
428              
429             sub add_field {
430 2     2 1 11 my ( $self, %field_attr ) = @_;
431 2         7 my $field = $self->_make_field( \%field_attr );
432             # make it the last field.
433 2 100       5 unless ( exists $field_attr{order} ) {
434 1         13 my $order = $field->parent->_get_highest_field_order;
435 1         3 $field->order($order + 5);
436             }
437 2         6 return $field;
438             }
439              
440             sub after_update_model {
441 64     64 0 1545 my $self = shift;
442             # This an attempt to reload the repeatable
443             # relationships after the database is updated, so that we get the
444             # primary keys of the repeatable elements. Otherwise, if a form
445             # is re-presented, repeatable elements without primary keys may
446             # be created again. There is no reliable way to connect up
447             # existing repeatable elements with their db-created primary keys.
448 64 100 100     280 if ( $self->has_repeatable_fields && $self->model ) {
449 2         51 foreach my $field ( $self->all_repeatable_fields ) {
450 4 50       9 next unless $field->is_active;
451             # Check to see if there are any repeatable subfields with
452             # null primary keys, so we can skip reloading for the case
453             # where all repeatables have primary keys.
454 4         4 my $needs_reload = 0;
455 4         9 foreach my $sub_field ( $field->all_fields ) {
456 2 100 66     14 if ( $sub_field->is_compound && $sub_field->has_primary_key ) {
457 1         1 foreach my $pk_field ( @{ $sub_field->primary_key } ) {
  1         18  
458 1 50       12 $needs_reload++ unless $pk_field->fif;
459             }
460 1 50       3 last if $needs_reload;
461             }
462             }
463 4 100       14 next unless $needs_reload;
464 1         4 my @names = split( /\./, $field->full_name );
465 1         4 my $rep_model = $self->find_sub_obj( $self->model, \@names );
466             # $rep_model is a single row or an array of rows or undef
467             # If we found a database model for the repeatable, initialize
468             # with 'fill_from_object'
469 1 50       4 if ( ref $rep_model ) {
470 1         14 my $parent = $field->parent;
471 1         6 $field->init_state;
472 1         31 $field->fill_from_object( $rep_model );
473             }
474             }
475             }
476             }
477              
478             # model for render_hook in forms to modify render_args for rendering
479             sub render_hook {
480 198     198 0 340 my ( $self, $renderer, $rargs ) = @_;
481             }
482              
483             sub get_render_args {
484 7     7 0 19 my ( $self, %args ) = @_;
485 7         38 my $render_args = merge( $self->base_render_args, $self->render_args );
486 7         24 $render_args = merge( $render_args, \%args );
487 7         20 return $render_args;
488             }
489              
490             sub render {
491 6     6 0 542 my ( $self, $rargs ) = @_;
492 6         42 my $render_args = $self->get_render_args(%$rargs, rendering => 'form');
493 6         115 return $self->renderer->render_form($render_args, $self->sorted_fields);
494             }
495              
496             sub render_start {
497 1     1 0 372 my ( $self, $rargs ) = @_;
498 1         6 my $render_args = $self->get_render_args(%$rargs, rendering => 'form_start');
499 1         25 return $self->renderer->render_start($render_args);
500             }
501              
502             sub render_end {
503 0     0 0   my ( $self, $rargs ) = @_;
504 0           my $render_args = $self->get_render_args(%$rargs, rendering => 'form_end');
505 0           return $self->renderer->render_end($render_args);
506             }
507              
508             sub render_errors {
509 0     0 0   my ( $self, $rargs ) = @_;
510 0           my $render_args = $self->get_render_args(%$rargs, rendering => 'form_errors');
511 0           return $self->renderer->render_form_errors($render_args);
512             }
513              
514             # just for top level fields
515             sub render_hidden_fields {
516 0     0 0   my $self = shift;
517 0           foreach my $field ( $self->all_sorted_fields ) {
518 0 0 0       if ( $field->type eq 'Hidden' && $field->has_value ) {
519 0           $field->render_element;
520             }
521             }
522             }
523              
524             1;
525              
526             __END__
527              
528             =pod
529              
530             =encoding UTF-8
531              
532             =head1 NAME
533              
534             Data::MuForm - Data validator and form processor
535              
536             =head1 VERSION
537              
538             version 0.03
539              
540             =head1 SYNOPSIS
541              
542             Moo conversion of HTML::FormHandler, with more emphasis on data
543             validation and a new way of rendering. The core behavior is basically
544             the same as FormHandler, but some names have been changed, some
545             functionality removed, some added. It will be necessary to change
546             your forms to convert to MuForm, but it shouldn't be difficult.
547              
548             See the manual at L<Data::MuForm::Manual>, and in particular
549             L<Data::MuForm::Manual::FormHandlerDiff> if you're already using
550             FormHandler.
551              
552             my $validator = MyApp::Form::Test->new;
553             $validator->check( data => $params );
554             or
555             my $form = MyApp::Form::User->new;
556             $form->process( model => $row, params => $params );
557             my $rendered_form = $form->render;
558             if( $form->validated ) {
559             # perform validated form actions
560             }
561             else {
562             # perform non-validated actions
563             }
564              
565             An example of a custom form class:
566              
567             package MyApp::Form::User;
568             use Moo;
569             use Data::MuForm::Meta;
570             extends 'Data::MuForm';
571              
572             has_field 'name' => ( type => 'Text' );
573             has_field 'age' => ( type => 'Integer', apply => [ MinimumAge ] );
574             has_field 'hobbies' => ( type => 'Multiple' );
575             has_field 'address' => ( type => 'Compound' );
576             has_field 'address.city' => ( type => 'Text' );
577             has_field 'address.state' => ( type => 'Select' );
578             has_field 'email' => ( type => 'Email' );
579              
580             A dynamic form - one that does not use a custom form class - may be
581             created using the 'field_list' attribute to set fields:
582              
583             my $validator = Data::MuForm->new(
584             name => 'login_form',
585             field_list => [
586             'username' => {
587             type => 'Text',
588             apply => [ { check => qr/^[0-9a-z]*\z/,
589             message => 'Contains invalid characters' } ],
590             },
591             'password' => { apply => [ Password ] },
592             ],
593             );
594              
595             =head1 DESCRIPTION
596              
597             This documentation is mainly of Data::MuForm class attributes and methods.
598             For general-purpose documentation see L<Data::MuForm::Manual>.
599              
600             =head1 NAME
601              
602             Data::MuForm
603              
604             =head1 ATTRIBUTES and METHODS
605              
606             =head2 Creating a form with 'new'
607              
608             The new constructor takes name/value pairs:
609              
610             MyForm->new( action => $action );
611              
612             No attributes are required on new. Normally you would pass in persistent
613             attributes on 'new' (such as 'schema') and request/process related attributes on 'process'.
614              
615             The form's fields will be built from the form definitions on new.
616              
617             The 'field_list' is passed in on 'new' because fields are build at construction time.
618             It can also be a method in the form class.
619              
620             field_list - an array of field definitions
621              
622             =head2 process & check
623              
624             Data to be validated/processed:
625              
626             data $validator->check( data => {} );
627             params $form->process( params => {} );
628              
629             The 'init_values' hashref can be passed in, but can also be set in the form class:
630              
631             init_values - a hashref or object to provide initial values
632              
633             Passed in on process with a DBIC model MuForm class:
634              
635             model - database row object
636              
637             See the model class for more information about 'model', 'model_id',
638             'model_class', and 'schema' (for the DBIC model).
639             L<Data::MuForm::Model::DBIC>.
640              
641             =head2 Processing
642              
643             =head3 check
644              
645             Use the 'check' method to perform validation on your data:
646              
647             my $result = $validator->check( data => { ... } );
648              
649             The 'result' returned from 'check' is $form->validated, but you can
650             override the 'check_result' method in the form to return data in
651             whatever format you wish.
652              
653             =head3 process
654              
655             Call the 'process' method on your form to perform validation and
656             update. A database form must have either a model (row object) or
657             a schema, model_id (row primary key), and model_class (usually set in the form).
658             A non-database form requires only parameters.
659              
660             $form->process( model => $book, params => $c->req->parameters );
661             $form->process( model_id => $model_id,
662             schema => $schema, params => $c->req->parameters );
663             $form->process( params => $c->req->parameters );
664              
665             This process method returns the 'validated' flag (C<< $form->validated >>).
666             If it is a database form and the form validates, the database row
667             will be updated.
668              
669             After the form has been processed, you can get a parameter hashref suitable
670             for using to fill in the form from C<< $form->fif >>.
671             A hash of inflated values (that would be used to update the database for
672             a database form) can be retrieved with C<< $form->value >>.
673              
674             If you don't want to update the database, you can use the 'check' method instead.
675              
676             =head3 params
677              
678             Parameters are passed in when you call 'process'.
679             HFH gets data to validate and store in the database from the params hash.
680             If the params hash is empty, no validation is done, so it is not necessary
681             to check for POST before calling C<< $form->process >>. (Although see
682             the 'posted' option for complications.)
683              
684             Params can either be in the form of CGI/HTTP style params:
685              
686             {
687             user_name => "Joe Smith",
688             occupation => "Programmer",
689             'addresses.0.street' => "999 Main Street",
690             'addresses.0.city' => "Podunk",
691             'addresses.0.country' => "UT",
692             'addresses.0.address_id' => "1",
693             'addresses.1.street' => "333 Valencia Street",
694             'addresses.1.city' => "San Francisco",
695             'addresses.1.country' => "UT",
696             'addresses.1.address_id' => "2",
697             }
698              
699             or as structured data in the form of hashes and lists:
700              
701             {
702             addresses => [
703             {
704             city => 'Middle City',
705             country => 'GK',
706             address_id => 1,
707             street => '101 Main St',
708             },
709             {
710             city => 'DownTown',
711             country => 'UT',
712             address_id => 2,
713             street => '99 Elm St',
714             },
715             ],
716             'occupation' => 'management',
717             'user_name' => 'jdoe',
718             }
719              
720             CGI style parameters will be converted to hashes and lists for HFH to
721             operate on.
722              
723             =head3 submitted
724              
725             Note that MuForm by default uses empty params as a signal that the
726             form has not actually been submitted, and so will not attempt to validate
727             a form with empty params. Most of the time this works OK, but if you
728             have a small form with only the controls that do not return a post
729             parameter if unselected (checkboxes and select lists), then the form
730             will not be validated if everything is unselected. For this case you
731             can either add a hidden field as an 'indicator', or use the 'submitted' flag:
732              
733             $form->process( submitted => ($c->req->method eq 'POST'), params => ... );
734              
735             The 'submitted' flag also works to prevent validation from being performed
736             if there are extra params in the params hash and it is not a 'POST' request.
737              
738             =head2 Getting data out
739              
740             =head3 fif (fill in form)
741              
742             If you don't use MuForm rendering and want to fill your form values in
743             using some other method (such as with HTML::FillInForm or using a template)
744             this returns a hash of values that are equivalent to params which you may
745             use to fill in your form.
746              
747             The fif value for a 'title' field in a TT form:
748              
749             [% form.fif.title %]
750              
751             Or you can use the 'fif' method on individual fields:
752              
753             [% form.field('title').fif %]
754              
755             If you use MuForm to render your forms or field you probably won't use
756             these methods.
757              
758             =head3 value
759              
760             Returns a hashref of all field values. Useful for non-database forms, or if
761             you want to update the database yourself. The 'fif' method returns
762             a hashref with the field names for the keys and the field's 'fif' for the
763             values; 'value' returns a hashref with the field accessors for the keys, and the
764             field's 'value' (possibly inflated) for the values.
765              
766             Forms containing arrays to be processed with L<Data::MuForm::Field::Repeatable>
767             will have parameters with dots and numbers, like 'addresses.0.city', while the
768             values hash will transform the fields with numbers to arrays.
769              
770             =head2 Accessing and setting up fields
771              
772             Fields are declared with a number of attributes which are defined in
773             L<Data::MuForm::Field>. If you want additional attributes you can
774             define your own field classes (or apply a role to a field class - see
775             L<Data::MuForm::Manual::Cookbook>). The field 'type' (used in field
776             definitions) is the short class name of the field class, used when
777             searching the 'field_namespace' for the field class.
778              
779             =head3 has_field
780              
781             The most common way of declaring fields is the 'has_field' syntax.
782             Using the 'has_field' syntax sugar requires C< use Data::MuForm::Meta; >.
783             See L<Data::MuForm::Manual::Intro>
784              
785             use Moo;
786             use Data::MuForm::Meta;
787             has_field 'field_name' => ( type => 'FieldClass', .... );
788              
789             =head3 field_list
790              
791             A 'field_list' is an array of field definitions which can be used as an
792             alternative to 'has_field' in small, dynamic forms to create fields.
793              
794             field_list => [
795             field_one => {
796             type => 'Text',
797             required => 1
798             },
799             field_two => 'Text,
800             ]
801              
802             The field_list array takes elements which are either a field_name key
803             pointing to a 'type' string or a field_name key pointing to a
804             hashref of field attributes. You can also provide an array of
805             hashref elements with the name as an additional attribute.
806             The field list can be set inside a form class, when you want to
807             add fields to the form depending on some other state, although
808             you can also create all the fields and set some of them inactive.
809              
810             sub field_list {
811             my $self = shift;
812             my $fields = $self->schema->resultset('SomeTable')->
813             search({user_id => $self->user_id, .... });
814             my @field_list;
815             while ( my $field = $fields->next )
816             {
817             < create field list >
818             }
819             return \@field_list;
820             }
821              
822             =head2 add_field
823              
824             You can add an additional field with $form->add_field.
825              
826             my $order = $form->field('foo')->order + 1;
827             $form->add_field(
828             name => 'my_cb',
829             type => 'Checkbox',
830             order => $order,
831             );
832              
833             It will be ordered as the last field unless you set the 'order'
834             attribute. Form fields are automatically ordered by 5 (i.e. 5, 10, 15, etc).
835              
836             =head3 active/inactive
837              
838             A field can be marked 'inactive' and set to active at process time
839             by specifying the field name in the 'active' array:
840              
841             has_field 'foo' => ( type => 'Text', inactive => 1 );
842             ...
843             my $form = MyApp::Form->new;
844             $form->process( active => ['foo'] );
845              
846             Or a field can be a normal active field and set to inactive at process
847             time:
848              
849             has_field 'bar';
850             ...
851             my $form = MyApp::Form->new;
852             $form->process( inactive => ['foo'] );
853              
854             Fields specified as active/inactive on 'process' will have the flag
855             flag cleared when the form is cleared (on the next process/check call).
856              
857             The 'sorted_fields' method returns only active fields, sorted according to the
858             'order' attribute. The 'fields' method returns all fields.
859              
860             foreach my $field ( $self->all_sorted_fields ) { ... }
861              
862             You can test whether a field is active by using the field 'is_active' and 'is_inactive'
863             methods.
864              
865             =head3 field_namespace
866              
867             Use to look for field during form construction. If a field is not found
868             with the field_namespace (or Data::MuForm/Data::MuFormX),
869             the 'type' must start with a '+' and be the complete package name.
870              
871             =head3 fields
872              
873             The array of fields, objects of L<Data::MuForm::Field> or its subclasses.
874             A compound field will itself have an array of fields,
875             so this is a tree structure.
876              
877             =head3 sorted_fields
878              
879             Returns those fields from the fields array which are currently active, ordered
880             by the 'order' attribute. This is the method that returns the fields that are
881             looped through when rendering.
882              
883             =head3 field($name), subfield($name)
884              
885             'field' is the method that is usually called to access a field:
886              
887             my $title = $form->field('title')->value;
888             [% f = form.field('title') %]
889              
890             my $city = $form->field('addresses.0.city')->value;
891              
892             Since fields are searched for using the form as a base, if you want to find
893             a sub field in a compound field method, the 'subfield' method may be more
894             useful, since you can search starting at the current field. The 'chained'
895             method also works:
896              
897             -- in a compound field --
898             $self->field('media.caption'); # fails
899             $self->field('media')->field('caption'); # works
900             $self->subfield('media.caption'); # works
901              
902             =head2 Constraints and validation
903              
904             Most validation is performed on a per-field basis, and there are a number
905             of different places in which validation can be performed.
906              
907             See also L<Data::MuForm::Manual::Validation>.
908              
909             =head3 Class validation for individual fields
910              
911             You can define a method in your class to perform validation on a field.
912             This method is the equivalent of the field class validate method except it is
913             in the validator/form class, so you might use this
914             validation method if you don't want to create a field subclass.
915              
916             It has access to the form ($self) and the field.
917             This method is called after the field class 'validate' method, and is not
918             called if the value for the field is empty ('', undef). (If you want an
919             error message when the field is empty, use the 'required' flag and message
920             or the form 'validate' method.)
921             The name of this method can be set with 'set_validate' on the field. The
922             default is 'validate_' plus the field name:
923              
924             sub validate_testfield { my ( $self, $field ) = @_; ... }
925              
926             If the field name has dots they should be replaced with underscores.
927              
928             Note that you can also provide a coderef which will be a method on the field:
929              
930             has_field 'foo' => ( methods => { validate => \&validate_foo } );
931              
932             =head3 validate
933              
934             This is a form method that is useful for cross checking values after they have
935             been saved as their final validated value, and for performing more complex
936             dependency validation. It is called after all other field validation is done,
937             and whether or not validation has succeeded, so it has access to the
938             post-validation values of all the fields.
939              
940             This is the best place to do validation checks that depend on the values of
941             more than one field.
942              
943             =head2 Accessing errors
944              
945             Also see L<Data::MuForm::Manual::Errors>.
946              
947             Set an error in a field with C<< $field->add_error('some error string'); >>.
948             Set a form error not tied to a specific field with
949             C<< $self->add_form_error('another error string'); >>.
950             The 'add_error' and 'add_form_error' methods call localization. If you
951             want to skip localization for a particular error, you can use 'push_error'
952             or 'push_form_errors' instead.
953              
954             has_errors - returns true or false
955             error_fields - returns list of fields with errors
956             errors - returns array of error messages for the entire form
957             num_errors - number of errors in form
958              
959             Each field has an array of error messages. (errors, has_errors, num_errors,
960             clear_errors)
961              
962             $form->field('title')->errors;
963              
964             Compound fields also have an array of error_fields.
965              
966             =head2 Clear form state
967              
968             The clear method is called at the beginning of 'process' if the form
969             object is reused, such as when it is persistent,
970             or in tests. If you add other attributes to your form that are set on
971             each request, you may need to either clear those yourself or ensure that
972             they are always set on each process call.
973              
974             =head2 Miscellaneous attributes
975              
976             =head3 name
977              
978             The form's name. Useful for multiple forms. Used for the form element 'id'.
979             When 'field_prefix' is set it is used to construct the field 'id'
980             and 'name'. The default is derived from the form class name.
981              
982             =head3 init_values
983              
984             An 'init_values' object or hashref may be used instead of the 'model' to pre-populate the values
985             in the form. This can be useful when populating a form from default values
986             stored in a similar but different object than the one the form is creating.
987             It can be set in a variety of ways:
988              
989             my $form = MyApp::Form->new( init_values => { .... } );
990             $form->process( init_values => {...}, ... );
991             has '+init_values' => ( default => sub { { .... } } );
992             sub init_values { my $self = shift; .... }
993              
994             The method version is useful if the organization of data in your form does
995             not map to an existing or database object in an automatic way, and you need
996             to create a different type of object for initialization. (You might also
997             want to do 'update_model' yourself.)
998              
999             You can use both a 'model' and an 'init_values' hashref
1000             when some of the fields in your form come from the database and some
1001             are process or environment type flags that are not in the database.
1002              
1003             =head3 ctx
1004              
1005             Place to store application context for your use in your form's methods.
1006              
1007             =head2 Localizer
1008              
1009             The form has a 'localizer' object which is shared with form fields.
1010             Uses gettext style .po files with names parameters, and is implemented
1011             with internal code borrowed from L<Locale::TextDomain::OO>.
1012              
1013             =head2 Flags
1014              
1015             =head3 validated, is_valid
1016              
1017             Flag that indicates if form has been validated. You might want to use
1018             this flag if you're doing something in between process and returning,
1019             such as setting a stash key. ('is_valid' is a synonym for this flag)
1020              
1021             $form->process( ... );
1022             $c->stash->{...} = ...;
1023             return unless $form->validated;
1024              
1025             =head3 ran_validation
1026              
1027             Flag to indicate that validation has been run. This flag will be
1028             false when the form is initially loaded and displayed, since
1029             validation is not run until MuForm has params to validate.
1030              
1031             =head3 field_prefix
1032              
1033             String to be used as a prefix for field ids and names
1034             in an HTML form. Useful for multiple forms
1035             on the same HTML page. The prefix is stripped off of the fields
1036             before creating the internal field name, and added back in when
1037             returning a parameter hash from the 'fif' method. For example,
1038             the field name in the HTML form could be "book.borrower", and
1039             the field name in the MuForm form (and the database column)
1040             would be just "borrower".
1041              
1042             has '+name' => ( default => 'book' );
1043             has '+field_prefix' => ( default => 'book' );
1044              
1045             Also see the Field attribute "prefixed_name", a convenience function which
1046             will return the field_prefix + "." + field full_name
1047              
1048             =head2 setup
1049              
1050             This is where args passed to 'process' are set, and the form is
1051             filled by params, object, or fields.
1052              
1053             =head1 AUTHOR
1054              
1055             Gerda Shank
1056              
1057             =head1 COPYRIGHT AND LICENSE
1058              
1059             This software is copyright (c) 2017 by Gerda Shank.
1060              
1061             This is free software; you can redistribute it and/or modify it under
1062             the same terms as the Perl 5 programming language system itself.
1063              
1064             =cut