Reputation: 3162
I have a button that on click it displays a toast message. I am trying to display the toast message automatically when the button is displayed (without having to click on it).
This is my code:
<button x-data
@click="$dispatch('notice', {type: 'success', text: '🔥 Success!'})"
class="m-4 bg-green-500 text-lg font-bold p-6 py-2 text-white shadow-md rounded">
Success
</button>
<div
x-data="noticesHandler()"
class="fixed inset-0 flex flex-col-reverse items-end justify-start h-screen w-screen"
@notice.window="add($event.detail)"
style="pointer-events:none">
<template x-for="notice of notices" :key="notice.id">
<div
x-show="visible.includes(notice)"
x-transition:enter="transition ease-in duration-200"
x-transition:enter-start="transform opacity-0 translate-y-2"
x-transition:enter-end="transform opacity-100"
x-transition:leave="transition ease-out duration-500"
x-transition:leave-start="transform translate-x-0 opacity-100"
x-transition:leave-end="transform translate-x-full opacity-0"
@click="remove(notice.id)"
class="rounded mb-4 mr-6 w-56 h-16 flex items-center justify-center text-white shadow-lg font-bold text-lg cursor-pointer"
:class="{
'bg-green-500': notice.type === 'success',
'bg-blue-500': notice.type === 'info',
'bg-orange-500': notice.type === 'warning',
'bg-red-500': notice.type === 'error',
}"
style="pointer-events:all"
x-text="notice.text">
</div>
</template>
</div>
<script>
function noticesHandler() {
return {
notices: [],
visible: [],
add(notice) {
notice.id = Date.now()
this.notices.push(notice)
this.fire(notice.id)
},
fire(id) {
this.visible.push(this.notices.find(notice => notice.id == id))
const timeShown = 2000 * this.visible.length
setTimeout(() => {
this.remove(id)
}, timeShown)
},
remove(id) {
const notice = this.visible.find(notice => notice.id == id)
const index = this.visible.indexOf(notice)
this.visible.splice(index, 1)
},
}
}
</script>
Tried to do it with x-init but it doesn't work:
<button x-data
x-init="$dispatch('notice', {type: 'success', text: '🔥 Success!'})"
class="m-4 bg-green-500 text-lg font-bold p-6 py-2 text-white shadow-md rounded">
Success
</button>
Any ideas on how I can do this?
Upvotes: 3
Views: 18230
Reputation: 10502
You need to also use the $nextTick
magic here, because x-init
fires before the noticesHandler()
component is ready.
<button x-data
x-init="$nextTick(() => {$dispatch('notice', {type: 'success', text: '🔥 Success!'})})"
class="m-4 bg-green-500 text-lg font-bold p-6 py-2 text-white shadow-md rounded">
Success
</button>
This way x-init
waits until Alpine.js finishes DOM updates, so basically each component is ready.
Upvotes: 9