Laravel/PHP: How to Validate Rendered Fields? - php

I have three forms, and one submit button. I only render two of the forms at any given point based on some predicate but when I submit the form, I would like the validate only the fields that exist in the currently rendered forms
Here is what the validation rules look
public function rules($request) {
return [
'name' => 'required|max:255',
'firm' => 'required|max:255',
'contactnumber' => 'required|numeric',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|confirmed|min:'.Spark::minimumPasswordLength(),
'vat_id' => 'nullable|max:50|vat_id',
'terms' => 'required|accepted',
'accountHolderEmail' => 'required|email|max:255',
'accountHolder' => 'required|max:255',
'cardNumber' => 'required|numeric|digits:16',
'cvc' => 'required|numeric|digits:3',
'expiry_month' => array('required', 'regex:/0[1-9]|1[0-2]/'),
'expiry_year' => 'required|numeric|digits:4|date_format:Y|after:'. date('Y', strtotime('-1 years'))
];
}
I would like to validate the last six fields only when I have rendered the form that contains those fields, but I just cannot seem to get it right.
I have tried adding sometimes but that just makes the fields completely optional and that is not the desired behavior because when the form requiring those fields is rendered, we actually need the fields to be mandatory.
I have also tried using Validator::make and passing those last six fields there and that does not do it as well.

You can set flags for each form and set a value for them whether they are rendered or not.
For example
<input name="flag1" value="1"> //if form 1 is rendered
<input name="flag2" value="0"> //if form 2 is not rendered
Then you can use required_if validator like mentioned below:
'name' => 'required_if:flag1,1|max:255',
'firm' => 'required_if:flag2,1|max:255',

Related

Laravel validate array and exclude on specific array value

I have an array of values that I send together with other fields in a form to laravel.
The array contains a role_id field and a status field, the status can be I (Insert) U (update) D (Delete). When I validate the values in the array I want it to skip the ones where the status equals D. Otherwise I want it to validate.
private function checkValuesUpdate($userid = null)
{
return Request::validate(
[
'displayname' => 'required',
'username' => 'required',
'email' => ['nullable', 'unique:contacts,email' . (is_null($userid ) ? '' : (',' . $userid ))],
'roles.*.role_id' => ['exclude_if:roles.*.status,D', 'required']
]
);
}
I can't seem to get it to work. I've been searching all over the place for functional code as well as the Laravel documentation. But no luck so far. Has anybody ever done this?
Your problem comes from a misunderstanding of the exclude_if rule. It doesn't exclude the value from validation, it only excludes the value from the returned data. So it would not be included if you ran request()->validated() to get the validated input values.
According to the documentation, you can use validation rules with array/star notation so using the required_unless rule might be a better approach. (Note there's also more concise code to replace the old unique rule, and I've added a rule to check contents of the role status.)
$rules = [
'displayname' => 'required',
'username' => 'required',
'email' => [
'nullable',
Rule::unique("contacts")->ignore($userid ?? 0)
],
'roles' => 'array',
'roles.*.status' => 'in:I,U,D',
'roles.*.role_id' => ['required_unless:roles.*.status,D']
];

Laravel Validation rules: required_without

I have two fields: Email and Telephone
i want to create a validation where one of two fields are required and if one or both fields are set, it should be the correct Format.
I tried this, but it doesnt work, i need both though
public static array $createValidationRules = [
'email' => 'required_without:telephone|email:rfc',
'telephone' => 'required_without:email|numeric|regex:/^\d{5,15}$/',
];
It is correct that both fields produce the required_without error message if both are empty. This error message clearly says that the field must be filled if the other is not. You may change the message if needed:
$messages = [
'email.required_without' => 'foo',
'telephone.required_without' => 'bar',
];
However, you must add the nullable rule, so the format rules don't apply when the field is empty:
$rules = [
'email' => ['required_without:telephone', 'nullable', 'email:rfc'],
'telephone' => ['required_without:email', 'nullable', 'numeric', 'regex:/^\d{5,15}$/'],
];
Furthermore: It is recommended writing the rules as array, especially when using regex.

