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

vinalvess's avatar

Livewire 3: Checkbox not working properly

Hello,

I'm currently migrating my app from livewire 2 to livewire 3 and I'm having an issue that, when I post a form with a checkbox, the value of the checkbox is always boolean instead of posting the value property of the checkbox. It used to work well on livewire 2 but on 3 it started failing. The value property of the example below has a permission name, but when I check the checkbox and post it, the value posted is a boolean(true). Any ideas?

<input class="form-check-input" type="checkbox"  wire:model="selectedPermissions.{{$loop->index}}.create" value="{{$perm->perm_create}}" />
0 likes
13 replies
LaryAI's avatar
Level 58

In Livewire 3, the behavior of checkboxes has changed. Instead of posting the value property of the checkbox, it now posts a boolean value (true or false) based on whether the checkbox is checked or not.

To solve this issue, you can modify your Livewire component to handle the checkbox value correctly. You can use the wire:click directive to update the value of the checkbox when it is clicked.

Here's an example of how you can modify your code:

<input class="form-check-input" type="checkbox" wire:model="selectedPermissions.{{$loop->index}}.create" wire:click="$set('selectedPermissions.{{$loop->index}}.create', {{$perm->perm_create}})" />

In this example, we are using the wire:click directive to update the value of selectedPermissions.{{$loop->index}}.create when the checkbox is clicked. The value is set to {{$perm->perm_create}}, which should be the desired value of the checkbox.

Make sure to replace {{$loop->index}} and {{$perm->perm_create}} with the appropriate values from your code.

This should solve the issue and correctly post the value of the checkbox instead of a boolean.

Snapey's avatar

I love how Lary grabs your suggestion and then replays it like its factual. (actually I hate it)

From the docs

By binding multiple checkboxes to the $updateTypes property, the user can select multiple update types and they will be added to the $updateTypes array property:

<input type="checkbox" value="email" wire:model="updateTypes">
<input type="checkbox" value="sms" wire:model="updateTypes">
<input type="checkbox" value="notificaiton" wire:model="updateTypes">

For example, if the user checks the first two boxes but not the third, the value of $updateTypes will be: ["email", "sms"]

So I have no idea what Lary is on about.

First off, I would examine the HTML in the browser. There you can check the correct value is actually being set on the checkbox

1 like
vinalvess's avatar

Ended up rewriting my logic to use booleans instead of string as values. But this is a big breaking change, watch out!

2 likes
vinalvess's avatar

Just found out that it doesn't even work with 0 and 1 coming from mysql tinyint column which is the schemabuilder boolean() method's datatabase type. To solve the issue I had to add a cast for the properties that are tinyint converting it to bool. It is not the end of the world but adds some pain to the upgrade process.

protected $casts = [
    'opt_in_email' => 'bool',
    'opt_in_phone' => 'bool',
  ];
9 likes
ahlvd's avatar

You have to ensure that all sub-Keys of your Model start with an empty array. e.g. by initializing before rendering like so:

for($index = 0; $index < $maxIndex; $index++) {	
	$this->selectedPermissions[$index]['created'] = [];
}

Otherwise Livewire will not work as you expected. We've had the same issue in a large dynamic form and this solved the issue.

1 like
WadeShuler's avatar

This seems to be an issue with livewire v3. I had this working with v2.. updated.. moved to Form component. and stumbled across my checkboxes.

I don't know if bool works as casts, but the laravel docs show boolean:

protected $casts = [
    'opt_in_email' => 'boolean',
    'opt_in_phone' => 'boolean',
];

In my MySQL database, I have an is_valid_email column, which is a tinyint like it should be. Value of 1 or 0. The checkbox doesn't recognize an integer of 1 as true.

<div class="form-check form-switch my-4">
    <input type="checkbox" id="isValidEmailCheckbox" class="form-check-input" wire:model.live="form.is_valid_email" value="1" />
    <label class="form-check-label" for="isValidEmailCheckbox">Is Valid Email?</label>
</div>

It doesn't matter if I use the #[Validate] attribute or the rules() method. I tried to cast it to a boolean in my Model, didn't help.

The only way to solve it is to directly set it to true or false:

$this->is_valid_email = ($wordpressUser->is_valid_email == 1) ? true : false;
1 like
nexgendevs's avatar

@WadeShuler

Thanks for this solution, it worked perfectly for me as well. I used a shortcut version, casted it as bool in livewire component too

(bool) $wordpressUser->is_valid_email

vinalvess's avatar

The $casts to bool has been working well for me, but I have to remember to add the cast to every boolean property on every model that has boolean properties and if I forget, the checkbox does not get checked if the value is 1 in the database, on version 2 it used to work well.

paulgiorgi's avatar

can I say that livewire v2 was overall better ?

1 like
Snapey's avatar

Can I just say that there is no issue here at all...

    public $roles = [];

initialise array with existing roles

        $user = User::with('roles')->find($this->user_id);

        $this->roles = $user->roles->pluck('id');

pass all allowable roles to view in render method

 return view('livewire.user-admin')
            ->withAllRoles(Role::get());

view

@foreach($allRoles as $role)
  <label>
    <input type="checkbox" wire:model="roles" value="{{ $role->id }}"  />
  {{ $role->name }}</label>
@endforeach

and then in the save method, sync the roles

$user->roles()->sync($this->roles);

ZERO drama

Please or to participate in this conversation.