laravellaravel-backpack

How to correctly validate checklist field in laravel backpack?


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?


Solution

  • 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"],
            ];
        }
    }