laravel validate array fields

I am trying to validate array field using laravel validate functionality as follow
$this->validate($request,['prodActualQty' => 'required|numeric','actQty[]' => 'required'
],$messages);
my input file is: <input class='form-control' type='text' name='actQty[]'>
It gives error if fields are blank but it still gives error even we fill the fields.
In Laravel 5.2 you can validate Form array elements using wildcards keyword.
So as per your situation you can either remove [] like below
$this->validate($request->all(), [
'prodActualQty' => 'required',
'actQty' => 'required'
]);
Or use wildcard operator
$this->validate($request->all(), [
'prodActualQty' => 'required',
'actQty.*' => 'required'
]);

Laravel Validation one of two fields must be filled

I have two fields:
QQ
Email
How do I set up a Validator object so that one of these fields must be filled? It doesn't matter which.
$messages = array(
'email.required_without:qq' => Lang::get('messages.mustenteremail'),
'email.email' => Lang::get('messages.emailinvalid'),
'qq.required_without:email' => Lang::get('messages.mustenterqq'),
);
required_without should work.
It means that the field is required if the other field is not present. If have more than two fields and only one is required, use required_without_all:foo,bar,...
$rules = array(
'Email' => 'required_without:QQ',
'QQ' => 'required_without:Email',
);
In the example above (given by lucasgeiter) you actually only need one of the conditions not both.
$rules = array(
'Email' => 'required_without:QQ'
);
If you have both rules then filling neither in will result in TWO error messages being displayed. This way it will check that at least one field is filled in and will only display one error message if neither are filled.
Laravel >= 8.32 only support.
Both (mobile or email) are presented simultaneously -> throw an error.
Both (mobile or email) is not present simultaneously -> throw an error.
Allowed
Only one parameter can be allowed.
'email' => [ 'prohibited_unless:mobile,null,','required_without:mobile','email', 'max:255', ],
'mobile' => [ 'prohibited_unless:email,null','required_without:email', 'digits_between:5,13', 'numeric' ],
EDIT: You can also use prohibits:email and prohibits:mobile in combination of required_without:... rule

Laravel if field required, don't return error for each value?

I have a very large registration form.
'username_c' => 'required|unique:contacts_cstm',
'password' => 'required|min:6',
'email' => 'required|email',
'password_repeat' => 'required|same:password',
'first_name' => 'required',
'last_name' => 'required',
'rsa' => 'required',
And so on (another 15 fields)...
The problem is if the form is submitted with nothing entered, about 20 different errors are returned (as they should be).
Except, it would be nice if any of the required fields is NOT entered, to spit back one error saying "All fields are required" or something similar.
I've read through Laravel's docs. on this and didn't find anything. Is there any easy way to do this?
Assuming that all of your fields in the $rules array are required, you should be able to do something as simple as an array_filter($required_fields_input), compare the length against that of your $required_rules and redirect back with a single error message/alert.
See code example below. I tried to keep it simple/commented enough...
Not tested at all ... but theoretically! .... ;)
class YourController {
// ...
public function postFormData()
{
$rules = [
// ...
'first_name' => 'required',
'last_name' => 'required',
'rsa' => 'required'
// ...
];
// Assuming all fields in $rules are "required"
$required_fields = array_keys($rules);
$required_fields_input = Input::only($required_fields);
// Clean out all empty/null fields
$input_not_empty = array_filter($required_fields_input);
if (count($input_not_empty) < count($required_fields))
{
$fill_them_all_in_message = "Please fill in all required fields.";
return Redirect::back()->withMessage($fill_them_all_in_message);
}
/**
* All required fields present
* Continue as usual ..
* .. Validate/Respond/etc...
*/
}
//...
}
I think that pretty much covers your main concern of
a.) Avoiding 15 messages that say "XYZ field is required" ....
b.) Still allowing for the rest of the validation/processing to continue as usual.
Hope that helps!

Categories