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 82     82   38606 use Moo::Role;
  82         113  
  82         403  
4              
5 82     82   16319 use Types::Standard -types;
  82         109  
  82         701  
6 82     82   244816 use Type::Utils;
  82         266609  
  82         687  
7 82     82   74245 use Data::Clone ('data_clone');
  82         115  
  82         3513  
8 82     82   4040 use Class::Load ('load_optional_class');
  82         88923  
  82         3360  
9 82     82   314 use Scalar::Util 'blessed';
  82         108  
  82         230143  
10             with 'Data::MuForm::Common';
11              
12              
13             has 'value' => ( is => 'rw', predicate => 'has_value', default => sub {{}} );
14 133     133 0 277 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 223     223 0 55424 sub build_field_list {[]}
23             has 'fields' => ( is => 'rw', isa => ArrayRef, default => sub {[]});
24 1050     1050 0 2230 sub push_field { my ( $self, @fields ) = @_; push @{$self->{fields}}, @fields; }
  1050         979  
  1050         2875  
25 85     85 0 92 sub clear_fields { my $self = shift; $self->{fields} = undef; }
  85         172  
26 2080     2080 0 2267 sub all_fields { my $self = shift; return @{$self->{fields}}; }
  2080         1560  
  2080         4937  
27 5     5 0 9 sub set_field_at { my ( $self, $index, $field ) = @_; @{$self->{fields}}[$index] = $field; }
  5         17  
  5         17  
28 60     60 0 4258 sub num_fields { my $self = shift; return scalar (@{$self->{fields}}); }
  60         71  
  60         329  
29 776     776 0 768 sub has_fields { my $self = shift; return scalar (@{$self->{fields}}); }
  776         578  
  776         4866  
30             has 'error_fields' => ( is => 'rw', isa => ArrayRef, default => sub {[]} );
31 308     308 0 484 sub clear_error_fields { $_[0]->{error_fields} = [] }
32 375     375 0 331 sub has_error_fields { my $self = shift; return scalar @{$self->error_fields}; }
  375         278  
  375         787  
33 9     9 0 536 sub num_error_fields { my $self = shift; return scalar @{$self->error_fields}; }
  9         48  
  9         24  
34 81     81 0 88 sub add_error_field { my ($self, $field) = @_; push @{$self->error_fields}, $field; }
  81         80  
  81         318  
