package HTML::FormFu::Deflator::CompoundSplit; use Moose; extends 'HTML::FormFu::Deflator'; use HTML::FormFu::Constants qw( $EMPTY_STR $SPACE ); has split => ( is => 'rw', traits => ['Chained'] ); has join => ( is => 'rw', traits => ['Chained'] ); has field_order => ( is => 'rw', traits => ['Chained'] ); sub deflator { my ( $self, $value ) = @_; return if !defined $value || $value eq $EMPTY_STR; my ( $multi, @fields ) = @{ $self->parent->get_fields }; my $split = defined $self->split ? $self->split : qr/$SPACE+/; my $join = defined $self->join ? $self->join : $SPACE; my @parts = CORE::split $split, $value; if ( my $order = $self->field_order ) { my @new_order; FIELD: for my $i (@$order) { for my $field (@fields) { if ( $field->name eq $i ) { push @new_order, $field; next FIELD; } } } @fields = @new_order; } my %value; for my $i ( 0 .. $#fields ) { # if there are more parts than fields, join the extra ones # to make the final field's value if ( $i == $#fields ) { my $default = CORE::join $join, @parts[ $i .. $#parts ]; $fields[$i]->default($default); $value{ $fields[$i]->name } = $default; } else { $fields[$i]->default( $parts[$i] ); $value{ $fields[$i]->name } = $parts[$i]; } } return \%value; } __PACKAGE__->meta->make_immutable; 1; __END__ =head1 NAME HTML::FormFu::Deflator::CompoundSplit - CompoundSplit deflator =head1 SYNOPSIS --- element: - type: Multi name: address elements: - name: number - name: street deflator: - type: CompoundSplit # set the default $form->get_field('address')->default( $address ); =head1 DESCRIPTION Deflator to allow you to set several field's values at once. For use with a L group of fields. A L value passed to the L field will be split according to the L setting, and its resulting parts passed to its child elements. =head1 METHODS =head2 split Arguments: $regex Default Value: C Regex used to split the default value. Defaults to a regex matching 1 or more space characters. =head2 join Arguments: $string Default Value: C<' '> If spliting the value results in more parts than there are fields, any extra parts are joined again to form the value for the last field. The value of L is used to join these values. Defaults to a single space. For example, if the Multi element contains fields C and C, and is given the value C<10 Downing Street>; when split this results in 3 parts: C<10>, C and C. In this case, the 1st part, C<10> is assigned to the first field, and the 2nd and 3rd parts are re-joined with a space to give the single value C, which is assigned to the 2nd field. =head2 field_order Arguments: \@order If the parts from the split value should be assigned to the fields in a different order, you must provide an arrayref containing the names, in the order they should be assigned to. --- element: - type: Multi name: address elements: - name: street - name: number deflator: - type: CompoundSplit field_order: - number - street =head1 AUTHOR Carl Franks =head1 LICENSE This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut