File Coverage

blib/lib/Data/MuForm/Fields.pm
Criterion Covered Total %
statement 345 349 98.8
branch 139 164 84.7
condition 112 141 79.4
subroutine 51 51 100.0
pod 0 38 0.0
total 647 743 87.0


line stmt bran cond sub pod time code
1             package Data::MuForm::Fields;
2             # ABSTRACT: Common attributes and methods for forms and compound fields
3 81     81   36873 use Moo::Role;
  81         165  
  81         385  
4              
5 81     81   15558 use Types::Standard -types;
  81         112  
  81         735  
6 81     81   235199 use Type::Utils;
  81         258995  
  81         627  
7 81     81   72919 use Data::Clone ('data_clone');
  81         106  
  81         3354  
8 81     81   3938 use Class::Load ('load_optional_class');
  81         84077  
  81         2973  
9 81     81   303 use Scalar::Util 'blessed';
  81         98  
  81         224957  
10             with 'Data::MuForm::Common';
11              
12              
13             has 'value' => ( is => 'rw', predicate => 'has_value', default => sub {{}} );
14 133     133 0 273 sub clear_value { $_[0]->{value} = {} }
15 7     7 0 1174 sub values { $_[0]->value }
16             has 'init_value' => ( is => 'rw', clearer => 'clear_init_value' );
17             has 'input' => ( is => 'rw', clearer => 'clear_input' );
18             has 'skip_fields_without_input' => ( is => 'rw' ); # except 'input_without_param'
19             has 'filled_from' => ( is => 'rw', clearer => 'clear_filled_from' );
20             has 'meta_fields' => ( is => 'rw' );
21             has 'field_list' => ( is => 'rw', isa => ArrayRef, lazy => 1, builder => 'build_field_list' );
22 222     222 0 55242 sub build_field_list {[]}
23             has 'fields' => ( is => 'rw', isa => ArrayRef, default => sub {[]});
24 1045     1045 0 1405 sub push_field { my ( $self, @fields ) = @_; push @{$self->{fields}}, @fields; }
  1045         899  
  1045         2859  
25 85     85 0 88 sub clear_fields { my $self = shift; $self->{fields} = undef; }
  85         172  
26 2072     2072 0 2254 sub all_fields { my $self = shift; return @{$self->{fields}}; }
  2072         1506  
  2072         4837  
27 5     5 0 9 sub set_field_at { my ( $self, $index, $field ) = @_; @{$self->{fields}}[$index] = $field; }
  5         7  
  5         15  
28 60     60 0 4940 sub num_fields { my $self = shift; return scalar (@{$self->{fields}}); }
  60         74  
  60         333  
29 775     775 0 693 sub has_fields { my $self = shift; return scalar (@{$self->{fields}}); }
  775         627  
  775         3301  
30             has 'error_fields' => ( is => 'rw', isa => ArrayRef, default => sub {[]} );
31 308     308 0 477 sub clear_error_fields { $_[0]->{error_fields} = [] }
32 375     375 0 303 sub has_error_fields { my $self = shift; return scalar @{$self->error_fields}; }
  375         272  
  375         777  
33 9     9 0 748 sub num_error_fields { my $self = shift; return scalar @{$self->error_fields}; }
  9         10  
  9         51  
34 81     81 0 85 sub add_error_field { my ($self, $field) = @_; push @{$self->error_fields}, $field; }
  81         91  
  81         294  
35 8     8 0 11 sub all_error_fields { my $self = shift; return @{$self->error_fields}; }
  8         135  
  8         25  
