AlpineJS – open model from the JS script (trigger toggle without button)

I have following modal:

<div x-data="modal" class="mb-5">
        <!-- modal -->
        <div class="fixed inset-0 bg-[black]/60 z-[999] hidden overflow-y-auto" :class="open && '!block'">
            <div class="flex items-start justify-center min-h-screen px-4" @click.self="open = false">
                <div x-show="open" x-transition x-transition.duration.300 class="panel border-0 p-0 rounded-lg overflow-hidden my-8 w-full max-w-lg">
                    <div class="flex bg-[#fbfbfb] dark:bg-[#121c2c] items-center justify-between px-5 py-3">
                        <div class="font-bold text-lg">Modal Title</div>
                        <button type="button" class="text-white-dark hover:text-dark" @click="toggle">
                            <svg> ... </svg>
                        </button>
                    </div>
                    <div class="p-5">
                        <div class="dark:text-white-dark/70 text-base font-medium text-[#1f2937]">
                            <p>Mauris mi tellus, pharetra vel mattis sed, tempus ultrices eros. Phasellus egestas sit amet velit sed luctus. Orci varius natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Suspendisse potenti. Vivamus ultrices sed urna ac pulvinar. Ut sit amet ullamcorper mi.</p>
                        </div>
                        <div class="flex justify-end items-center mt-8">
                            <button type="button" class="btn btn-outline-danger" @click="toggle">Discard</button>
                            <button type="button" class="btn btn-primary ltr:ml-4 rtl:mr-4" @click="toggle">Save</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

And JS code:

window.addEventListener('actionDelete', event => {

    console.log(Alpine.toggle)
})

document.addEventListener("alpine:init", () => {
    Alpine.data("modal", (initialOpenState = false) => ({
        open: initialOpenState,

        toggle() {
            this.open = !this.open;
        },
    }));
});

I am getting following error:

Uncaught TypeError: Alpine.toggle is not a function

What am I doing wrong here? How can trigger toggle without button?

>Solution :

You cannot access x-data properties directly from outside, but you can attach an event listener on the component that calls toggle() method.

Note: you have to use kebab-case (or snake case) for event names in the HTML, so add the .camel modifier to catch camelCased events.

<script defer src="https://cdn.jsdelivr.net/npm/alpinejs@3.x.x/dist/cdn.min.js"></script>

<button x-data @click="$dispatch('actionDelete')">Emit actionDelete event</button>

<div x-data="modal" @action-delete.camel.window="toggle()">
   <div x-show="open">Modal is open</div>
   <div x-show="!open">Modal is hidden</div>
</div>


<script>
document.addEventListener("alpine:init", () => {
    Alpine.data("modal", (initialOpenState = false) => ({
        open: initialOpenState,

        toggle() {
            this.open = !this.open;
        },
    }));
});
</script>

Leave a Reply