Livewire: Using wire:click in combination with x-on:click (alpine)

Created on 2 Jan 2020  路  3Comments  路  Source: livewire/livewire

Describe the bug
Hi @calebporzio - I have a component that's using alpinejs in order to show some dropdown. The code is the following:

<div x-show="open" x-on:click.away="open = false" class="absolute right-0 mt-2 py-1 bg-white border rounded-lg shadow-xl left-0">
    @foreach($this->incident->workflow_transitions() as $transition)
        <a href="#" x-on:click="open = false" wire:click.prevent="changeStatus('{{ $transition->getName() }}')" class="block px-4 py-2 text-gray-800 hover:bg-blue-200 text-sm">
                            {{ \Illuminate\Support\Str::snakeToTitle($transition->getName()) }}
            <i class="fas fa-arrow-right mx-2"></i>
            <span class="bg-blue-700 text-xs text-white p-1">{{ \Illuminate\Support\Str::snakeToTitle($transition->getTos()[0]) }}</span>
        </a>
    @endforeach
</div>

When clicking the button, the dropdown is showing correctly - the idea is that when the user clicks on the <a>, the dropdown will close. However, it seems that having x-on:click and wire:click on the same element won't work, as the wire:click is being executed, but the dropdown is not being hidden.

Any suggestions on how I could make the 2 work together? Thanks!

Most helpful comment

You can interact with Livewire from within Alpine using what's provided by the Inline Scripts approach with Livewire. Livewire ships a @this Blade directive to access the Livewire component. So, instead of having both an Alpine and a Livewire click listener, you could combine the two calls: x-on:click.prevent="open = false; @this.call('changeStatus', {{ $transition->getName() }})".

<div x-show="open" x-on:click.away="open = false" class="absolute right-0 mt-2 py-1 bg-white border rounded-lg shadow-xl left-0">
    @foreach($this->incident->workflow_transitions() as $transition)
        <a href="#"x-on:click.prevent="open = false; @this.call('changeStatus', {{ $transition->getName() }})" class="block px-4 py-2 text-gray-800 hover:bg-blue-200 text-sm">
                            {{ \Illuminate\Support\Str::snakeToTitle($transition->getName()) }}
            <i class="fas fa-arrow-right mx-2"></i>
            <span class="bg-blue-700 text-xs text-white p-1">{{ \Illuminate\Support\Str::snakeToTitle($transition->getTos()[0]) }}</span>
        </a>
    @endforeach
</div>

All 3 comments

You can interact with Livewire from within Alpine using what's provided by the Inline Scripts approach with Livewire. Livewire ships a @this Blade directive to access the Livewire component. So, instead of having both an Alpine and a Livewire click listener, you could combine the two calls: x-on:click.prevent="open = false; @this.call('changeStatus', {{ $transition->getName() }})".

<div x-show="open" x-on:click.away="open = false" class="absolute right-0 mt-2 py-1 bg-white border rounded-lg shadow-xl left-0">
    @foreach($this->incident->workflow_transitions() as $transition)
        <a href="#"x-on:click.prevent="open = false; @this.call('changeStatus', {{ $transition->getName() }})" class="block px-4 py-2 text-gray-800 hover:bg-blue-200 text-sm">
                            {{ \Illuminate\Support\Str::snakeToTitle($transition->getName()) }}
            <i class="fas fa-arrow-right mx-2"></i>
            <span class="bg-blue-700 text-xs text-white p-1">{{ \Illuminate\Support\Str::snakeToTitle($transition->getTos()[0]) }}</span>
        </a>
    @endforeach
</div>

Great call @mattdfloyd - does this do it @pmartelletti ?

@calebporzio that would do it, yes! Thanks a lot @mattdfloyd :)

Was this page helpful?
0 / 5 - 0 ratings