Mike Rampling
Mike Rampling

Reputation: 35

Validation check field not empty

We're trying to have one or another field validated, the second field only shows up when they choose to not fill in the first. So we only need the second field to validate if the first is left empty from them skipping over it.

For context its to checek the make of an appliance, we have a list of brands/makes known to the system but an option to write it manually if yours doesnt show up. But we need to validate that the manual entry field isn't empty, but only if they've skipped over the first list.

'single_item_make' => 'required_if:policy_type,single|required_if:single_item_make_other,',
'single_item_make_other' => 'required_if:policy_type,single|required_if:single_item_make,'

We tried the above and it didnt work, we cant seem to find anything in the docs about checking fields for being empty.

Only one of these two fields will be submitted at a time.

Upvotes: 0

Views: 1367

Answers (2)

Robert
Robert

Reputation: 5973

You can not combine the required_if with the required_without in this case, because it conflicts.

In your current code, the first rule on both is:

required_if:policy_type,single

Which requires both fields if policy_type === 'single', if 1 of the fields is empty this validation will fail.

A solution might be to use complex conditional validation, like so:

$v = Validator::make($data, [
     'policy_type' => [
          'required',
          'in:single,x,y', // ?
     ],
     // some other static validation rules you have
]);

// conditional validation based on policy_type === 'single';
$v->sometimes('single_item_make', 'required_without:single_item_make_other', function ($input) {
    return $input->policy_type === 'single';
});

$v->sometimes('single_item_make_other', 'required_without:single_item_make', function ($input) {
    return $input->policy_type === 'single';
});

This will only check that both can't be empty at the same time and that one field is required when the other one is empty.

However, this will leave the option for the user to fill in both.


If you would want to validate that both can't be empty, but only 1 can be set at the same time (xor), you would have to extend your validator as this does not exist in Laravel.

Put this in your AppServiceProvider's boot() method:

Validator::extendImplicit('xor', function ($attribute, $value, $parameters, $validator) {
    return empty($value) || empty(data_get($validator->getData(), $parameters[0]));
});

Then you can use:

$v->sometimes('single_item_make', 'required_without:single_item_make_other|xor:single_item_make_other', function ($input) {
    return $input->policy_type === 'single';
});

$v->sometimes('single_item_make_other', 'required_without:single_item_make|xor:single_item_make', function ($input) {
    return $input->policy_type === 'single';
});

In this case, required_without makes sure that if 1 is empty the other 1 is required and the xor validation makes sure that if 1 is set, the other 1 can not have a value.

You can add custom error messages in your validation or use a custom validator and pass those validation messages there.

More info: https://laravel.com/docs/5.7/validation#conditionally-adding-rules

I have not tested both pieces of code, but they should work.

Upvotes: 1

nice_dev
nice_dev

Reputation: 17825

As the required_without docs suggest, you need to use it as below:

'single_item_make' => 'required_if:policy_type,single|required_without:single_item_make_other,',
'single_item_make_other' => 'required_if:policy_type,single|required_without:single_item_make,'

Upvotes: 0

Related Questions