| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- <!--
- Sélecteur de dates avec Vuetify
- @see https://vuetifyjs.com/en/components/date-pickers/
- -->
- <template>
- <v-layout row wrap>
- <v-menu
- ref="menu"
- v-model="menu"
- :close-on-content-click="false"
- :nudge-right="40"
- :return-value.sync="modelValue"
- lazy
- transition="scale-transition"
- offset-y
- :max-width="290"
- :min-width="290"
- :position-x="positionX"
- :position-y="positionY"
- >
- <template v-slot:activator="{ on, attrs }">
- <v-text-field
- v-model="displayDate"
- :label="label"
- :readonly="readOnly"
- v-bind="attrs"
- v-on="on"
- @blur="menu = false"
- ></v-text-field>
- </template>
- <v-date-picker
- v-if="!withTime"
- :model-value="modelValue"
- :locale="i18n.locale.value"
- @update:model-value="updateDate"
- no-title
- scrollable
- >
- </v-date-picker>
- <v-date-picker
- v-else
- :model-value="modelValue"
- :locale="i18n.locale.value"
- @update:model-value="updateDate"
- no-title
- scrollable
- type="datetime"
- >
- </v-date-picker>
- </v-menu>
- </v-layout>
- </template>
- <script setup lang="ts">
- import { ref, computed, nextTick, watch } from 'vue'
- import { useI18n } from 'vue-i18n'
- const props = defineProps({
- modelValue: Date,
- label: String,
- readOnly: {
- type: Boolean,
- default: false,
- },
- format: {
- type: String,
- default: null,
- },
- withTime: {
- type: Boolean,
- default: false,
- },
- /**
- * Position du date-picker
- * @see https://vuetifyjs.com/en/api/v-menu/#props-position
- */
- position: {
- type: String as PropType<'left' | 'center' | 'right'>,
- default: 'center',
- },
- })
- const emit = defineEmits(['update:modelValue'])
- const i18n = useI18n()
- const menu = ref(false)
- const positionX = ref(0)
- const positionY = ref(0)
- const displayDate = computed({
- get: () => {
- if (!props.modelValue) return ''
- if (props.format) {
- return new Intl.DateTimeFormat(i18n.locale.value, {
- year: 'numeric',
- month: '2-digit',
- day: '2-digit',
- hour: props.withTime ? '2-digit' : undefined,
- minute: props.withTime ? '2-digit' : undefined,
- }).format(props.modelValue)
- }
- return props.modelValue.toLocaleDateString(i18n.locale.value)
- },
- set: () => {},
- })
- function updateDate(value) {
- emit('update:modelValue', value)
- menu.value = false
- }
- function updatePosition() {
- nextTick(() => {
- const activator = document.querySelector('.v-menu__activator')
- if (activator) {
- const rect = activator.getBoundingClientRect()
- positionX.value = rect.left
- positionY.value = rect.bottom
- }
- })
- }
- watch(menu, (val) => {
- if (val) updatePosition()
- })
- </script>
- <style scoped>
- .v-menu__content {
- position: absolute !important;
- }
- </style>
|