Rafaelindriago's avatar

Use wire:target with "magic actions"

Hello guys, we all know that Livewire offer the wire:loading feature to apply classes or attributes while the component is updating a property or calling a method, but when i want to "target" the magic action $refresh it no take effect, anyone knows how to handle this? Is Livewire 3. 👀

0 likes
5 replies
vincent15000's avatar

You don't need to target this action because wire:loading is automatically activated when the component refreshes (as you say for example while a property is updated).

What are you exactly trying to do ?

1 like
Rafaelindriago's avatar

@vincent15000 You're right, but if i use wire:loading without wire:target it will take effect for any action or update in the componente, i'm trying to make a "refresh" button and i want that the "loading" icon inside that button appears only when the magic action $refresh is called, use it without wire:target makes more sense for a global loading indicator, but this is not the case, maybe i need to create a method for refresh and target it, because with the magic methods like $refresh, $set, $toggle it doesn't work. 😢

1 like
vincent15000's avatar
Level 63

@Rafaelindriago According to the documentation, you can only target the Livewire actions or parameters that you have created, because the component refreshes only partially according to actions or properties updates.

https://livewire.laravel.com/docs/wire-loading#targeting-specific-actions

If you need to force the refresh of the component, that means that you want to refresh the entire component. In that case, you have another way to display loading indicator by using the lazy loading.

https://livewire.laravel.com/docs/lazy

1 like
Rafaelindriago's avatar

@vincent15000 thanks! Finally i just create a new method refreshAll() and target it, even is better because when use wire:loading.attr="disabled" on buttons, the focus is lost after the button is enabled again, but the disabled attribute is a mandatory to avoid multiple request if the user click many times quickly, so at the end of the method i put a $this->js() to restore the focus to the button, is more accesible in that way if the application is used with keyboard instead of mouse pointer.

1 like
Rafaelindriago's avatar

Here is my code:

Blade template:

<button class="btn btn-light"
        type="button"
        wire:click="refreshAll"
        wire:loading.attr="disabled"
        wire:target="refreshAll"
        x-ref="refreshButton">
      <span class="fas fa-fw fa-sync-alt"
            wire:loading.remove
            wire:target="refreshAll"></span>
      <span class="fas fa-fw fa-circle-notch fa-spin"
            wire:loading
            wire:target="refreshAll"></span>
</button>             		

Component method:

public function refreshAll(): void
{
    $this->js(<<<'JS'
        $refs.refreshButton.focus()
    JS);
}

Also i discover that Alpine can be used inside a Livewire component without any x-data="{}", at least the $refs magic variable and x-ref directive are available. 😉

Please or to participate in this conversation.