livewire: Multiple checkboxes with the same `wire:model` not being bound to an array

Describe the bug Data binding does not appear to be working for checkboxes. Other input types, including radio buttons do work as expected. The model is initialized to an empty array but the checkbox all start as checked. On un-checking one, a boolean value is sent to the server.

To Reproduce Steps to reproduce the behavior:

  1. Source of App\Http\Livewire\Demo.php:
<?php

namespace App\Http\Livewire;

use Livewire\Component;

class Demo extends Component
{
    public $color = 'none';
    public $cars = [];

    public function render()
    {
        return view('livewire.demo');
    }
}
  1. Source of resource\view\livewire\demo.blade.php:
<div>
    <form>
        <fieldset>
            <legend>Colors</legend>
            <div>
                <label for="color">None</label>
                <input type="radio" wire:model="color" name="color" value="none">
            </div>
            <div>
                <label for="color">Red</label>
                <input type="radio" wire:model="color" name="color" value="red">
            </div>
            <div>
                <label for="color">Blue</label>
                <input type="radio" wire:model="color" name="color" value="blue">
            </div>
        </fieldset>

        <fieldset>
            <legend>Cars</legend>
            <div>
                <label for="cars">Honda</label>
                <input type="checkbox" wire:model="cars" name="cars" value="honda">
            </div>
            <div>
                <label for="cars">Ford</label>
                <input type="checkbox" wire:model="cars" name="cars" value="ford">
            </div>
            <div>
                <label for="cars">Golf</label>
                <input type="checkbox" wire:model="cars" name="cars" value="golf">
            </div>
        </fieldset>
    </form>

    <hr>

    <div>
        <p>The color is: {{ $color }}</p>

        <p>Selected cars:</p>
        <ul>
            @forelse ($cars as $car)
            <li>{{ $car }}</li>
            @empty
            <li>No cars selected</li>
            @endforelse
        </ul>
    </div>
</div>

Expected behavior On setting the initial state of the model to an empty array, I would expect all checkboxes bound to the model to be unchecked. On checking a checkbox, I would expect the value of that checkbox to be sent to the server.

Screenshot Payload of ‘cars’ model as a boolean Capture

Desktop (please complete the following information):

  • Browser, Chrome, Windows

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 42 (8 by maintainers)

Most upvoted comments

@intrepidws - I believe what you’re looking for is the current functionality:

  • Behavior Sep-04-2019 10-02-25

  • Code

... Component {
    public $event = [];
...
}

<div>
    <input type="checkbox" wire:model="event", value="123">
    <input type="checkbox" wire:model="event", value="456">
    <div>@json($event)</div>
</div>

In order to prime the checkboxes from my model, I found it necessary to convert the IDs to strings

mount;

        $this->groups = $user->groups()->pluck('id')->map(
                                function($group) {
                                    return strval($group);
                                });

or

        $this->groups = $user->groups()->pluck('id')->map(fn($g) => strval($g));

This has been fixed and is available in the latest release: v0.2.10

unfortunately, I can see this problem still exist, not sure if I am missing something!

Thanks Caleb. As Caleb rightly says, single checkboxes are working correctly. As a temporary fix I used nested data binding to achieve something similar:

demo.blade.php:

@foreach ($cars as $car)
<div>
    <label for="cars">{{ $car }}</label>
    <input type="checkbox" wire:model="cars.{{ $car }}" name="cars" value="1">
</div>
@endforeach

Similar to @redbastie but am using the id’s of the values that I will save:

                @foreach($items as $item)
                    <input type="checkbox" value="1"
                               wire:model="myItems.{{ $item->id }}">
                        {{ $item->name }}
                @endforeach

And then in my save method in the component I use array_keys on $myItems.

To initialise the checked boxes, in mount() I create myItems like so:

$this->myItems = array_fill_keys($user->items->toArray(), 1);

Any way to use the debounce method for multiple checkboxes bound to the same model? I’m finding that debouncing only applies to each individual input, rather than all of the checkboxes.

The solution is to prefill the array apparently.

public $event = [];

good answer…thank you