How to validate fields in a repeatable type? #284
-
Currently I have a module that can add a user with fields name and email one at a time. But now we changed it so we can add multiple users at once so I used a repeatable field type. I was adding the validation at
So how can I validate the fields in a repeatable type? |
Beta Was this translation helpful? Give feedback.
Replies: 0 comments 8 replies
-
Repeatable sends the value as a json string. You can ovewrite the Something along this lines (this is pseudo, not tested but should get you working..) : use Illuminate\Support\Facades\Validator;
use \Backpack\CRUD\app\Http\Controllers\Operations\CreateOperation { store as traitStore; }
...
public function store()
{
$this->crud->hasAccessOrFail('create');
$users_to_add = json_decode(request()->get('your_repeatable_field'));
foreach($users_to_add as $user) {
Validator::make($user, ['email' => 'required|min:5', 'name' => 'required'])->validate();
}
// if we are here there is no validator errors, otherwise we would be redirected back with errors.
// mass create your users, or create them individually inside the foreach loop
\Alert::success(trans('backpack::crud.insert_success'))->flash();
return redirect()->back();
} About the validating part ... atm is not possible to figure out which one of the names failed in the repeatable field. It would get you back with like: More on field functions override here: https://backpackforlaravel.com/docs/4.1/crud-operation-create#callbacks Best, |
Beta Was this translation helpful? Give feedback.
-
I agree with @pxpm 's answer here, it should do just fine, but I think there's a more elegant way to go about it. Personally I think it's better to keep all validation in one place, and I don't see any reason not to add validation logic to the existing FormRequest. That's where the normal validation happens, that's where the I've just created a simple example on how to validate the first public function rules()
{
return [
'name' => 'required|min:5|max:255',
'description' => 'required',
'simple' => function($attribute, $value, $fail) {
$fieldGroups = json_decode($value);
// allow repeatable field group to be empty
if (count($fieldGroups) == 0) {
return true;
}
// run through each field group inside the repeatable field
// and run a custom validation for it
foreach ($fieldGroups as $key => $group) {
$fieldGroupValidator = Validator::make((array)$group, [
'text' => 'required|min:10|max:255',
'email' => 'required|email',
]);
if ($fieldGroupValidator->fails())
{
// dd($fieldGroupValidator->errors());
return $fail('One of the entries in the '.$attribute.' group is invalid.');
}
}
},
];
} The code above does have one downside, though. When something is invalid inside a field group, the ENTIRE field group is flagged as being invalid: Which... might not be what you're looking for. Obviously this could be further customized and we could parse I'd love to have a definitive guide on how to do this properly... I think this is a pretty cool problem to solve, I've had fun 😆 |
Beta Was this translation helpful? Give feedback.
-
@tabacitu Is there a solution for this? |
Beta Was this translation helpful? Give feedback.
-
@tabacitu @pxpm i think this should be fixed. Its really anoying for a user that all the repeatable field flaged as invalid. Any idea on how to solve? |
Beta Was this translation helpful? Give feedback.
-
@tabacitu @pxpm i made sth like this in the request 'order_invoice_rules_data' => function ($attribute, $value, $fail) {
$fieldGroups = json_decode($value);
foreach ($fieldGroups as $key => $group) {
$fieldGroupValidator = Validator::make((array) $group, [
'order_services[]' => 'required|min:1|max:255',
'invoice_moment_id' => 'required|min:1|max:255',
'inc_id' => 'required|min:1|max:255',
'invoice_description' => 'required|min:1|max:255',
], $this->messages())->validate();
} But showing * as required in labels and which fields are invalid (marked with red border ) i think is fixed in repeatable blade file. Im right? |
Beta Was this translation helpful? Give feedback.
-
Hello @aberaldo Thanks for sharing your solution. You can configure your repeatable fields to show the red astherisk by setting up the wrapper class required: 'wrapperAttributes' => [
'class' => 'form-group col-md-6 required',
], We still don't have a non-hacky solution for knowing exactly which row triggered the error. Well technically we could know by getting the key in the validation loop that failed and then have some kind of script that would find the "X" row and mark it with error. I didn't test this, not sure it could be implemented at all, I think it could work like that, but never tried. |
Beta Was this translation helpful? Give feedback.
Repeatable sends the value as a json string. You can ovewrite the
create()
method in your CrudController, intercept the request and manualy validate and create the users.Something along this lines (this is pseudo, not tested but should get you working..) :