Search code examples
laravel-livewire

Livewire checkbox preselected not working


I have collection of permission_types which i can access in my view. I am looping the permission_types to show each one in check box. all the checkboxes are binded to permission_resource, which is defined as a public property array. I want all the checkboxes to be preselected for which i used checked attribute but it won't work, as soon as i remove the wire:model attribute from input all the checkboxes are preselected. which narrows down the problem to wire:model binding.

What i am trying to achieve:

All i want to do is preselect the checkboxes binded to public property $permission_resource. Can anyone please help me out. I really cannot figure out what am i doing wrong here. Appreciate any effort to solve this problem in advance.

Relevent Component Code:

public $permission_types;
public $permission_resource = [];

public function render()
{
    $this->permission_types = PermissionType::all();
            
    // dd($this->permission_types->toArray());
            
    return view('livewire.permissions.create-permission-component')
            ->extends('layouts.app')
            ->section('content');
}

Relevant View Code:

<div class="row">
    @foreach($this->permission_types as $permissionType)
        <div class="col-md-3">
             <input wire:model="permission_resource" type="checkbox" class="filled-in chk-col-green form-control" id="{{$permissionType['name']}}" value="{{ $permissionType['name'] }}" checked />
            <label for="{{ $permissionType['name'] }}" class="p-r-30">{{ ucfirst($permissionType['name']) }} Resource</label>
        </div>
    @endforeach
</div>

Permission Types Dump

enter image description here

What i have tried so far:

so far i have tried following but none of it worked for me.

1: defining public $permission_resource; instead of public $permission_resource = [];

2: wire:model="permission_resource.{{$permissionType["id"]}}"

3: wire:model="permission_resource.{{$permissionType["name"]}}"

4: wire:model.defer="permission_resource.{{$permissionType["id"]}}"

5: wire:model.defer="permission_resource.{{$permissionType["name"]}}"

6: name="permission_resource.{{$permissionType["id"]}}"


Solution

  • You are binding all the inputs to the same (array) variable, what you want to do is bind each to an element in that array, not to the array itself.

    So you would need to prepopulate that array, and then bind each input using $loop->index.

    Not sure if you have a good reason for populating permission_types in the render method, better in mount if it is not highly dynamic (likely to change from render to render).

    Populating permission_resource in mount might look like this:

        public function mount() {
            $this->permission_types = PermissionType::all();
            $this->permission_resource = $this->permission_types->pluck('name');
        }
    

    Then in the blade, bind to elements of the array, and don't set checked yourself, wire:model will always override this anyway, checking your checkbox if the thing you have bound to is truthy, and unchecking if bound var is falsey (this is why everything is unchecked for you with the wire:model binding them to the array, because empty($array) == false, if you just fix the casing of permission_type in the blade you will find the checkbox all come on when you check one, because they are all bound to the same thing).

    <input wire:model="permission_resource.{{$loop->index}}" type="checkbox" class="filled-in chk-col-green form-control" id="{{$permission_type['name']}}" value="{{$permission_type['name']}}" />
    

    PS: That will at least get to what you wanted, depending on what you are ultimately trying to do with permission_resource, it may not be a very good/useful representation for the purpose.