Closed flowbru closed 2 years ago
WIll check what is going on, can you add a snippet of which props you are using?
Thank you for your response. You can find my whole modal code including the datepicker below.
<template>
<TransitionRoot as="template" :show="open">
<Dialog as="div" class="fixed z-10 inset-0 overflow-y-auto" >
<div class="flex items-end justify-center min-h-screen pt-4 px-4 pb-20 text-center sm:block sm:p-0">
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0" enter-to="opacity-100" leave="ease-in duration-200" leave-from="opacity-100" leave-to="opacity-0">
<DialogOverlay class="fixed inset-0 bg-gray-500 bg-opacity-75 transition-opacity" />
</TransitionChild>
<span class="hidden sm:inline-block sm:align-middle sm:h-screen" aria-hidden="true">​</span>
<TransitionChild as="template" enter="ease-out duration-300" enter-from="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95" enter-to="opacity-100 translate-y-0 sm:scale-100" leave="ease-in duration-200" leave-from="opacity-100 translate-y-0 sm:scale-100" leave-to="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95">
<div class="inline-block align-bottom bg-white rounded-lg px-4 pt-5 pb-4 text-left overflow-hidden shadow-xl transform transition-all sm:my-8 sm:align-middle sm:max-w-lg sm:w-full sm:p-6">
<div>
<div class="mx-auto flex items-center justify-center h-12 w-12 rounded-full bg-green-100">
<CalendarIcon class="h-6 w-6 text-green-600" aria-hidden="true" />
</div>
<div class="mt-3 text-center sm:mt-5">
<DialogTitle as="h3" class="font-bold text-2xl leading-6 text-gray-900">
{{ $t('Create new appointment') }}
</DialogTitle>
<Datepicker v-model="date"
format="dd.MM.yyyy HH:mm"
locale="de-DE" />
</div>
</div>
<div class="mt-5 sm:mt-6 sm:grid sm:grid-cols-2 sm:gap-3 sm:grid-flow-row-dense">
<!-- TODO: Buttons -->
</div>
</div>
</TransitionChild>
</div>
</Dialog>
</TransitionRoot>
</template>
<script setup>
import { ref } from 'vue';
import { Dialog, DialogOverlay, DialogTitle, TransitionChild, TransitionRoot } from '@headlessui/vue';
import { CheckIcon, CalendarIcon } from '@heroicons/vue/outline';
import Datepicker from 'vue3-date-time-picker';
let props = defineProps({
showModal: Boolean,
});
const date = ref(new Date());
const open = ref(props.showModal);
const emit = defineEmits(['close']);
function closeModal() {
open.value = false;
emit('close');
}
</script>
<style scoped>
.dp__menu {
z-index: 9999!important;
}
</style>
Investigated a little, this is not an issue from the date picker side. The dialog itself focuses first focusable element, causing conflict within a component since the date picker has a prop open on focus. To be able to open the menu I had to add the initial-focus
element to a button as stated here.
Also, noticed some strange behavior, when I click on the component from the dialog, it does a multi-click, which is very odd. I guess they do some custom click handling in the Dialog component. This is happening only when I don't specify initial-focus
element. This is also the reason why the menu is not opening.
Also when the menu is opened with a portal, causes the dialog to close whenever the menu is clicked. This is happening if you connect the @close
event from the dialog. This will be fixed in the upcoming version.
Thank you for your support!
hi @Jasenkoo ,
I found strange behavior while using datepicker inside modal from CoreUI Vue here. which it is using bootstrap4
basically it did not prompt any error, but when I was picking a date, the modal automatically closed too.
is there any option how do I resolve this ?
Thanks in advance.
@rinaldihtb What version of the component are you using?
@rinaldihtb What version of the component are you using?
@Jasenkoo , thanks for your response,
for datepicker, i'm using the latest one. "vue3-date-time-picker": "^2.5.0",
and for CoreUI i'm using 4.1 version
Hello Guys, Recently I'm using this template https://github.com/uilibrary/AatroX-vue.
I tried to use "vue3-date-time-picker": "^2.5.0" in a modal and I couldn't get it to work. Please would you have any help?
The same problem as @flowbru
TLDR: Use teleport
feature to render the date picker from WITHIN the modal instead of default body
element
--
@lgazoni @rinaldihtb We recently encountered this error using Tailwind UI Dialog/Modal wherein the datepicker automatically closes upon any interaction.
We found out that this happens since vue3-date-time-picker
renders as a child of the root body
element and Headless UI Dialog/Modal prevents any clicks to elements outside of the modal.
To solve, we used the teleport
function of vue3-date-time-picker
to make the plugin render within the modal instead of at the root body
element, which prevents clicks/focus.
See example below:
<template>
<Dialog :open="isOpen" @close="setIsOpen">
<DialogOverlay />
<DialogTitle>Deactivate account</DialogTitle>
<DialogDescription>
This will permanently deactivate your account
</DialogDescription>
<p>
Are you sure you want to deactivate your account? All of your data will be
permanently removed. This action cannot be undone.
</p>
<div class="mt-2">
<!-- Set teleport attribute here! -->
<Datepicker
teleport="'#datePickerContainerId" <----------------- this <------------------
inputClassName="rounded-lg font--h5"
/>
</div>
<!-- Provide div for teleport WITHIN the modal -->
<div id="datePickerContainerId"></div>
<button @click="setIsOpen(false)">Deactivate</button>
<button @click="setIsOpen(false)">Cancel</button>
</Dialog>
</template>
<script>
import { ref } from "vue";
import {
Dialog,
DialogOverlay,
DialogTitle,
DialogDescription,
} from "@headlessui/vue";
import Datepicker from "vue3-date-time-picker";
import "vue3-date-time-picker/dist/main.css";
export default {
components: { Dialog, DialogOverlay, DialogTitle, DialogDescription, Datepicker },
setup() {
let isOpen = ref(true);
return {
isOpen,
setIsOpen(value) {
isOpen.value = value;
},
};
},
};
</script>
@Jasenkoo We might need to include this in the package documentation. How do we go about this? I can submit a PR, just let me know š
@johndalangin @lgazoni @rinaldihtb
@lgazoni @rinaldihtb We recently encountered this error using Tailwind UI Dialog/Modal wherein the datepicker automatically closes upon any interaction.
This is partially due to dialog, also, if you are using some form of components, most of them rely on click-outside directive from vueuse library which has an event listener on mousedown
which is triggered before I can call stopPropagnation
.
We found out that this happens since
vue3-date-time-picker
renders as a child of the rootbody
element and Headless UI Dialog/Modal prevents any clicks to elements outside of the modal.
Also, this solution works fine, that is the way the teleport target is provided. If it is rendered without teleport, it may cause some issues with relative parents.
We might need to include this in the package documentation. How do we go about this? I can submit a PR, just let me know š
For now, I have the docs in a separate repo, I might move to the main in the near future. Where would you like to add it? Under teleport or somewhere on top?
I found strange behavior while using datepicker inside modal from CoreUI Vue here. which it is using bootstrap4
I will take a deeper look at what is happening here.
We recently encountered this error using Tailwind UI Dialog/Modal
Are you using pure CSS or with some component framework?
Hello @johndalangin ,
Thank you so much. I tried to put your suggestion in the modal I developed, but unfortunately it didn't work. The form still doesn't open the calendar. another problem I had was to include the css import, it only worked including in the header as I believe it is incompatible with postCSS.
See my example below:
<template>
<link
rel="stylesheet"
href="https://unpkg.com/vue3-date-time-picker@latest/dist/main.css"
/>
<TransitionRoot appear :show="show" as="template">
<Dialog as="div">
<div class="fixed inset-5 z-10 overflow-y-auto">
<div class="min-h-screen px-4 text-center">
<TransitionChild
as="template"
enter="duration-300 ease-out"
leave="duration-200 ease-in"
>
<DialogOverlay class="fixed inset-0 bg-black opacity-10" />
</TransitionChild>
<span class="inline-block h-screen align-middle" aria-hidden="true">
​
</span>
<TransitionChild
as="template"
enter="duration-300 ease-out"
enter-from="opacity-0 scale-95"
enter-to="opacity-100 scale-100"
leave="duration-200 ease-in"
leave-from="opacity-100 scale-100"
leave-to="opacity-0 scale-95"
>
<div
class="inline-block w-full max-w-4xl p-6 my-8 overflow-hidden text-left align-middle transition-all transform bg-white shadow-xl rounded-2xl"
>
<DialogTitle
as="h3"
class="text-lg font-medium leading-6 text-gray-900"
>
Janela de configuraĆ§Ć£o de tarefa
</DialogTitle>
<div class="mt-2 mb-5">
<p class="text-sm text-gray-500">
Realize a configuraĆ§Ć£o da tarefa selecionada como um intervalo
de tempo ou monitoramento em tempo real
</p>
</div>
<!--
OPĆĆES DE SELECAO (MONITORAMENTO ON LINE OU INTERVALO)
-->
<!-- FLEX COM {TOGGLE} : {INICIO E FIM }: {BOTOES RESULTADOS E CANCELAR} -->
<div class="grid grid-flow-row-dense mb-auto">
<!-- INCLUSAO DO TOGGLE PARA ANALISE E MONITORAMENTO -->
<div class="flex-initial w-40 mb-4 my-5 mt-3">
<Switch
v-model="monitoring"
v-on:click="SwitchMonitoring()"
:class="monitoring ? 'bg-purple-500' : 'bg-purple-500'"
class="relative inline-flex items-center h-6 rounded-full w-11 border-black"
>
<!-- <span class="sr-only">Enable notifications</span> -->
<span
:class="monitoring ? 'translate-x-6' : 'translate-x-1'"
class="inline-block w-4 h-4 transform bg-white rounded-full"
/>
</Switch>
<span class="ml-2" v-if="!isActive">Intevalo</span>
<span class="ml-2" v-if="isActive">OnLine</span>
</div>
<!-- ------------------------ -->
<!-- FLEX PARA INCLUIR A SELEĆĆO DO INTRVALO DE TEMPO INICIAL E FINAL -->
<div v-show="!monitoring" class="flex" id="idAnalise">
<div class="flex-auto">
<spam
class="text-sm block tracking-wide text-gray-700 font-bold mb-2"
>Inicio:</spam
>
<Datepicker
v-model="date"
format="yyyy-MM-dd HH:mm:ss"
teleport="'#datePickerContainerId"
/><!-- include teleport -->
</div>
<!-- Provide div for teleport WITHIN the modal -->
<div id="datePickerContainerId"></div>
<div class="flex w-5"></div>
<div class="flex-auto">
<spam
class="text-sm block tracking-wide text-gray-700 font-bold mb-2"
>Fim:</spam
><Datepicker
v-model="date"
format="yyyy-MM-dd HH:mm:ss"
teleport="'#datePickerContainerId"
/> <!-- include teleport -->
</div>
<!-- Provide div for teleport WITHIN the modal -->
<div id="datePickerContainerId"></div>
<!-- BOTOES PARA RECUPERAR A ANALISE E CANCELAR -->
<div class="flex w-5"></div>
<div class="float-right mt-5 flex">
<BaseBtn
class="border border-primary text-primary rounded-full hover:bg-primary hover:text-white mt-2 mr-2"
@click="closeModal(true)"
>Resultados</BaseBtn
>
<BaseBtn
class="border border-danger text-danger rounded-full hover:bg-danger hover:text-white mt-2 mr-2"
@click="closeModal(false)"
>Cancelar</BaseBtn
>
</div>
</div>
<!-- {FREQUENCIA } : {BOTOES RESULTADOS E CANCELAR} -->
<div v-show="monitoring" class="flex">
<div class="flex-col" id="idRealTime">
<div class="flex-auto">
<spam
class="text-sm block tracking-wide text-gray-700 font-bold mb-2"
>FrequĆŖncia (seg):</spam
>
<!-- entrada do campo frequencia do Timer -->
<input
class="number flex-auto appearance-none block bg-gray-50 text-gray-700 border border-gray-200 rounded leading-tight focus:outline-none focus:bg-white focus:border-gray-500"
id="freq"
type="number"
value="50"
name="frequencyNumber"
/>
</div>
</div>
<!-- BOTOES PARA REALTIME E CANCELAR -->
<div class="flex w-5"></div>
<div class="float-right mt-5 flex">
<BaseBtn
class="border border-primary text-primary rounded-full hover:bg-primary hover:text-white mt-2 mr-2"
@click="closeModal(true)"
>Monitoramento</BaseBtn
>
<BaseBtn
class="border border-danger text-danger rounded-full hover:bg-danger hover:text-white mt-2 mr-2"
@click="closeModal(false)"
>Cancelar</BaseBtn
>
</div>
</div>
</div>
<!-- ------------------------------------------------------------- -->
</div>
</TransitionChild>
</div>
</div>
</Dialog>
</TransitionRoot>
<TemplateEditor
:show="edit"
:title="title"
:type="type"
:subTemplate="selectedGraph"
@close="edit = false"
@confirm="addGraph"
/>
</template>
<script>
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import BaseBtn from "@/components/Base/BaseBtn.vue";
import { mapActions } from "vuex";
import Datepicker from "vue3-date-time-picker";
//import "vue3-date-time-picker/dist/main.css";
import {
TransitionRoot,
TransitionChild,
Dialog,
DialogOverlay,
DialogTitle,
Switch,
} from "@headlessui/vue";
export default {
props: {
show: Boolean, ///< Boolean para exibir a janela
idTask: Number, ///< Id da task atual
taskName: String, ///< Nome da Task
},
data() {
let completeButtonRef = null;
const date = new Date();
return {
url: process.env.API_URL, ///< Teste com Env
monitoring: true, ///< Toogle de selecao (false == Intervals, true == Realtime)
date, ///< Data Atual
startDateTime: Date, ///< Data inicial com hora
endDateTime: Date, ///< Data Final com hora
frequency: Number, ///< Numero da frequencia em ms para monitoramento em real time
completeButtonRef,
};
},
//mounted() {
//
//},
components: {
BaseBtn,
TransitionRoot,
TransitionChild,
Dialog,
DialogOverlay,
DialogTitle,
Switch,
Datepicker,
},
methods: {
...mapActions({ updateTemplate: "userSession/updateTemplate" }),
/**
* @brief recarrega template original
*
*/
refresh() {
this.editedTemplate = { ...this.template };
},
/**
* @brief fecha o modal de lista dos grƔficos
*
* @param confirm indica se o usuƔrio confirmou as alteraƧƵes feitas no template
*/
closeModal(confirm) {
if (confirm) {
//this.updateTemplate({ ...this.editedTemplate });
}
this.$emit("closeModal");
},
},
/**
* Funcao para Exibir ou ocultar os parametros de monitoramento conforme selecionado
* Realtime ==>
* Intervals ==> Start and Time
*/
SwitchMonitoring() {
console.log(this.mode);
// if (mode == "visible") {
// this.isRealtime = "visible";
// } else {
// this.isRealtime = "invisible";
// }
},
computed: {
/** funcao para controlar o estado do toggle (analise ou realtime) */
isActive() {
return this.monitoring;
},
},
};
</script>
@johndalangin I have another issue following the teleport example posted.
Every time styles of transform, left and top are added into the teleport causing it datepicker to be rendered offscreen. The id given is modified based on the id of the teleport.
Hi @lgazoni kindly check your syntax you may have an unnecessary '
here:
teleport="'#datePickerContainerId"
^
^
^
Sorry about that, that's my bad.
@jadpdm Could you provide a codesandbox.io
link to an example of your concern? Thank you.
Hi there,
thanks alot for your awesome datepicker!
I just tried to use it inside a modal (tailwindui) and the input field is displayed correctly. However when I click on the input field, the date picker menu is not being opened. When I embed the datepicker the exact same way on the normal page, it works as expected.
What am I missing here?