DateTimePicker.vue 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <template>
  2. <v-row>
  3. <v-col cols="12" md="6">
  4. <v-text-field
  5. :model-value="dateModel ? _useDate.format(dateModel, 'fullDateWithWeekday') : undefined"
  6. :label="$t('choose_day')"
  7. prepend-icon="fas fa-calendar"
  8. :rules="rules"
  9. :variant="variant"
  10. :error="error || !!fieldViolations"
  11. :error-messages="
  12. errorMessage || (fieldViolations ? $t(fieldViolations) : '')
  13. "
  14. readonly
  15. >
  16. <v-menu
  17. v-model="showMenuDate"
  18. :close-on-content-click="false"
  19. activator="parent"
  20. min-width="0"
  21. >
  22. <v-date-picker
  23. :model-value="dateModel"
  24. @update:model-value="onUpdateDate($event)"
  25. />
  26. </v-menu>
  27. </v-text-field>
  28. </v-col>
  29. <v-col cols="12" md="6">
  30. <v-text-field
  31. :model-value="time"
  32. :variant="variant"
  33. :label="$t('choose_hour')"
  34. prepend-icon="fas fa-clock"
  35. :rules="rules"
  36. :error="error || !!fieldViolations"
  37. :error-messages="
  38. errorMessage || (fieldViolations ? $t(fieldViolations) : '')
  39. "
  40. readonly
  41. >
  42. <v-menu
  43. v-model="showMenuTime"
  44. :close-on-content-click="false"
  45. activator="parent"
  46. min-width="0"
  47. >
  48. <v-time-picker
  49. :model-value="time"
  50. format="24hr"
  51. @update:model-value="onUpdateTime($event)"
  52. scrollable
  53. />
  54. </v-menu>
  55. </v-text-field>
  56. </v-col>
  57. </v-row>
  58. </template>
  59. <script setup lang="ts">
  60. import type { PropType, Ref } from 'vue'
  61. import { ref } from 'vue'
  62. import { useFieldViolation } from '~/composables/form/useFieldViolation'
  63. import { useDate } from 'vuetify'
  64. import DateUtils from "~/services/utils/dateUtils";
  65. const props = defineProps({
  66. /**
  67. * v-model
  68. */
  69. modelValue: {
  70. type: String as PropType<Date | string | null>,
  71. required: false,
  72. default: null,
  73. },
  74. /**
  75. * Nom de la propriété d'une entité lorsque l'input concerne cette propriété
  76. * - Utilisé par la validation
  77. * - Laisser null si le champ ne s'applique pas à une entité
  78. */
  79. field: {
  80. type: String,
  81. required: false,
  82. default: null,
  83. },
  84. /**
  85. * Label du champ
  86. * Si non défini, c'est le nom de propriété qui est utilisé
  87. */
  88. label: {
  89. type: String,
  90. required: false,
  91. default: null,
  92. },
  93. /**
  94. * Définit si le champ est en lecture seule
  95. */
  96. readonly: {
  97. type: Boolean,
  98. required: false,
  99. },
  100. /**
  101. * Règles de validation
  102. * @see https://vuetify.cn/en/components/forms/#validation-with-submit-clear
  103. */
  104. rules: {
  105. type: Array,
  106. required: false,
  107. default: () => [],
  108. },
  109. /**
  110. * Le champ est-il actuellement en état d'erreur
  111. */
  112. error: {
  113. type: Boolean,
  114. required: false,
  115. },
  116. /**
  117. * Si le champ est en état d'erreur, quel est le message d'erreur?
  118. */
  119. errorMessage: {
  120. type: String,
  121. required: false,
  122. default: null,
  123. },
  124. /**
  125. * @see https://vuetifyjs.com/en/api/v-autocomplete/#props-variant
  126. */
  127. variant: {
  128. type: String as PropType<
  129. | 'filled'
  130. | 'outlined'
  131. | 'plain'
  132. | 'underlined'
  133. | 'solo'
  134. | 'solo-inverted'
  135. | 'solo-filled'
  136. | undefined
  137. >,
  138. required: false,
  139. default: 'outlined',
  140. },
  141. })
  142. const showMenuTime = ref(false)
  143. const showMenuDate = ref(false)
  144. const _useDate = useDate()
  145. const { fieldViolations, updateViolationState } = useFieldViolation(props.field)
  146. const dateModel = computed(()=> props.modelValue ? new Date(props.modelValue) : undefined)
  147. const time = computed(()=> props.modelValue ? _useDate.format(new Date(props.modelValue),'fullTime24h') : undefined)
  148. const emit = defineEmits(['update:model-value'])
  149. const onUpdateDate = (event: string) => {
  150. updateViolationState()
  151. let date = DateUtils.combineDateAndTime(event, time.value)
  152. emit('update:model-value', date.toISOString().replace('.000Z', '+00:00'))
  153. }
  154. const onUpdateTime = (event: string) => {
  155. updateViolationState()
  156. let date = DateUtils.combineDateAndTime(dateModel.value, event)
  157. emit('update:model-value', date.toISOString().replace('.000Z', '+00:00'))
  158. }
  159. onBeforeUnmount(() => {
  160. updateViolationState()
  161. })
  162. </script>
  163. <style scoped lang="scss">
  164. </style>