Hi @all, just another module for review.
I have to constraint a textfield depending on the value of an associated select field. In my case either a telephone or fax number or an email address or maybe later on an icq or skype address. This brought me to the idea to create a dynamic constraint which loads the needed constraints later on. At the moment if got the feeling it's more like a hack of FormFu. Maybe some has an idea to run it smoother with the FormFu structure. Parameters: - dynamic_field: the name of the form field that's values are taken inti account - dynamic: the structure defining the values and it's specific constraints and the message that will be shown - force: dynamic gives an error itself if the value of dynamic_field is not contained in the parameter dynamic' - message: shown when the value is not found in the parameter dynamic' What I have in my configfile: - type: Text name: data label: Value size: 50 constraints: - Required - Printable - Dynamic dynamic_field: type_id dynamic: 1: constraints: - type: Regex regex: '\d' message: not a valid telefax number 2: constraints: - type: Email message: not a valid email address 3: constraints: - type: Regex common: - URI - tel - nofuture message: not a valid telehone number 4: constraints: - type: Regex common: - URI - tel - nofuture message: not a valid mobile phone number force: 1 message: type of input could not be determined Below the code. Greets, Mario ################################### package HTML::FormFu::Constraint::Dynamic; use strict; use base 'HTML::FormFu::Constraint'; use HTML::FormFu::ObjectUtil qw/ _require_constraint /; __PACKAGE__->mk_accessors( qw/ dynamic_field dynamic force / ); sub process { my ( $self, $params ) = @_; # we need the dynamic field parameter my $dynamic_field = $self->dynamic_field; return if !defined $dynamic_field; # the dynamic_field param must exist return if !exists $params->{$dynamic_field}; my $dynamic_value = $params->{$dynamic_field}; # do we force a known value my $force = $self->force; # we need dynamic data my $dynamic_definition = $self->dynamic; if (!defined $dynamic_definition) { # error if we force a known value if ($force) { return $self->mk_errors( { pass => 0, message => $self->message, } ); } # nothing to do return; } # Reorganize data by value my $constrain_values = $dynamic_definition; # map { # $constrain_values->{ delete $_->{value} } = { # constraint => delete $_->{constraints}, # message => delete $_->{message} # } } @$dynamic_definition; # if the value is unknown # TODO: $dynamic_value is tainted - rewrite for 'eq'-compare if (!defined $constrain_values->{ $dynamic_value }) { # error if we force a known value if ($force) { return $self->mk_errors( { pass => 0, message => $self->message, } ); } # nothing to do return; } # create constraints my @constraints; foreach my $constraint_data ( @{ $constrain_values->{ $dynamic_value }->{constraints} } ) { # CAVEAT: the css class is dynmaic_error, not xxx_error # create constraint and correct parent my $constraint = $self->_require_constraint( delete $constraint_data->{type}, $constraint_data ); $constraint->{parent} = $self->{parent}; push @constraints, $constraint; } # run constraints my @errors; foreach my $constraint ( @constraints ) { my @constraint_errors = eval { $constraint->process( $params ); }; push @errors, @constraint_errors; } # replace my message string with specific one $self->message( $constrain_values->{ $dynamic_value }->{message} ); # CAVEAT: Doesn't use any messages from the sub constraints return @errors; } 1; __END__ _______________________________________________ HTML-FormFu mailing list HTML-FormFu@lists.scsys.co.uk http://lists.scsys.co.uk/cgi-bin/mailman/listinfo/html-formfu