I have a modal that i show or hide using alpine js. When I press a button I check a bool and if it's true then I want to close that modal, to do so I have to interact with Alpines' data. Is there a way to call Alphines' functions from JS?
I've tried using custom event but that doesn't seem to work
let event = new CustomEvent("closeModal", {}); window.dispatchEvent(event)
Then in the modals' div
x-show="isOpen()" @closeModal.window="close"
CodePudding user response:
I do this with an Alpine Store value and a custom event (on the document
, but it would also bubble up to window
if you want). The alpine:init
event is registering the two document listeners.
Your button would dispatch this closemodal
event (escape keydown also hides the modal in this example).
I have style="display: none"
on the div to keep it hidden before alpine:init
is called during page load... maybe an x-cloak
on the div would achieve the same desired (initially hidden) effect.
NOTE: I include this single modal partial on all pages that need modal functionality. So it ends up being a single Alpine Store variable that all pages share, since they all share the same modal partial view in the page markup.
<script>
document.addEventListener('alpine:init', () => {
Alpine.store('openmodal', false);
document.addEventListener('openmodal', () => {
Alpine.store('openmodal', true);
})
document.addEventListener('closemodal', () => {
Alpine.store('openmodal', false);
// clear modal content here if you want
})
});
</script>
<div
x-show="$store.openmodal"
style="display: none"
x-on:keydown.escape.prevent.stop="$dispatch('closemodal');"
role="dialog"
aria-modal="true"
>
.. modal content
</div>
then somewhere else you have your button
<button onclick="$dispatch('closemodal');">close</button>