| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156 |
- <!--
- Sélecteur de dates
- @see https://vuetifyjs.com/en/components/date-pickers/
- -->
- <template>
- <main>
- <v-text-field
- ref="input"
- v-model="datesFormatted"
- autocomplete="off"
- :label="$t(fieldLabel)"
- prepend-icon="mdi:mdi-calendar"
- :disabled="readonly"
- :density="dense ? 'compact' : 'default'"
- :single-line="singleLine"
- :error="error || !!fieldViolations"
- :error-messages="errorMessage || fieldViolations ? $t(fieldViolations) : ''"
- @update:focused=""
- @focus="onInputFocused($event); $emit('focus', $event)"
- @blur="onInputBlured($event); $emit('blur', $event)"
- />
- <v-menu
- activator="input"
- :model-value="dateOpen"
- :close-on-content-click="false"
- :nudge-right="40"
- transition="scale-transition"
- offset-y
- min-width="auto"
- >
- <!-- TODO: terminer une fois v-date-picker implémenté dans vuetify 3 -->
- <v-date-picker
- v-model="datesParsed"
- :range="range"
- color="ot-green lighten-1"
- @input="dateOpen = range && datesParsed.length < 2"
- />
- </v-menu>
- </main>
- </template>
- <script setup lang="ts">
- import {useNuxtApp} from "#app";
- import {useFieldViolation} from "~/composables/form/useFieldViolation";
- import {computed, ComputedRef, Ref} from "@vue/reactivity";
- import DateUtils from "~/services/utils/dateUtils";
- import {onUnmounted, watch, WatchStopHandle} from "@vue/runtime-core";
- const props = defineProps({
- field: {
- type: String,
- required: false,
- default: null
- },
- label: {
- type: String,
- required: false,
- default: null
- },
- data: {
- type: [String, Array],
- required: false,
- default: null
- },
- readonly: {
- type: Boolean,
- required: false
- },
- range: {
- type: Boolean,
- required: false
- },
- dense: {
- type: Boolean,
- required: false
- },
- singleLine: {
- type: Boolean,
- required: false
- },
- format: {
- type: String,
- required: false,
- default: 'DD/MM/YYYY'
- },
- error: {
- type: Boolean,
- required: false
- },
- errorMessage: {
- type: String,
- required: false,
- default: null
- }
- })
- const input = ref(null)
- const { emit } = useNuxtApp()
- const { data, range } = props
- const {fieldViolations, updateViolationState} = useFieldViolation(props.field)
- const datesParsed: Ref<Array<string>|string|null> = range ? ref(Array<string>()) : ref(null)
- const fieldLabel = props.label ?? props.field
- const dateOpen: Ref<boolean> = ref(false)
- const onInputFocused = (event: any) => {
- dateOpen.value = true
- }
- const onInputBlured = (event: any) => {
- dateOpen.value = false
- }
- if (Array.isArray(datesParsed.value)) {
- for (const date of data as Array<string>) {
- if (date) {
- datesParsed.value.push(DateUtils.format(date, 'YYYY-MM-DD'))
- }
- }
- } else {
- datesParsed.value = data ? DateUtils.format(data, 'YYYY-MM-DD') : null
- }
- const datesFormatted: ComputedRef<string|null> = computed(() => {
- if (props.range && datesParsed.value && datesParsed.value.length < 2) {
- return null
- }
- return datesParsed.value ? DateUtils.formatAndConcat(datesParsed.value, props.format) : null
- })
- const unwatch: WatchStopHandle = watch(datesParsed, (newValue, oldValue) => {
- if (newValue === oldValue) { return }
- if (props.range && newValue && newValue.length < 2) { return }
- updateViolationState(Array.isArray(newValue) ? DateUtils.sort(newValue) : newValue)
- })
- onUnmounted(() => {
- unwatch()
- })
- </script>
- <style scoped>
- </style>
|