in my project I use Laravel 8, Livewire and Alpine.js.
My livewire toaster code (app\Http\Livewire\ToasterNotification.php):
<?php
namespace App\Http\Livewire;
use Livewire\Component;
class ToasterNotification extends Component
{
public $notifications = array();
protected $listeners = ['notificationUpdate', 'notificationRemove'];
public function notificationUpdate($notif)
{
array_push($this->notifications, $notif);
$this->dispatchBrowserEvent('toast-message-show');
}
public function notificationRemove($id)
{
unset($this->notifications[$id]);
}
public function render()
{
return view('livewire.toaster-notification');
}
}
Which executes this blade (resources\views\livewire\toaster-notification.blade.php
) and he will call a blade component named toaster on "x-toaster":
<div
wire:poll.5s
aria-live="polite"
aria-atomic="true"
style="z-index:1200; position: absolute; top: 70px; right: 20px; min-height: 200px;"
>
@foreach($notifications as $i => $notification)
<x-toaster id="{{ $i }}" message="{{ $notification['message'] }}" color="{{ $notification['color'] }}"/>
@endforeach
</div>
(resources\views\components\toaster.blade.php):
<div
class="toaster toastAlert show border-{{ $color }}"
style="min-width: 250px"
data-autohide="false"
role="alert"
aria-live="assertive"
aria-atomic="true"
id="toastAlert{{ $id }}"
>
<div class="toast-header">
<svg class="bd-placeholder-img rounded mr-2 bg-{{ $color }}" width="20" height="20" focusable="false" role="img">
<rect width="100%" height="100%" fill="#ffffff00"></rect>
</svg>
<strong class="mr-auto">{{ $message }}</strong>
<button type="button" class="ml-2 mb-1 close" wire:click="notificationRemove({{ $id }})">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
I want improve the old system which reloads every 5s and use alpine along livewire if possible. Actually my code looks like this :
<script defer src="https://unpkg.com/alpinejs@3.9.0/dist/cdn.min.js"></script>
<style> [x-cloak] { display: none !important; } </style>
<div
x-data="{show:false}"
@toast-message-show.window="
show = true;
setTimeout(() => show=false, 5000);
"
x-show="show"
x-cloak
>
@foreach($notifications as $i => $notification)
<x-toaster id="{{ $i }}" message="{{ $notification['message'] }}" color="{{ $notification['color'] }}"/>
@endforeach
</div>
But I have no display. I think there is an issue because nothing is executed while in the foreach. I've tried to add some test messages like
<h1 x-data="{ message: 'I ❤️ Alpine' }" x-text="message"></h1>
But nothing worked out.
Ok i found out the answer, it was messy but i had to remove the style and put the src in the blade app.