Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Run function on load with AlpineJS

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

<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?

>Solution :

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading