I have a modal window for filters on my application. The filters modal has @click.outside="filters = false"
so if the user clicks outside of the modal it will hide. Inside of that filters modal I have an option for choosing the minimum date for which I'm using Flatpickr.
The problem is when you click on the arrows to change the month - or the month or year at the top - the filters modal will hide.
I believe that I need to use e.stopPropagation
or @click.prevent
on the element but it hasn't worked in each spot that I've tried it.
How do I make it so that any clicks inside of the Flatpicker window doesn't propagate up and close the filters modal?
Here is my full code -
<div x-show="filters" @click.outside="filters = false" x-on:keydown.escape.window="filters = false" class="absolute shadow-lg z-40 mt-4">
<div x-trap="filters">
<div>
<label for="filter-date-min" class="block text-sm font-semibold leading-5 text-gray-700">Minimum Date</label>
<div class="mt-1 relative rounded-md shadow-sm">
<div x-data="{
value: '',
init() {
let picker = flatpickr(this.$refs.picker, {
dateFormat: 'Y-m-d',
defaultDate: this.value,
onChange: (date, dateString) => {
this.value = dateString
},
})
},
}">
<input id="filter-date-min" placeholder="MM/DD/YYYY" x-ref="picker" x-bind:value="value" class="flex-1 min-w-0 block w-full px-3 py-2 rounded-none rounded-r-md focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 border active" autocomplete="off">
</div>
</div>
</div>
</div>
</div>
A simple solution for this issue is to introduce a pickerOpen
variable that monitors the Flatpickr popup's state via the onOpen
and onClose
hooks. Then only close the modal window when Flatkpickr popup is inactive.
<div x-data="{filters: false, pickerOpen: false}">
<div x-show="filters"
@click.outside="if (!pickerOpen) {filters = false}"
x-on:keydown.escape.window="if (!pickerOpen) {filters = false}"
class="absolute shadow-lg z-40 mt-4">
<div x-trap="filters">
<div>
<label for="filter-date-min" class="block text-sm font-semibold leading-5 text-gray-700">Minimum Date</label>
<div class="mt-1 relative rounded-md shadow-sm">
<div x-data="{
value: '',
init() {
let picker = flatpickr(this.$refs.picker, {
dateFormat: 'Y-m-d',
defaultDate: this.value,
onOpen: () => {this.pickerOpen = true},
onClose: () => {this.pickerOpen = false},
onChange: (date, dateString) => {
this.value = dateString
},
})
},
}">
<input id="filter-date-min" placeholder="MM/DD/YYYY" x-ref="picker" x-bind:value="value" autocomplete="off"
class="flex-1 min-w-0 block w-full px-3 py-2 rounded-none rounded-r-md focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm border-gray-300 border active">
</div>
</div>
</div>
</div>
</div>
</div>