35 8     8 0 10 sub all_error_fields { my $self = shift; return @{$self->error_fields}; }
  8         10  
  8         40  
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 129     129 0 3129 sub build_field_namespace { [] }
49              
50             sub subfield {
51 8     8 0 57 my ( $self, $name ) = @_;
52 8         24 return $self->field($name, $self);
53             }
54              
55             sub field {
56 515     515 0 71945 my ( $self, $name, $f ) = @_;
57              
58 515         491 my $index;
59             # if this is a full_name for a compound field
60             # walk through the fields to get to it
61 515 50       989 return undef unless ( defined $name );
62 515 100 66     2104 if( $self->form && $self == $self->form &&
      66        
63             exists $self->index->{$name} ) {
64 436         36836 return $self->index->{$name};
65             }
66 79 100       1922 if ( $name =~ /\./ ) {
67 12         40 my @names = split /\./, $name;
68 12   33     60 $f ||= $self->form || $self;
      66        
69 12         24 foreach my $fname (@names) {
70 30         83 $f = $f->field($fname);
71 30 50       98 return unless $f;
72             }
73 12         129 return $f;
74             }
75             else # not a compound name
76             {
77 67         188 for my $field ( $self->all_fields ) {
78 96 100       422 return $field if ( $field->name eq $name );
79             }
80             }
81 2         6 return;
82             }
83              
84             sub all_sorted_fields {
85 762     762 0 2223 my $self = shift;
86 2059         4433 my @fields = sort { $a->order <=> $b->order }
87 762         1584 grep { $_->is_active } $self->all_fields;
  2140         4218  
88 762         1533 return @fields;
89             }
90              
91             sub sorted_fields {
92 8     8 0 68 my $self = shift;
93 8         23 my @fields = $self->all_sorted_fields;
94 8         40 return \@fields;
95             }
96              
97             sub field_index {
98 586     586 0 757 my ( $self, $name ) = @_;
99 586         605 my $index = 0;
100 586         1478 for my $field ( $self->all_fields ) {
101 908 100       3942 return $index if $field->name eq $name;
102 901         856 $index++;
103             }
104 579         821 return;
105             }
106              
107             # Repeatable overrides this
108             sub fields_validate {
109 152     152 0 156 my $self = shift;
110              
111 152 50       285 return unless $self->has_fields;
112             # validate all fields
113 152         178 my %value_hash;
114 152         305 foreach my $field ( $self->all_sorted_fields ) {
115 438 100 66     1370 next if ( !$field->is_active || $field->disabled );
116 436 100 100     1252 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         1186 $field->field_validate; # this calls all the various validation routines
119 429 100 100     28291 $value_hash{ $field->accessor } = $field->value
120             if ( $field->has_value && !$field->no_update );
121             }
122 152         1139 $self->value( \%value_hash );
123             }
124              
125             sub fields_fif {
126 111     111 0 146 my ( $self, $prefix ) = @_;
127              
128 111   100     325 $prefix ||= '';
129 111 100 100     772 $prefix = $self->field_prefix . "."
130             if ( $self->isa('Data::MuForm') && $self->field_prefix );
131              
132 111         106 my %params;
133 111         232 foreach my $field ( $self->all_sorted_fields ) {
134 296 100 33     473 next if ( ! $field->is_active || $field->password || $field->no_fif );
      66        
135 289         603 my $fif = $field->fif;
136 289 100 100     858 next if ( !defined $fif || (ref $fif eq 'ARRAY' && ! scalar @{$fif} ) );
  19   33     58  
137 288 100       487 if ( $field->has_fields ) {
138             # this builds up foo.0.bar.name
139 53         276 my $next_params = $field->fields_fif( $prefix . $field->name . '.' );
140 53 50       120 next unless $next_params;
141 53         81 %params = ( %params, %{$next_params} );
  53         309  
142             }
143             else {
144 235         580 $params{ $prefix . $field->name } = $fif;
145             }
146             }
147 111 50       390 return if !%params;
148 111         540 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         1 my @field_results;
157 1         3 foreach my $field ( $self->all_sorted_fields ) {
158 2 50       6 next if ! $field->is_active;
159 2         8 my $result = $field->get_result;
160 2         4 push @field_results, $result;
161             }
162 1         2 $result->{fields} = \@field_results;
163 1         2 return $result;
164             }
165              
166             #====================================================================
167             # Build Fields
168             #====================================================================
169              
170             sub build_fields {
171 229     229 0 386 my $self = shift;
172              
173             # process meta fields
174 229         4112 my @meta_fields = $self->_meta_fields;
175 229         3510 $self->meta_fields(\@meta_fields);
176 229         4690 my $meta_fields = data_clone(\@meta_fields);
177 229         1208 $self->process_field_array( $meta_fields );
178              
179             # process field_list
180 228         1242 my $field_list = $self->field_list;
181 228 100 100     7351 $field_list = $self->convert_field_list_to_hashes($field_list)
182             if $field_list->[0] && ref($field_list->[0]) ne 'HASH';
183 228         1432 $self->process_field_array ( $field_list );
184              
185 228 100       1140 return unless $self->has_fields;
186 148         984 $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         74 while (@$field_list) {
194 8         12 my $name = shift @$field_list;
195 8         11 my $attr = shift @$field_list;
196 8 100       22 unless ( ref $attr eq 'HASH' ) {
197 4         10 $attr = { type => $attr };
198             }
199 8         37 push @new_fields, { name => $name, %$attr };
200             }
201 3         5 return \@new_fields;
202             }
203              
204             sub process_field_array {
205 457     457 0 600 my ( $self, $fields ) = @_;
206              
207 457         1647 $fields = $self->clean_fields($fields);
208              
209             # TODO: there's got to be a better way of doing this
210 457         690 my $num_fields = scalar @$fields;
211 457         433 my $num_dots = 0;
212 457         430 my $count_fields = 0;
213 457         1076 while ( $count_fields < $num_fields ) {
214 195         364 foreach my $field (@$fields) {
215 887         1466 my $count = ( $field->{name} =~ tr/\.// );
216 887 100       1608 next unless $count == $num_dots;
217 585         1454 $self->_make_field($field);
218 584         915 $count_fields++;
219             }
220 194         1495 $num_dots++;
221             }
222             }
223              
224             has 'include' => ( is => 'rw', builder => 'build_include', lazy => 1 );
225 226     226 0 30617 sub build_include { [] }
226             sub has_include {
227 457     457 0 523 my $self = shift;
228 457   50     1483 my $include = $self->include || [];
229 457         5366 return scalar @{$include};
  457         1129  
230             }
231              
232             sub clean_fields {
233 457     457 0 528 my ( $self, $fields ) = @_;
234 457 100       1212 if( $self->has_include ) {
235 6         9 my @fields;
236 6         6 my %include = map { $_ => 1 } @{ $self->include };
  16         126  
  6         12  
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 451         4309 return data_clone( $fields );
243             };
244              
245             sub _make_field {
246 587     587   646 my ( $self, $field_attr ) = @_;
247              
248 587   100     1999 my $type = $field_attr->{type} ||= 'Text';
249 587         634 my $name = $field_attr->{name};
250              
251             # check for a field prefixed with '+', that overrides
252 587         504 my $do_update;
253 587 100       1368 if ( $name =~ /^\+(.*)/ ) {
254 4         10 $field_attr->{name} = $name = $1;
255 4         7 $do_update = 1;
256             }
257              
258 587         1721 my $class = $self->_find_field_class( $type, $name );
259              
260 587         1878 my $parent = $self->_find_parent( $field_attr );
261              
262 586         1556 my $field = $self->_update_or_create( $parent, $field_attr, $class, $do_update );
263              
264 586 100       2221 $self->form->add_to_index( $field->full_name => $field ) if $self->form;
265              
266 586         1004 return $field;
267             }
268              
269             sub _find_field_class {
270 587     587   768 my ( $self, $type, $name ) = @_;
271              
272 587         2612 my $field_ns = $self->field_namespace;
273 587         57612 my @classes;
274             # '+'-prefixed fields could be full namespaces
275 587 100       1438 if ( $type =~ s/^\+// ) {
276 13         21 push @classes, $type;
277             }
278 587         995 foreach my $ns ( @$field_ns, 'Data::MuForm::Field' ) {
279 598         1577 push @classes, $ns . "::" . $type;
280             }
281             # look for Field in possible namespaces
282 587         532 my $class;
283 587         720 foreach my $try ( @classes ) {
284 595 100       567705 last if $class = load_optional_class($try) ? $try : undef;
    100          
285             }
286 587 50       30891 die "Could not load field class '$type' for field '$name'"
287             unless $class;
288              
289 587         1241 return $class;
290             }
291              
292              
293             sub _find_parent {
294 587     587   713 my ( $self, $field_attr ) = @_;
295              
296             # parent and name correction for names with dots
297 587         531 my $parent;
298 587 100 100     3320 if ( $field_attr->{name} =~ /\./ ) {
    100          
299 121         417 my @names = split /\./, $field_attr->{name};
300 121         181 my $simple_name = pop @names;
301 121         230 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         415 $parent = $self->field($parent_name, $self);
306 121 100       793 if ($parent) {
307 120 50       715 die "The parent of field " . $field_attr->{name} . " is not a Compound Field"
308             unless $parent->isa('Data::MuForm::Field::Compound');
309 120         252 $field_attr->{name} = $simple_name;
310             }
311             else {
312 1         56 die "did not find parent for field " . $field_attr->{name};
313             }
314             }
315             elsif ( !( $self->form && $self == $self->form ) ) {
316             # set parent
317 61         1097 $parent = $self;
318             }
319              
320             # get full_name
321 586         870 my $full_name = $field_attr->{name};
322             $full_name = $parent->full_name . "." . $field_attr->{name}
323 586 100       2136 if $parent;
324 586         1724 $field_attr->{full_name} = $full_name;
325 586         803 return $parent;
326              
327             }
328              
329             sub _update_or_create {
330 586     586   773 my ( $self, $parent, $field_attr, $class, $do_update ) = @_;
331              
332 586   66     1589 $parent ||= $self->form;
333 586         814 $field_attr->{parent} = $parent;
334 586         10264 $field_attr->{localizer} = $parent->localizer;
335 586         19493 $field_attr->{renderer} = $parent->renderer;
336 586 100       13095 $field_attr->{form} = $self->form if $self->form;
337             $field_attr->{skip_fields_without_input} = $parent->skip_fields_without_input
338 586 50 66     2716 if ! $self->is_form && $self->is_compound && ! exists $field_attr->{skip_fields_without_input};
      66        
339 586         1740 my $index = $parent->field_index( $field_attr->{name} );
340 586         517 my $field;
341 586 100       950 if ( defined $index ) {
342 7 100       16 if ($do_update) { # this field started with '+'. Update.
343 2         12 $field = $parent->field( $field_attr->{name} );
344 2 50       14 die "Field to update for " . $field_attr->{name} . " not found"
345             unless $field;
346 2         6 munge_field_attr($field_attr);
347 2         2 foreach my $key ( keys %{$field_attr} ) {
  2         7  
348 18 100 100     1011 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       72 $field->$key( $field_attr->{$key} )
351             if $field->can($key);
352             }
353             }
354             else { # replace existing field
355 5         15 $field = $self->new_field( $class, $field_attr);
356 5         27 $parent->set_field_at( $index, $field );
357             }
358             }
359             else { # new field
360 579         1434 $field = $self->new_field( $class, $field_attr);
361 579         2755 $parent->push_field($field);
362             }
363 586 100 100     8409 $field->form->add_repeatable_field($field)
364             if ( $field->form && $field->is_repeatable);
365              
366 586         1175 return $field;
367             }
368              
369             sub new_field {
370 608     608 0 860 my ( $self, $class, $field_attr ) = @_;
371             # not handling roles
372 608         8519 my $field = $class->new(%$field_attr);
373 608         16889 return $field;
374             }
375              
376             sub order_fields {
377 218     218 0 290 my $self = shift;
378              
379             # number all unordered fields by 5
380 218         289 my $order = 5;
381 218         419 foreach my $field ( $self->all_fields ) {
382 625 100       1546 if ( $field->has_fields ) {
383 71         231 $field->order_fields;
384             }
385             # fields will default to 0, so we
386             # rewrite order if 0
387 625 100       1817 $field->order($order) unless $field->order;
388 625         1594 $order += 5;
389             }
390             }
391              
392             sub _get_highest_field_order {
393 1     1   7 my $self = shift;
394 1         1 my $order = 0;
395 1         2 foreach my $field ( $self->all_fields ) {
396 3 100       17 $order = $field->order if $field->order > $order;
397             }
398 1         2 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   164 my ( $self, $class, $field_attr ) = @_;
406 24         55 my $field = $self->new_field( $class, $field_attr );
407 24         65 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 215 my ( $self, $input, $exists ) = @_;
418              
419 160         405 $self->filled_from('params');
420 160 0 33     441 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         654 $self->transform_and_set_input($input);
424 160         217 my $my_input = {};
425 160 50       449 if ( ref $input eq 'HASH' ) {
426 160         398 foreach my $field ( $self->all_sorted_fields ) {
427 454 50       796 next if ! $field->is_active;
428 454   66     2106 my $fname = $field->input_param || $field->name;
429 454         501 my $exists = exists $input->{$fname};
430 454 100 100     1313 next if ( $self->skip_fields_without_input && ! $exists && ! $field->has_input_without_param );
      100        
431 447 100 100     1318 if ( ! $exists && $field->disabled && ! $field->has_value ) {
      100        
432 1         3 $field->fill_from_fields;
433             }
434             else {
435 446         1694 $field->fill_from_params($input->{$fname}, $exists );
436             }
437 447 100       1604 $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       589 $self->input( scalar keys %$my_input ? $my_input : {});
443 160         298 return;
444             }
445              
446             sub fill_from_object {
447 95     95 0 285 my ( $self, $obj ) = @_;
448              
449 95 50 33     234 return unless ( $obj || $self->has_fields ); # empty fields for compounds
450 95         213 $self->filled_from('object');
451 95         83 my $my_value;
452             my $init_obj;
453 95 100 66     728 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         31 $init_obj = $self->form->init_values;
458             }
459 95         1226 for my $field ( $self->all_sorted_fields ) {
460 257 50       532 next if ! $field->is_active;
461 257 100 100     4051 if ( (ref $obj eq 'HASH' && !exists $obj->{ $field->accessor } ) ||
      100        
      66        
462             ( blessed($obj) && !$obj->can($field->accessor) ) ) {
463 35         117 my $found = 0;
464              
465 35 100       65 if ($init_obj) {
466             # if we're using a model, look for accessor not found in obj
467             # in the init_values
468 9         21 my @names = split( /\./, $field->full_name );
469 9         25 my $init_obj_value = $self->find_sub_obj( $init_obj, \@names );
470 9 100       15 if ( defined $init_obj_value ) {
471 7         7 $found = 1;
472 7         43 $field->fill_from_object( $init_obj_value );
473             }
474             }
475              
476 35 100       111 $field->fill_from_fields() unless $found;
477             }
478             else {
479 222 50       1334 my $value = $self->_get_value( $field, $obj ) unless $field->writeonly;
480 222         698 $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         945 $my_value->{ $field->name } = $field->value;
485             }
486 95         712 $self->value($my_value);
487 95         281 return;
488             }
489              
490             # for when there are no params and no init_values
491             sub fill_from_fields {
492 238     238 0 296 my ( $self ) = @_;
493              
494 238         818 $self->filled_from('fields');
495             # defaults for compounds, etc.
496 238 100       879 if ( my @values = $self->get_default_value ) {
497 6 50       816 my $value = @values > 1 ? \@values : shift @values;
498 6 50 66     27 if( ref $value eq 'HASH' || blessed $value ) {
499 6         121 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 232         251 my $my_value;
507 232         808 for my $field ( $self->all_sorted_fields ) {
508 642 50       3065 next if (!$field->is_active);
509 642         1590 $field->fill_from_fields();
510 642 100       1782 $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 232 100       759 $self->value($my_value) if ( keys %$my_value );
516 232         2580 return;
517             }
518              
519             sub find_sub_obj {
520 10     10 0 44 my ( $self, $obj, $field_name_array ) = @_;
521 10         13 my $this_fname = shift @$field_name_array;;
522 10         24 my $field = $self->field($this_fname);
523 10         50 my $new_obj = $self->_get_value( $field, $obj );
524 10 50       23 if ( scalar @$field_name_array ) {
525 0         0 $new_obj = $field->find_sub_obj( $new_obj, $field_name_array );
526             }
527 10         15 return $new_obj;
528             }
529              
530              
531              
532             sub _get_value {
533 232     232   244 my ( $self, $field, $obj ) = @_;
534              
535 232         3041 my $accessor = $field->accessor;
536 232         924 my @values;
537 232 100 66     812 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         31 @values = $obj->$accessor;
540             # for non-DBIC blessed object where access returns arrayref
541 11 100 66     57 if ( scalar @values == 1 && ref $values[0] eq 'ARRAY' && $field->multiple ) {
      66        
542 1         1 @values = @{$values[0]};
  1         8  
543             }
544             }
545             elsif ( exists $obj->{$accessor} ) {
546 216         244 my $v = $obj->{$accessor};
547 216 100 100     528 if($field->multiple && ref($v) eq 'ARRAY'){
548 2         5 @values = @$v;
549             } else {
550 214         314 @values = $v;
551             }
552             }
553             elsif ( @values = $field->get_default_value ) {
554             }
555             else {
556 2         3 return;
557             }
558 230 100       555 if( $field->has_transform_default_to_value ) {
559 8         33 @values = $field->transform_default_to_value->($field, @values);
560             }
561 230         212 my $value;
562 230 100       352 if( $field->multiple ) {
563 5 100 100     44 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         2 $value = shift @values;
568             }
569             else {
570 3         4 $value = \@values;
571             }
572             }
573             else {
574 225 50       414 $value = @values > 1 ? \@values : shift @values;
575             }
576 230         324 return $value;
577             }
578              
579              
580             sub fields_set_value {
581 103     103 0 133 my $self = shift;
582 103         120 my %value_hash;
583 103         277 foreach my $field ( $self->all_fields ) {
584 305 100       1404 next if ! $field->is_active;
585 302 100 100     4906 $value_hash{ $field->accessor } = $field->value
586             if ( $field->has_value && !$field->no_update );
587             }
588 103         854 $self->value( \%value_hash );
589             }
590              
591              
592             sub clear_data {
593 133     133 0 405 my $self = shift;
594 133         447 $self->clear_input;
595 133         11363 $self->clear_value;
596             # TODO - better way?
597 133 100       513 $self->_clear_active unless $self->is_form;;
598 133         1373 $self->clear_error_fields;
599 133         347 $self->clear_filled_from;
600 133         2324 foreach my $field ( $self->all_fields ) {
601 349         12842 $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 587 my ( $self, $field ) = @_;
610              
611 81         269 $self->add_error_field($field);
612 81 100       9175 if ( $self->parent ) {
613 16         384 $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.04
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