Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Rretzko's avatar
Level 15

Livewire Form not validating array

Hi - I'm using a Livewire 3 Component with a Form Object on Laravel 11 app. I'd like to keep all of the input validation on the Form Object, but haven't cracked the code on validating array values.

My blade file has two groups of checkboxes ("gradesTaught" and "gradesITeach"). The validation from the Livewire component on "gradesTaught" works exactly as expected, but the validation from the Form Object (SchoolForm) does nothing. I've put the two validation routines in place to confirm that the validation per see is working and the problem is in the Form Object. Any help on where I've gone wrong is appreciated! Livewire SchoolCreateComponent

class SchoolCreateComponent extends Component
{
	public array $gradesTaught = [];
	public function rules()
    {
        return [
            'gradesTaught' => ['required','array','min:1'],
        ];
    }
 #[NoReturn] public function save(): void
    {
        $this->validate();
}

SchoolForm

class SchoolForm extends Form
{
public array $gradesITeach = [];
public function rules()
    {
        return [
            'gradesITeach' => ['required','array','min:1'],
        ];
    }
public function update()
    {
        $this->validate();

    }
}

blade component

{{-- GRADES TAUGHT IN SCHOOL --}}
            <div class="flex flex-col">
                <label for="" class="required">Grades Taught in School</label>
                <div
                    @class([
                     'flex flex-row space-x-2',
                     'border border-red-600 px-2 py-1' => $errors->has('gradesTaught'),
                     ])
                >
                    @for($i=1; $i<13; $i++)
                        <div>
                            <input wire:model.blur="gradesTaught"
                                   wire:key="gradesTaught{{ $i }}"
                                   type="checkbox"
                                   value="{{ $i }}"
                            />
                            <label>{{ $i }}</label>
                        </div>
                    @endfor
                </div>
                @error('gradesTaught')
                    <x-input-error messages="{{ $message }}" />
                @enderror
            </div>

            {{-- GRADES I TEACH IN SCHOOL --}}
            <div class="flex flex-col" >
                <label for="" class="required">Grades I Teach in School</label>
                <div
                    @class([
                     'flex flex-row space-x-2',
                     'border border-red-600 px-2 py-1' => $errors->has('gradesITeach'),
                     ])
                >
                    @for($i=1; $i<13; $i++)
                        <div>
                            <input wire:model="form.gradesITeach"
                                   wire:key="gradesITeach{{ $i }}"
                                   type="checkbox"
                                   value="{{ $i }}"
                            />
                            <label>{{ $i }}</label>
                        </div>
                    @endfor
                </div>
                @error('gradesITeach')
                <x-input-error messages="{{ $message }}" />
                @enderror
            </div>
0 likes
2 replies
LaryAI's avatar
Level 58

To address the issue of validating array values in your Livewire component and Form Object, let's break down the problem and provide a solution.

Problem Analysis

  1. Livewire Component (SchoolCreateComponent):

    • You have an array gradesTaught that is being validated correctly.
    • Validation rules are defined in the rules method and applied in the save method.
  2. Form Object (SchoolForm):

    • You have an array gradesITeach that is not being validated as expected.
    • Validation rules are defined in the rules method and applied in the update method.

Solution

The main issue seems to be the way the form data is being handled and validated. Ensure that the form data is correctly bound and validated within the Livewire component.

Step-by-Step Solution

  1. Update the Livewire Component:
    • Ensure that the form object is properly instantiated and its validation rules are applied.
use Livewire\Component;
use App\Forms\SchoolForm;

class SchoolCreateComponent extends Component
{
    public array $gradesTaught = [];
    public SchoolForm $form;

    public function mount()
    {
        $this->form = new SchoolForm();
    }

    public function rules()
    {
        return [
            'gradesTaught' => ['required', 'array', 'min:1'],
            'form.gradesITeach' => ['required', 'array', 'min:1'],
        ];
    }

    public function save()
    {
        $this->validate();
        $this->form->update();
    }

    public function render()
    {
        return view('livewire.school-create-component');
    }
}
  1. Update the Form Object:
    • Ensure that the form object has the correct validation rules and methods.
use Livewire\Form;

class SchoolForm extends Form
{
    public array $gradesITeach = [];

    public function rules()
    {
        return [
            'gradesITeach' => ['required', 'array', 'min:1'],
        ];
    }

    public function update()
    {
        $this->validate();
        // Perform the update logic here
    }
}
  1. Update the Blade Component:
    • Ensure that the form data is correctly bound to the Livewire component and form object.
{{-- GRADES TAUGHT IN SCHOOL --}}
<div class="flex flex-col">
    <label for="" class="required">Grades Taught in School</label>
    <div
        @class([
            'flex flex-row space-x-2',
            'border border-red-600 px-2 py-1' => $errors->has('gradesTaught'),
        ])
    >
        @for($i=1; $i<13; $i++)
            <div>
                <input wire:model.blur="gradesTaught"
                       wire:key="gradesTaught{{ $i }}"
                       type="checkbox"
                       value="{{ $i }}"
                />
                <label>{{ $i }}</label>
            </div>
        @endfor
    </div>
    @error('gradesTaught')
        <x-input-error messages="{{ $message }}" />
    @enderror
</div>

{{-- GRADES I TEACH IN SCHOOL --}}
<div class="flex flex-col">
    <label for="" class="required">Grades I Teach in School</label>
    <div
        @class([
            'flex flex-row space-x-2',
            'border border-red-600 px-2 py-1' => $errors->has('form.gradesITeach'),
        ])
    >
        @for($i=1; $i<13; $i++)
            <div>
                <input wire:model="form.gradesITeach"
                       wire:key="gradesITeach{{ $i }}"
                       type="checkbox"
                       value="{{ $i }}"
                />
                <label>{{ $i }}</label>
            </div>
        @endfor
    </div>
    @error('form.gradesITeach')
        <x-input-error messages="{{ $message }}" />
    @enderror
</div>

Explanation

  • Livewire Component: The SchoolCreateComponent now includes the SchoolForm object and validates both gradesTaught and form.gradesITeach.
  • Form Object: The SchoolForm object contains its own validation rules and an update method to handle the form submission.
  • Blade Component: The form fields are correctly bound to the Livewire component and form object, ensuring that validation errors are displayed appropriately.

This should ensure that both gradesTaught and gradesITeach arrays are validated correctly.

Rretzko's avatar
Rretzko
OP
Best Answer
Level 15

It seems obvious in retrospect, but in case anyone else hits this problem, the solution is to prepend 'form.' on the error:

@error('form.gradesITeach')
       <x-input-error messages="{{ $message }}" />
@enderror

and NOT

@error('gradesITeach')
      <x-input-error messages="{{ $message }}" />
 @enderror

Please or to participate in this conversation.