Dependent Validations

Dependent Validations

schwaluckschwaluck Posts: 103Questions: 27Answers: 1

Hello everyone,

I have the following problem: In my datatable I have the columns
"test_1" (varchar), "test_2" (decimal), "test_3" (decimal) and "test_4" (varchar).

Now I want to implement the following validations:
1. If the value "oil" or the value "oil and adblue" is selected at "test_1", an input at "test_2" should be required.
2. If the value "adblue" or the value "oil and adblue" is selected in "test_1", an input in "test_3" should be required.
3. If the value "oil", the value "adblue" or the value "oil and adblue" is selected at "test_1", an input at "test_4" should be required.

I have already tried different approaches for this, but none has led to the desired result. That is my current code:

Field::inst( 'test_1' )
->validator( Validate::notEmpty( ValidateOptions::inst()
->message( 'Please select a value.' ) 
            ) ),
Field::inst( 'test_2 )
->setFormatter( Format::ifEmpty( null ) )
->validator( Validate::minNum( 0))
->validator( Validate::maxNum( 100 ) )
->validator( 'Validate::numeric', [  "decimal" => ','] )
->validator( function ($val, $data, $field){
    if($data['test_1']=='adblue' &&  is_null($val)) {
        return 'Please enter the value.';
    }
    elseif ($data['test_1']=='oil and adblue' && $val == '' ) {
        return 'Please enter the value';
    }
    else {
        return true;
    }
}),
Field::inst( 'test_3' )
->setFormatter( Format::ifEmpty( null ) )
->validator( Validate::minNum( 0))
->validator( Validate::maxNum( 100 ) )
->validator( 'Validate::numeric', [  "decimal" => ','] )
->validator( function ($val, $data, $field){
    if($data['test_1']=='oil' && $val == null) {
        return 'Please enter the value.';
    }
    elseif ($data['test_1']=='oil and adblue' && $val == null ) {
        return 'Please enter the value.';
    }
    else {
        return true;
    }
}),
Field::inst( 'test_4' )
->setFormatter( Format::ifEmpty( null ) )
->validator( function ($val, $data, $field){
    if((($data['test_1']=='adblue') || ($data['test_1']=='oil') || ($data['test_1']=='oil and adblue') ) &&
        (($data['test_2'] != "") || ($data['test_3'] != "")) && ($val == "")) {
        return 'Please enter the value.';
    }
    elseif($data['test_1']=='No' && $val == '') {
        return true;
    }
})
->validator( function ($val) {
    if ( ($val != "") && (preg_match("/[a-zA-Z,]/", $val) == 0)) {
        return true;
    }
    else {
            return "Es sind nur Ziffern erlaubt.";
    }
}),

Note: I have already replaced the part is_null($val) with the following options, but they did not help:
1. $val == ''
2. $data["test_2"] == ''
3. $data["test_2"] == null

Does anyone have an idea what the problem might be?

This question has an accepted answers - jump to answer

Answers

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406
    edited October 2020 Answer ✓

    Interesting, I didn't know you can have multiple validators for one field. If I make a custom validator I put all the validation in there ... Could that be a cause of your issue? Don't know. Maybe you want to give it a try.

    Have you checked with your debugger whether all variables are really set? This depends on the form options as well: https://editor.datatables.net/reference/option/formOptions.main
    The default for "normal" editing using the Editor form is "submit: all". But that might be different in your case?!

    Instead of using this:
    1. $val == ''
    2. $data["test_2"] == ''
    3. $data["test_2"] == null

    I always use this which covers space and null:
    1. $val <= ''
    2. $data["test_2"] <= ''

    Here is one of my validators that also checks whether the field is set at all:

    Field::inst( 'acct.external_id' )
        ->validator( function ( $val, $data, $opts ) use ( $msg ) {
            if ( $data['acct']['include'] > 0 && isset($val) ) {
                if ($val <= '') {
                    return $msg[0];
                }
            }
            return true;
        } ),            
    

    $msg is an array of language dependent error messages

    And another one - a bit more complex. Works like a charm ...

    Field::inst( 'acct.order_text' ) //only SAP civitec
        ->validator( function ( $val, $data, $opts ) use ( $msg ) {
            if ( $data['acct']['include'] > 0 && isset($val) ) {
                if ($val <= '' 
                    && $data['acct']['cost_center'] <= ''
                    && $data['acct']['funder']      <= ''
                    && $data['govdept']['acct_system']             == 'SAP'     
                    && $data['govdept']['acct_system_provider']    == 'civitec' ) {
                    return $msg[10];
                }
            }
            return true;
        } ),
    
  • schwaluckschwaluck Posts: 103Questions: 27Answers: 1

    Hey rf1234,

    thanks for the quick response. I have tried out your suggested options.

    This solved the problem:
    1. $val <= ''
    2. $data["test_2"] <= ''

    So now my code looks like:

    Field::inst( 'test_3' )
    ->validator( Validate::minNum( 0))
    ->validator( Validate::maxNum( 100 ) )
    ->validator( 'Validate::numeric', [  "decimal" => ','] )
    ->setFormatter( Format::ifEmpty( null ) )
    ->validator( function ($val, $data, $field){
        if($data['test_1']=='oil' && $val <='') {
            return 'Please enter the value for oil';
        }
        elseif($data['test_1']=='oil and adblue' && $data['test_2']<='' 
            && $val <='') {
            return 'Please enter the value for oil and adblue.';
        }
        elseif($data['test_1']=='oil and adblue' && $data['test_2'] !='' 
            && $val <='') {
            return 'Please enter the value for oil.';
        }
        elseif($data['test_1']=='oil and adblue' && $data['test_2'] <='' 
            && $val !='') {
            return 'Please enter the value for adblue.';
        }
        else {
            return true;
        }
        }),
    

    Thank you for that solution! :)

    Note: Like you can see in my code, it is possible to use separate validator for one field instance.

  • rf1234rf1234 Posts: 2,808Questions: 85Answers: 406

    Glad you got it sorted - and I learned something as well :smiley:

This discussion has been closed.