HTML::FormFu::Constraint::Repeatable::Any - Ensure at least 1 of a repeated field is filled-in


HTML-FormFu documentation Contained in the HTML-FormFu distribution.

Index


Code Index:

NAME

Top

HTML::FormFu::Constraint::Repeatable::Any - Ensure at least 1 of a repeated field is filled-in

SYNOPSIS

Top

    elements:
      - type: Repeatable
        elements:
          - name: foo
            constraints:
              - type: Repeatable::Any

DESCRIPTION

Top

Ensure at least 1 of a repeated field is filled-in.

Any error will be attached to the first repetition of the field.

This constraint doesn't honour the not() value.

SEE ALSO

Top

Is a sub-class of, and inherits methods from HTML::FormFu::Constraint

HTML::FormFu

AUTHOR

Top

Carl Franks cfranks@cpan.org

LICENSE

Top

This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself.


HTML-FormFu documentation Contained in the HTML-FormFu distribution.

package HTML::FormFu::Constraint::Repeatable::Any;
use Moose;

extends 'HTML::FormFu::Constraint';

use Scalar::Util qw( reftype );
use Carp qw( croak );

after BUILD => sub {
    my $self = shift;

    $self->only_on_reps([1]);

    return;
};

sub process {
    my ( $self, $params ) = @_;

    return unless $self->_run_this_rep;

    # check when condition
    return if !$self->_process_when($params);

    my $field      = $self->field;
    my $repeatable = $field->get_parent({ type => 'Repeatable' });
    my $pass;

    my $original_name = $field->original_name || '';

    my @fields =
        grep { $_->get_parent({ type => 'Repeatable' }) == $repeatable }
        grep { ( $_->original_name || '' ) eq $original_name }
            @{ $repeatable->get_fields };

    my $increment_field_names = $repeatable->increment_field_names;

    for my $f (@fields) {
        my $value;
        
        if ( $increment_field_names )  {
            $value = $self->get_nested_hash_value( $params, $f->nested_name );
        }
        else {
            $value = _find_this_field_value( $self, $f, $repeatable, $params );
        }

        my $ok = eval { $self->constrain_value($value) };

        if ( $ok && !$@ ) {
            $pass = 1;
            last;
        }
    }

    return $self->mk_errors( {
            pass => $pass,
        } );
}

sub _find_this_field_value {
    my ( $self, $field, $repeatable, $params ) = @_;

    my $nested_name = $field->nested_name;

    my $value = $self->get_nested_hash_value( $params, $nested_name );

    my @fields_with_this_name = @{ $repeatable->get_fields({ nested_name => $nested_name }) };
    
    if ( @fields_with_this_name > 1 ) {
        my $index;
        
        for ( my $i=0; $i <= $#fields_with_this_name; ++$i ) {
            if ( $fields_with_this_name[$i] eq $field ) {
                $index = $i;
                last;
            }
        }
        
        croak 'did not find ourself - how can this happen?'
            if !defined $index;
        
        if ( reftype($value) eq 'ARRAY' ) {
            $value = $value->[$index];
        }
        elsif ( $index == 0 ) {
            # keep $value
        }
        else {
            undef $value;
        }
    }
    
    return $value;
}

sub constrain_value {
    my ( $self, $value ) = @_;

    return defined $value && length $value;
}

__PACKAGE__->meta->make_immutable;

1;

__END__