Issue using "required_if" validation rule in form builder

kiltedup - 5 months ago

Hi,

I think this is a Laravel issue but posting here to see if anyone has encountered this and can suggest a solution. I had a form with a bunch of custom validation. This was working on Pyro 3.0 but since the site was upgraded to 3.3 it has stopped working.

Issue is that if a 'required_if' rule is used, any subsequent rules are still processed. Whereas before they would be skipped. Example rules on two fields :

'sosParent' => [
    'type' => 'anomaly.field_type.select',
    'required' => true,
    'config' => [
        'default_value' => 'Yes',
        'mode' => 'radio',
            'options' => [
                'Yes' => 'Yes',
                'No'  => 'No',
            ],
        ],
    ],
],
'sosTel' => [
    'type' => 'anomaly.field_type.text',
    'required' => false,
    'config' => [
        'type' => 'tel'
    ],
    'rules' => [
        'required_if:sosParent,No|digits:11'
    ],
],

Before - if my sosParent field was set to 'Yes' then the 'digits' rule on sosTel was ignored. But now it is still enforced. This sosTel field only appears when sosParent is 'No' so the error is never shown.

If that makes sense, any suggestions on how to ignore the second rule ????

Thanks

Dave

ryanthompson - 5 months ago

This might be because of the nullable rule introduced in Laravel 5.3..

Can you dump your rules for the form here: https://github.com/anomalylabs/streams-platform/blob/1.2/src/Ui/Form/FormValidator.php#L107

kiltedup - 5 months ago

array(25) {
  ["u16_memberID"]=>
  string(8) "nullable"
  ["first_name"]=>
  string(8) "required"
  ["last_name"]=>
  string(8) "required"
  ["username"]=>
  string(46) "alpha_num|unique:users_users,username|required"
  ["password"]=>
  string(8) "required"
  ["gender"]=>
  string(8) "required"
  ["addressParent"]=>
  string(8) "required"
  ["address1"]=>
  string(28) "required_if:addressParent,No"
  ["address2"]=>
  string(8) "nullable"
  ["town"]=>
  string(28) "required_if:addressParent,No"
  ["county"]=>
  string(28) "required_if:addressParent,No"
  ["postcode"]=>
  string(40) "required_if:addressParent,No|min:5|max:8"
  ["country"]=>
  string(28) "required_if:addressParent,No"
  ["nationality"]=>
  string(8) "required"
  ["dob"]=>
  string(73) "regex:/[0-9]{2}\/[0-9]{2}\/[0-9]{4}/|date_format:d/m/Y|valid_dob|required"
  ["sosParent"]=>
  string(8) "required"
  ["sosName"]=>
  string(24) "required_if:sosParent,No"
  ["sosTel"]=>
  string(34) "required_if:sosParent,No|digits:11"
  ["medicalCondition"]=>
  string(8) "required"
  ["medicalNotes"]=>
  string(32) "required_if:medicalCondition,Yes"
  ["socialConnect"]=>
  string(8) "nullable"
  ["socialName"]=>
  string(8) "nullable"
  ["socialID"]=>
  string(8) "nullable"
  ["socialToken"]=>
  string(16) "nullable|max:255"
  ["tshirt"]=>
  string(8) "required"
}

ryanthompson - 5 months ago

You can comment out this line: https://github.com/anomalylabs/streams-platform/blob/1.2/src/Ui/Form/Component/Field/Guesser/NullableGuesser.php#L53

That's really the only thing I've changed in rules / validation for the longest time. That will give you the "old" behavior as far as Pyro is concerned. Everything I believe is Laravel.

kiltedup - 5 months ago

It's the sosTel that's the issue. sosParent is set to Yes so sosTel is NOT required, but the sosTel still needs 11 digits to validate Just seen the 'nullable' stuff : So the rule : required_if:sosParent,No|nullable|digits:11 appears to do the trick .... I think

ryanthompson - 5 months ago

Excellent!

mattcdavis1 - 2 months ago

@ryanthompson - so is modifying the core the only way to get required_with/required_if to work? I'm having the same issue due to nullable being the first rule and my formBuilder rules just getting merged into that.

mattcdavis1 - 2 months ago

For now i've added the below to my custom form validator but ideally validation should be overrideable via the model rules and this nullable issue should be fixed.

public function handle(FormBuilder $builder)
    {
        $rules = [
            'referer_company' => [
                'required_with:referer_fee_percent',
            ],
            'referer_broker_name' => [
                'required_with:referer_fee_percent',
            ],
            'referer_street' => [
                'required_with:referer_fee_percent',
            ],
            'referer_city' => [
                'required_with:referer_fee_percent',
            ],
            'referer_state' => [
                'required_with:referer_fee_percent',
            ],
            'referer_zip' => [
                'required_with:referer_fee_percent',
            ],
            'referer_license_number' => [
                'required_with:referer_fee_percent',
            ],
            'referer_email' => [
                'required_with:referer_fee_percent',
            ],
            'referer_phone' => [
                'required_with:referer_fee_percent',
            ],
            'legal6_referral_payer' => [
                'required_with:referer_fee_percent',
            ],
        ];

        foreach ($builder->getEnabledFormFields() as $field) {
            if ($fieldRules = $rules[$field->getField()] ?? null) {
                $field->setRules($fieldRules);
            }
        }

        parent::handle($builder);
    }