Search code examples
laravellaravel-livewirelaravel-10laravel-livewire-wiremodellaravel-livewire-wireclick

Livewire component renders element attribute in wrong order and breaks the wire:click event


I'm working on a livewire component that acts as a file browser.

Initially a list of files and folders is passed to the components blade, if the item is a directory an anchor is returned which changes the current path to the items name which essentially 'moves' into the folder by requesting the files for the new path.

If the item is a file, a checkbox is returned like so

<input wire:model="fileList" class="form-check-input" value="latest.log" type="checkbox">

moving between folders and toggeling checkboxes works on the first render without issues, however when moved into another directory the wire:click event is not fired anymore. After changing the components controller numerous of times I noticed the when the view is re-rendered the checkbox is now returned but the attributes are in a different order like so:

<input class="form-check-input" type="checkbox" value="latest.log" wire:model="fileList">

After moving between folders a few times the checkboxes are returned as initially defined and the wire:click event is working as well. What is causing this behaviour? Why would the order change if its strictly defined in a blade templates for-loop like this;

@foreach ($files as $file)
    @if($file['attributes']['is_file'] == 'true')
        <input wire:model="fileList" class="form-check-input" value="{{ltrim($currentPath . '/' .  $file['attributes']['name'], '/')}}" type="checkbox">
    @else
        <a href="#" wire:click="updatePath('{{ $currentPath . '/' .  $file['attributes']['name'] }}')" class="link-danger"> {{ $file['attributes']['name'] }}</a>
    @endif
@endforeach

My components controller uses this function to move to a new folder;

public function updatePath($path)
    {
        $this->currentPath = ltrim($path, '/');

        $this->getFiles();
        $this->render();
    }

the getFiles() functions is defined like so;

    public function getFiles()
    {
        //redacted
        $this->files = $apiRequest['data'];
    }

It works as intended except for the checkboxes suddnly not fireing an event anymore.


Solution

  • As I have fixed the issue I am just going to answer my own question. Adding a unique wire:key allows keeping track of the inputs:

    <input wire:key="value.log" wire:model="fileList" class="form-check-input" value="latest.log" type="checkbox">
    

    This is also documented on livewire's website, I just must have missed it there.