Reputation: 341
I use Livewire, how can I put a loder on all pages but call it once
nav.blade.php
<html>
<head>
@livewireStyles
</head>
<body>
<livewire:layouts.header/>
{{ $slot }}
@livewireScripts
</body>
</html>
header.blade.php
<div>
<div class="spinner" wire:loading></div>
</div>
welcome.blade.php
<div>
<input wire:model="search" placeholder="Search">
</div>
When I write things in the input, it doesn't show the loder.
I want to call this loder only once and work on every page
Upvotes: 3
Views: 6789
Reputation: 70416
As of today wire:loading
only works in the scope of a single livewire component. There is no wire:loading.all
.
Simple solution: create a blade component and name it e.g. x-loading
<div class="page-loading" wire:loading>
Loading...
</div>
Style the component such that it appears e.g. in the bottom right corner of the page. You might want to use position: absolute
.
Place this component in the view of every livewire component you want to show the loading indicator for.
This solution comes with two drawbacks. First, if you try to position the loading indiator in a container that has absolute position (like a modal), it wont have the same position as you intended. Second, the loading blade component will be in every livewire component.
I just tested a more elegant solution. For this you have to use livewire js hooks: https://laravel-livewire.com/docs/2.x/reference
<script>
window.onload = function() {
Livewire.hook('message.sent', () => {
window.dispatchEvent(
new CustomEvent('loading', { detail: { loading: true }})
);
})
Livewire.hook('message.processed', (message, component) => {
window.dispatchEvent(
new CustomEvent('loading', { detail: { loading: false }})
);
})
}
</script>
<div
x-data="{ loading: false }"
x-show="loading"
@loading.window="loading = $event.detail.loading"
class="absolute z-50 bottom-20 right-20"
>
This is taking way too long...
</div>
Place this this code e.g. in your app layout.
Upvotes: 8