crud->addField( [ // Checklist 'label' => 'IDIOMAS', 'type' => 'checklist'," /> crud->addField( [ // Checklist 'label' => 'IDIOMAS', 'type' => 'checklist'," /> crud->addField( [ // Checklist 'label' => 'IDIOMAS', 'type' => 'checklist',"/>

How to correctly validate checklist field in laravel backpack?

43 views Asked by At

I created a "checklist" field with the following definition:

$this->crud->addField(
                [   // Checklist
                    'label'     => '<b>IDIOMAS</b>',
                    'type'      => 'checklist',
                    'name'      => 'idiomas',
                    'entity'    => 'idiomas',
                    'attribute' => 'titulo',
                    'model'     => "App\Models\Idioma",
                    'pivot'     => false,
                    'number_of_columns' => 3,
                    'wrapper' => [
                        'class' => 'form-group col-md-6',
                    ],
                    'tab' => 'HABILIDADES',
                ]
            );

I tried to validate with the following rules:

'idiomas' => 'required|array|min:1',
//'idiomas.*' => 'required|integer|exists:idiomas,id',

With the intention of forcing at least some element to be required. I did a lot of tests, the first one was just to use the "required" option, but nothing worked.

Reviewing the form that prints in html, I see that at the end there is a hidden field as follows:

<input type="hidden" value="[]" name="idiomas">

So for validation we receive "[]" which is NOT an array and cannot be validated that way. Shouldn't it be an array that you send? Because now it is a string of 2 characters that skips the validation of "required". For the moment what I did was to set the rule:

'idiomas' => 'required|min:3'

And change the validation message with:

'idiomas.min' => 'Debe seleccionar al menos un elemento'

But I was left with the doubt: Is there a better way?

Is the way Backpack Laravel returns the value to validate correct?

Should it be an array?

2

There are 2 answers

0
miken32 On BEST ANSWER

I'm not familiar with Backpack, but if the hidden element's value at initialization is [] I'm willing to bet it posts its data as a JSON string. To validate it, you'd need to decode the JSON first and then add it back into the request object. Here's my suggestion:

<?php

namespace App\Http\Requests;

use Illuminate\Foundation\Http\FormRequest;

class MyRequest extends FormRequest
{
    protected function prepareForValidation(): void
    {
        // could also use $this->replace() if desired
        $this->merge([
            "idiomas_data" => json_decode($this->idiomas),
        ]);
    }

    public function rules(): array
    {
        return [
            "idiomas_data" => ["required", "array", "min:1"],
            "idiomas_data.*" => ["integer", "exists:idiomas"],
        ];
    }
}
0
Jorge On

If you want to validate at least 1 element, can use something like this:

return [
        'idiomas' => [
            'required',
            'string',
            'json',
            function ($attribute, $value, $fail) {
                $elementsArray = json_decode($value, true);

                if (empty($elementsArray)) {
                    $fail('The '.$attribute.' must contain at least one element.');
                }
            },
        ],
    ];

Cheers.