Notificaciones con laravel livewire

Con livewire se pueden despachar eventos al navegador para ser detectados con javascript y poder realizar algún tipo de acción en el front end.

Despachando eventos en el navegador

Entonces básicamente la documentación de livewire indica que hay que hacer algo como esto:

1$this->dispatchBrowserEvent('name-updated', ['newName' => $value]);

Y con javascript podemos detectar ese evento:

1<script>
2window.addEventListener('name-updated', event => {
3 alert('Name updated to: ' + event.detail.newName);
4})
5</script>

Ejemplo práctico

Supongamos que queremos levantar una notificación cuando se ejecuta una acción con un componente: Lo que tenemos que hacer es despachar el evento con ciertas características que nos permitan hacer de nuestra notificación funcional y para eso haremos esto:

1$this->dispatchBrowserEvent('notification', [
2 'body' => 'El registro fue actualizado correctamente',
3 'timeout' => 4000
4]);

Aca basicamente le indicamos a nuestra notificación que va a tener un cuerpo (body) y un tiempo de espera (timeout) de 4 segundos para que se cierre automáticamente. Y nuestra notificacion va a lucir de esta manera:

1<div
2 x-data="{body: ''}"
3 x-show="body.length"
4 x-cloak
5 x-on:notification.window="body = $event.detail.body; setTimeout(() => body = '', $event.detail.timeout || 2000)"
6 class="fixed inset-0 flex px-4 py-6 items-start pointer-events-none">
7 <div class="w-full flex flex-col items-center space-y-4">
8 <div class="max-w-sm w-full bg-gray-900 rounded-lg pointer-events-auto">
9 <div class="p-4 flex items-center">
10 <div class="ml-2 w-0 flex-1 text-white">
11 <span x-text="body"></span>
12 </div>
13 <button class="inline-flex text-gray-400" x-on:click="body = ''">
14 <span class="sr-only">Close</span>
15 <span class="text-2xl">&times;</span>
16 </button>
17 </div>
18 </div>
19 </div>
20</div>

DRY

También podemos re usar la misma notificación sin importar que estemos livewire, por ejemplo, en alguna parte de nuestra aplicación podemos tener algo como esto:

1session()->flash('notification', 'Texto de notificación');

Los cambios que tenemos que hacer son los siguientes:

1<div
2 x-data="{body: ''}"
3 x-show="body.length"
4 x-cloak
5 x-on:notification.window="body = $event.detail.body; setTimeout(() => body = '', $event.detail.timeout || 2000)"
6 class="fixed inset-0 flex px-4 py-6 items-start pointer-events-none"
7 x-init="
8 @if (session()->has('notification'))
9 window.onload = () => {
10 window.dispatchEvent(new CustomEvent('notification', {
11 detail: {
12 body: '{{ session('notification') }}',
13 timeout: 3000
14 }
15 }))
16 }
17 @endif
18 "
19 >
20 <div class="w-full flex flex-col items-center space-y-4">
21 <div class="max-w-sm w-full bg-gray-900 rounded-lg pointer-events-auto">
22 <div class="p-4 flex items-center">
23 <div class="ml-2 w-0 flex-1 text-white">
24 <span x-text="body"></span>
25 </div>
26 <button class="inline-flex text-gray-400" x-on:click="body = ''">
27 <span class="sr-only">Close</span>
28 <span class="text-2xl">&times;</span>
29 </button>
30 </div>
31 </div>
32 </div>
33</div>

Nota: esto lo saque de un curso de https://codecourse.com/

Angel Cruz's avatar
Autor
Angel Cruz