36             has 'field_namespace' => (
37             is => 'rw',
38             isa => ArrayRef,
39             builder => 'build_field_namespace',
40             coerce => sub {
41             my $ns = shift;
42             return [] unless defined $ns;
43             return $ns if ref $ns eq 'ARRAY';
44             return [$ns] if length($ns);
45             return [];
46             },
47             );
48 128     128 0 3183 sub build_field_namespace { [] }
49              
50             sub subfield {
51 8     8 0 50 my ( $self, $name ) = @_;
52 8         21 return $self->field($name, $self);
53             }
54              
55             sub field {
56 511     511 0 70581 my ( $self, $name, $f ) = @_;
57              
58 511         488 my $index;
59             # if this is a full_name for a compound field
60             # walk through the fields to get to it
61 511 50       940 return undef unless ( defined $name );
62 511 100 66     2134 if( $self->form && $self == $self->form &&
      66        
63             exists $self->index->{$name} ) {
64 432         35413 return $self->index->{$name};
65             }
66 79 100       2012 if ( $name =~ /\./ ) {
67 12         73 my @names = split /\./, $name;
68 12   33     61 $f ||= $self->form || $self;
      66        
69 12         25 foreach my $fname (@names) {
70 30         87 $f = $f->field($fname);
71 30 50       96 return unless $f;
72             }
73 12         84 return $f;
74             }
75             else # not a compound name
76             {
77 67         136 for my $field ( $self->all_fields ) {
78 96 100       482 return $field if ( $field->name eq $name );
79             }
80             }
81 2         10 return;
82             }
83              
84             sub all_sorted_fields {
85 760     760 0 1754 my $self = shift;
86 2043         3565 my @fields = sort { $a->order <=> $b->order }
87 760         1296 grep { $_->is_active } $self->all_fields;
  2130         4414  
88 760         2346 return @fields;
89             }
90              
91             sub sorted_fields {
92 8     8 0 68 my $self = shift;
93 8         21 my @fields = $self->all_sorted_fields;
94 8         40 return \@fields;
95             }
96              
97             sub field_index {
98 581     581 0 793 my ( $self, $name ) = @_;
99 581         579 my $index = 0;
100 581         1494 for my $field ( $self->all_fields ) {
101 898 100       2178 return $index if $field->name eq $name;
102 891         819 $index++;
103             }
104 574         757 return;
105             }
106              
107             # Repeatable overrides this
108             sub fields_validate {
109 152     152 0 158 my $self = shift;
110              
111 152 50       292 return unless $self->has_fields;
112             # validate all fields
113 152         235 my %value_hash;
114 152         551 foreach my $field ( $self->all_sorted_fields ) {
115 438 100 66     1381 next if ( !$field->is_active || $field->disabled );
116 436 100 100     1346 next if ( $self->skip_fields_without_input && ! $field->has_input && ! $field->has_input_without_param );
      66        
117             # Validate each field and "inflate" input -> value.
118 429         1220 $field->field_validate; # this calls all the various validation routines
119 429 100 100     28170 $value_hash{ $field->accessor } = $field->value
120             if ( $field->has_value && !$field->no_update );
121             }
122 152         1058 $self->value( \%value_hash );
123             }
124              
125             sub fields_fif {
126 111     111 0 141 my ( $self, $prefix ) = @_;
127              
128 111   100     350 $prefix ||= '';
129 111 100 100     754 $prefix = $self->field_prefix . "."
130             if ( $self->isa('Data::MuForm') && $self->field_prefix );
131              
132 111         104 my %params;
133 111         206 foreach my $field ( $self->all_sorted_fields ) {
134 296 100 33     459 next if ( ! $field->is_active || $field->password || $field->no_fif );
      66        
135 289         633 my $fif = $field->fif;
136 289 100 100     845 next if ( !defined $fif || (ref $fif eq 'ARRAY' && ! scalar @{$fif} ) );
  19   33     57  
137 288 100       456 if ( $field->has_fields ) {
138             # this builds up foo.0.bar.name
139 53         281 my $next_params = $field->fields_fif( $prefix . $field->name . '.' );
140 53 50       92 next unless $next_params;
141 53         71 %params = ( %params, %{$next_params} );
  53         444  
142             }
143             else {
144 235         622 $params{ $prefix . $field->name } = $fif;
145             }
146             }
147 111 50       367 return if !%params;
148 111         349 return \%params;
149              
150             }
151              
152             sub fields_get_results {
153 1     1 0 1 my $self = shift;
154              
155 1         5 my $result = $self->get_result;
156 1         2 my @field_results;
157 1         3 foreach my $field ( $self->all_sorted_fields ) {
158 2 50       7 next if ! $field->is_active;
159 2         7 my $result = $field->get_result;
160 2         4 push @field_results, $result;
161             }
162 1         4 $result->{fields} = \@field_results;
163 1         3 return $result;
164             }
165              
166             #====================================================================
167             # Build Fields
168             #====================================================================
169              
170             sub build_fields {
171 228     228 0 330 my $self = shift;
172              
173             # process meta fields
174 228         4122 my @meta_fields = $self->_meta_fields;
175 228         4705 $self->meta_fields(\@meta_fields);
176 228         3693 my $meta_fields = data_clone(\@meta_fields);
177 228         1122 $self->process_field_array( $meta_fields );
178              
179             # process field_list
180 227         1290 my $field_list = $self->field_list;
181 227 100 100     5567 $field_list = $self->convert_field_list_to_hashes($field_list)
182             if $field_list->[0] && ref($field_list->[0]) ne 'HASH';
183 227         1552 $self->process_field_array ( $field_list );
184              
185 227 100       1090 return unless $self->has_fields;
186 147         1513 $self->order_fields;
187             }
188              
189             sub convert_field_list_to_hashes {
190 3     3 0 5 my ( $self, $field_list ) = @_;
191              
192 3         5 my @new_fields;
193 3         8 while (@$field_list) {
194 8         65 my $name = shift @$field_list;
195 8         10 my $attr = shift @$field_list;
196 8 100       18 unless ( ref $attr eq 'HASH' ) {
197 4         9 $attr = { type => $attr };
198             }
199 8         30 push @new_fields, { name => $name, %$attr };
200             }
201 3         7 return \@new_fields;
202             }
203              
204             sub process_field_array {
205 455     455 0 580 my ( $self, $fields ) = @_;
206              
207 455         1332 $fields = $self->clean_fields($fields);
208              
209             # TODO: there's got to be a better way of doing this
210 455         719 my $num_fields = scalar @$fields;
211 455         407 my $num_dots = 0;
212 455         1237 my $count_fields = 0;
213 455         1077 while ( $count_fields < $num_fields ) {
214 194         342 foreach my $field (@$fields) {
215 882         1424 my $count = ( $field->{name} =~ tr/\.// );
216 882 100       1592 next unless $count == $num_dots;
217 580         2298 $self->_make_field($field);
218 579         933 $count_fields++;
219             }
220 193         2212 $num_dots++;
221             }
222             }
223              
224             has 'include' => ( is => 'rw', builder => 'build_include', lazy => 1 );
225 225     225 0 29264 sub build_include { [] }
226             sub has_include {
227 455     455 0 505 my $self = shift;
228 455   50     1497 my $include = $self->include || [];
229 455         5372 return scalar @{$include};
  455         1072  
230             }
231              
232             sub clean_fields {
233 455     455 0 482 my ( $self, $fields ) = @_;
234 455 100       1441 if( $self->has_include ) {
235 6         8 my @fields;
236 6         5 my %include = map { $_ => 1 } @{ $self->include };
  16         124  
  6         13  
237 6         13 foreach my $fld ( @$fields ) {
238 16 100       46 push @fields, data_clone($fld) if exists $include{$fld->{name}};
239             }
240 6         13 return \@fields;
241             }
242 449         3989 return data_clone( $fields );
243             };
244              
245             sub _make_field {
246 582     582   630 my ( $self, $field_attr ) = @_;
247              
248 582   100     1933 my $type = $field_attr->{type} ||= 'Text';
249 582         630 my $name = $field_attr->{name};
250              
251             # check for a field prefixed with '+', that overrides
252 582         492 my $do_update;
253 582 100       1226 if ( $name =~ /^\+(.*)/ ) {
254 4         8 $field_attr->{name} = $name = $1;
255 4         7 $do_update = 1;
256             }
257              
258 582         1395 my $class = $self->_find_field_class( $type, $name );
259              
260 582         1841 my $parent = $self->_find_parent( $field_attr );
261              
262 581         1522 my $field = $self->_update_or_create( $parent, $field_attr, $class, $do_update );
263              
264 581 100       3062 $self->form->add_to_index( $field->full_name => $field ) if $self->form;
265              
266 581         1153 return $field;
267             }
268              
269             sub _find_field_class {
270 582     582   713 my ( $self, $type, $name ) = @_;
271              
272 582         2525 my $field_ns = $self->field_namespace;
273 582         56696 my @classes;
274             # '+'-prefixed fields could be full namespaces
275 582 100       1496 if ( $type =~ s/^\+// ) {
276 13         20 push @classes, $type;
277             }
278 582         971 foreach my $ns ( @$field_ns, 'Data::MuForm::Field' ) {
279 593         1568 push @classes, $ns . "::" . $type;
280             }
281             # look for Field in possible namespaces
282 582         546 my $class;
283 582         702 foreach my $try ( @classes ) {
284 590 100       4450 last if $class = load_optional_class($try) ? $try : undef;
    100          
285             }
286 582 50       30244 die "Could not load field class '$type' for field '$name'"
287             unless $class;
288              
289 582         1191 return $class;
290             }
291              
292              
293             sub _find_parent {
294 582     582   661 my ( $self, $field_attr ) = @_;
295              
296             # parent and name correction for names with dots
297 582         512 my $parent;
298 582 100 100     3272 if ( $field_attr->{name} =~ /\./ ) {
    100          
299 121         377 my @names = split /\./, $field_attr->{name};
300 121         175 my $simple_name = pop @names;
301 121         239 my $parent_name = join '.', @names;
302             # use special 'field' method call that starts from
303             # $self, because names aren't always starting from
304             # the form
305 121         429 $parent = $self->field($parent_name, $self);
306 121 100       663 if ($parent) {
307 120 50       692 die "The parent of field " . $field_attr->{name} . " is not a Compound Field"
308             unless $parent->isa('Data::MuForm::Field::Compound');
309 120         256 $field_attr->{name} = $simple_name;
310             }
311             else {
312 1         57 die "did not find parent for field " . $field_attr->{name};
313             }
314             }
315             elsif ( !( $self->form && $self == $self->form ) ) {
316             # set parent
317 61         1008 $parent = $self;
318             }
319              
320             # get full_name
321 581         869 my $full_name = $field_attr->{name};
322             $full_name = $parent->full_name . "." . $field_attr->{name}
323 581 100       1374 if $parent;
324 581         860 $field_attr->{full_name} = $full_name;
325 581         749 return $parent;
326              
327             }
328              
329             sub _update_or_create {
330 581     581   779 my ( $self, $parent, $field_attr, $class, $do_update ) = @_;
331              
332 581   66     3263 $parent ||= $self->form;
333 581         790 $field_attr->{parent} = $parent;
334 581         11150 $field_attr->{localizer} = $parent->localizer;
335 581         19099 $field_attr->{renderer} = $parent->renderer;
336 581 100       12583 $field_attr->{form} = $self->form if $self->form;
337             $field_attr->{skip_fields_without_input} = $parent->skip_fields_without_input
338 581 50 66     2481 if ! $self->is_form && $self->is_compound && ! exists $field_attr->{skip_fields_without_input};
      66        
339 581         1650 my $index = $parent->field_index( $field_attr->{name} );
340 581         547 my $field;
341 581 100       938 if ( defined $index ) {
342 7 100       15 if ($do_update) { # this field started with '+'. Update.
343 2         13 $field = $parent->field( $field_attr->{name} );
344 2 50       12 die "Field to update for " . $field_attr->{name} . " not found"
345             unless $field;
346 2         6 munge_field_attr($field_attr);
347 2         3 foreach my $key ( keys %{$field_attr} ) {
  2         5  
348 18 100 100     1093 next if $key eq 'name' || $key eq 'form' || $key eq 'parent' ||
      100        
      100        
      100        
349             $key eq 'full_name' || $key eq 'type';
350 8 50       74 $field->$key( $field_attr->{$key} )
351             if $field->can($key);
352             }
353             }
354             else { # replace existing field
355 5         22 $field = $self->new_field( $class, $field_attr);
356 5         26 $parent->set_field_at( $index, $field );
357             }
358             }
359             else { # new field
360 574         1369 $field = $self->new_field( $class, $field_attr);
361 574         2592 $parent->push_field($field);
362             }
363 581 100 100     8849 $field->form->add_repeatable_field($field)
364             if ( $field->form && $field->is_repeatable);
365              
366 581         1011 return $field;
367             }
368              
369             sub new_field {
370 603     603 0 687 my ( $self, $class, $field_attr ) = @_;
371             # not handling roles
372 603         9085 my $field = $class->new(%$field_attr);
373 603         17383 return $field;
374             }
375              
376             sub order_fields {
377 217     217 0 1316 my $self = shift;
378              
379             # number all unordered fields by 5
380 217         1968 my $order = 5;
381 217         489 foreach my $field ( $self->all_fields ) {
382 620 100       1545 if ( $field->has_fields ) {
383 71         228 $field->order_fields;
384             }
385             # fields will default to 0, so we
386             # rewrite order if 0
387 620 100       1759 $field->order($order) unless $field->order;
388 620         1517 $order += 5;
389             }
390             }
391              
392             sub _get_highest_field_order {
393 1     1   9 my $self = shift;
394 1         1 my $order = 0;
395 1         3 foreach my $field ( $self->all_fields ) {
396 3 100       18 $order = $field->order if $field->order > $order;
397             }
398 1         3 return $order;
399             }
400              
401             # This is a special make field that's used in the Repeatable field to
402             # create repeatable instances. It skips some of the overhead of _make_field
403             # because some of the info can be hardcoded and we don't want to index it.
404             sub _make_adhoc_field {
405 24     24   172 my ( $self, $class, $field_attr ) = @_;
406 24         51 my $field = $self->new_field( $class, $field_attr );
407 24         60 return $field;
408             }
409              
410              
411             #====================================================================
412             # Initialize input/value (InitResult)
413             #====================================================================
414              
415             # $input here is from the $params passed in on ->process
416             sub fill_from_params {
417 160     160 0 206 my ( $self, $input, $exists ) = @_;
418              
419 160         410 $self->filled_from('params');
420 160 0 33     427 return unless ( defined $input || $exists || $self->has_fields );
      33        
421             # TODO - this will get replaced by setting the actual processed input 14 lines down.
422             # Do we need this? Maybe could be used to transform input before processing?
423 160         617 $self->transform_and_set_input($input);
424 160         183 my $my_input = {};
425 160 50       436 if ( ref $input eq 'HASH' ) {
426 160         421 foreach my $field ( $self->all_sorted_fields ) {
427 454 50       789 next if ! $field->is_active;
428 454   66     2071 my $fname = $field->input_param || $field->name;
429 454         517 my $exists = exists $input->{$fname};
430 454 100 100     1237 next if ( $self->skip_fields_without_input && ! $exists && ! $field->has_input_without_param );
      100        
431 447 100 100     1288 if ( ! $exists && $field->disabled && ! $field->has_value ) {
      100        
432 1         3 $field->fill_from_fields;
433             }
434             else {
435 446         1703 $field->fill_from_params($input->{$fname}, $exists );
436             }
437 447 100       1597 $my_input->{$fname} = $field->input if $field->has_input;
438             }
439             }
440             # save input for this form or compound field. Used to determine whether really 'submitted'
441             # in form. This should not be used for errors or fif or anything like that.
442 160 100       671 $self->input( scalar keys %$my_input ? $my_input : {});
443 160         299 return;
444             }
445              
446             sub fill_from_object {
447 95     95 0 284 my ( $self, $obj ) = @_;
448              
449 95 50 33     207 return unless ( $obj || $self->has_fields ); # empty fields for compounds
450 95         202 $self->filled_from('object');
451 95         78 my $my_value;
452             my $init_obj;
453 95 100 66     737 if ( $self->form &&
      100        
      100        
454             $self->form->fill_from_object_source &&
455             $self->form->fill_from_object_source eq 'model' &&
456             $self->form->has_init_values ) {
457 6         30 $init_obj = $self->form->init_values;
458             }
459 95         1192 for my $field ( $self->all_sorted_fields ) {
460 257 50       538 next if ! $field->is_active;
461 257 100 100     4044 if ( (ref $obj eq 'HASH' && !exists $obj->{ $field->accessor } ) ||
      100        
      66        
462             ( blessed($obj) && !$obj->can($field->accessor) ) ) {
463 35         102 my $found = 0;
464              
465 35 100       51 if ($init_obj) {
466             # if we're using a model, look for accessor not found in obj
467             # in the init_values
468 9         24 my @names = split( /\./, $field->full_name );
469 9         22 my $init_obj_value = $self->find_sub_obj( $init_obj, \@names );
470 9 100       24 if ( defined $init_obj_value ) {
471 7         7 $found = 1;
472 7         46 $field->fill_from_object( $init_obj_value );
473             }
474             }
475              
476 35 100       102 $field->fill_from_fields() unless $found;
477             }
478             else {
479 222 50       1295 my $value = $self->_get_value( $field, $obj ) unless $field->writeonly;
480 222         670 $field->fill_from_object( $value );
481             }
482             # TODO: the following doesn't work for 'input_without_param' fields like checkboxes
483             # $my_value->{ $field->name } = $field->value if $field->has_value;
484 257         939 $my_value->{ $field->name } = $field->value;
485             }
486 95         734 $self->value($my_value);
487 95         288 return;
488             }
489              
490             # for when there are no params and no init_values
491             sub fill_from_fields {
492 236     236 0 315 my ( $self ) = @_;
493              
494 236         819 $self->filled_from('fields');
495             # defaults for compounds, etc.
496 236 100       895 if ( my @values = $self->get_default_value ) {
497 6 50       753 my $value = @values > 1 ? \@values : shift @values;
498 6 50 66     21 if( ref $value eq 'HASH' || blessed $value ) {
499 6         118 return $self->fill_from_object( $value );
500             }
501 0 0       0 if ( defined $value ) {
502 0         0 $self->init_value($value);
503 0         0 $self->value($value);
504             }
505             }
506 230         254 my $my_value;
507 230         794 for my $field ( $self->all_sorted_fields ) {
508 632 50       1025 next if (!$field->is_active);
509 632         2460 $field->fill_from_fields();
510 632 100       2602 $my_value->{ $field->name } = $field->value if $field->has_value;
511             }
512             # setting value here to handle disabled compound fields, where we want to
513             # preserve the 'value' because the fields aren't submitted...except for the
514             # form. Not sure it's the best idea to skip for form, but it maintains previous behavior
515 230 100       745 $self->value($my_value) if ( keys %$my_value );
516 230         2517 return;
517             }
518              
519             sub find_sub_obj {
520 10     10 0 31 my ( $self, $obj, $field_name_array ) = @_;
521 10         15 my $this_fname = shift @$field_name_array;;
522 10         24 my $field = $self->field($this_fname);
523 10         48 my $new_obj = $self->_get_value( $field, $obj );
524 10 50       21 if ( scalar @$field_name_array ) {
525 0         0 $new_obj = $field->find_sub_obj( $new_obj, $field_name_array );
526             }
527 10         18 return $new_obj;
528             }
529              
530              
531              
532             sub _get_value {
533 232     232   230 my ( $self, $field, $obj ) = @_;
534              
535 232         3134 my $accessor = $field->accessor;
536 232         905 my @values;
537 232 100 66     783 if ( blessed($obj) && $obj->can($accessor) ) {
    100          
    100          
538             # this must be an array, so that DBIx::Class relations are arrays not resultsets
539 11         27 @values = $obj->$accessor;
540             # for non-DBIC blessed object where access returns arrayref
541 11 100 66     59 if ( scalar @values == 1 && ref $values[0] eq 'ARRAY' && $field->multiple ) {
      66        
542 1         1 @values = @{$values[0]};
  1         2  
543             }
544             }
545             elsif ( exists $obj->{$accessor} ) {
546 216         222 my $v = $obj->{$accessor};
547 216 100 100     522 if($field->multiple && ref($v) eq 'ARRAY'){
548 2         7 @values = @$v;
549             } else {
550 214         318 @values = $v;
551             }
552             }
553             elsif ( @values = $field->get_default_value ) {
554             }
555             else {
556 2         3 return;
557             }
558 230 100       535 if( $field->has_transform_default_to_value ) {
559 8         28 @values = $field->transform_default_to_value->($field, @values);
560             }
561 230         206 my $value;
562 230 100       344 if( $field->multiple ) {
563 5 100 100     40 if ( scalar @values == 1 && ! defined $values[0] ) {
    100 100        
564 1         2 $value = [];
565             }
566             elsif ( scalar @values == 1 && ref $values[0] eq 'ARRAY' ) {
567 1         7 $value = shift @values;
568             }
569             else {
570 3         6 $value = \@values;
571             }
572             }
573             else {
574 225 50       365 $value = @values > 1 ? \@values : shift @values;
575             }
576 230         310 return $value;
577             }
578              
579              
580             sub fields_set_value {
581 103     103 0 121 my $self = shift;
582 103         121 my %value_hash;
583 103         261 foreach my $field ( $self->all_fields ) {
584 305 100       1389 next if ! $field->is_active;
585 302 100 100     4887 $value_hash{ $field->accessor } = $field->value
586             if ( $field->has_value && !$field->no_update );
587             }
588 103         944 $self->value( \%value_hash );
589             }
590              
591              
592             sub clear_data {
593 133     133 0 401 my $self = shift;
594 133         432 $self->clear_input;
595 133         11546 $self->clear_value;
596             # TODO - better way?
597 133 100       489 $self->_clear_active unless $self->is_form;;
598 133         1313 $self->clear_error_fields;
599 133         346 $self->clear_filled_from;
600 133         2306 foreach my $field ( $self->all_fields ) {
601 349         12884 $field->clear_data;
602             }
603             }
604              
605             # References to fields with errors are propagated up the tree.
606             # All fields with errors should end up being in the form's
607             # error_results. Once.
608             sub propagate_error {
609 81     81 0 563 my ( $self, $field ) = @_;
610              
611 81         271 $self->add_error_field($field);
612 81 100       8818 if ( $self->parent ) {
613 16         260 $self->parent->propagate_error( $field );
614             }
615             }
616              
617             1;
618              
619             __END__
620              
621             =pod
622              
623             =encoding UTF-8
624              
625             =head1 NAME
626              
627             Data::MuForm::Fields - Common attributes and methods for forms and compound fields
628              
629             =head1 VERSION
630              
631             version 0.03
632              
633             =head2 NAME
634              
635             Data::MuForm::Fields
636              
637             =head2 DESCRIPTION
638              
639             This role holds things that are common to Data::MuForm and compound fields.
640              
641             Includes code that was split up into multiple roles in FormHandler: Fields,
642             BuildFields, InitResult.
643              
644             =head1 AUTHOR
645              
646             Gerda Shank
647              
648             =head1 COPYRIGHT AND LICENSE
649              
650             This software is copyright (c) 2017 by Gerda Shank.
651              
652             This is free software; you can redistribute it and/or modify it under
653             the same terms as the Perl 5 programming language system itself.
654              
655             =cut