DateRangePickerCustom.vue 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. <template >
  2. <div v-click-outside="onOutsideClick">
  3. <v-text-field
  4. v-model="dateIntervalText"
  5. type="text"
  6. class="text-field"
  7. outlined
  8. readonly
  9. clearable
  10. hide-details
  11. :label="$t('when') + ' ?'"
  12. append-icon="mdi-calendar"
  13. @click="onClick"
  14. @change="$emit('change', $event ? $event.value : '')"
  15. @click:append="onClick"
  16. />
  17. <v-card v-show="show" class="date-picker pa-2">
  18. <div class="d-flex flex-row">
  19. <div class="presets">
  20. <a
  21. v-for="preset in presets"
  22. class="preset-link"
  23. @click="presetClicked(preset.range)"
  24. >
  25. {{ preset.label }}
  26. </a>
  27. </div>
  28. <v-date-picker
  29. ref="datePicker1"
  30. :value="isoDateStart"
  31. range
  32. :min="today"
  33. scrollable
  34. no-title
  35. locale="fr"
  36. @change="dateRangeChanged"
  37. />
  38. </div>
  39. </v-card>
  40. </div>
  41. </template>
  42. <script lang="ts">
  43. import Vue from 'vue'
  44. import { format, parse, addDays, addMonths, nextSunday } from 'date-fns'
  45. interface DateRangePreset {
  46. label: string,
  47. range: DateRange
  48. }
  49. export default Vue.extend({
  50. props: {
  51. value: {
  52. type: Object
  53. }
  54. },
  55. data () {
  56. return {
  57. model: null as DateRange | null,
  58. dateStart: null as Date | null,
  59. dateEnd: null as Date | null,
  60. show: false
  61. }
  62. },
  63. methods: {
  64. onClick() {
  65. this.show = !this.show
  66. },
  67. onOutsideClick() {
  68. this.show = false
  69. },
  70. presetClicked(range: DateRange) {
  71. this.dateStart = range.start
  72. this.dateEnd = range.end
  73. },
  74. clear () {
  75. this.dateStart = null
  76. this.dateEnd = null
  77. },
  78. dateToString(date: Date | null) {
  79. return date !== null ? format(date, 'yyyy-MM-dd') : ''
  80. },
  81. stringToDate(date: string) {
  82. return new Date(date)
  83. }
  84. },
  85. computed: {
  86. today() {
  87. return format(new Date(), 'yyyy-MM-dd')
  88. },
  89. presets (): Array<DateRangePreset> {
  90. const today = new Date()
  91. // Today
  92. const today_preset: DateRangePreset = {
  93. label: this.$t('today').toString(),
  94. range: {start: today, end: today}
  95. }
  96. // Cette semaine
  97. const week_preset: DateRangePreset = {
  98. label: this.$t('next_week').toString(),
  99. range: {start: today, end: addDays(today, 7)}
  100. }
  101. // Ce week-end
  102. const sunday: Date = nextSunday(today)
  103. const weekend_preset = {
  104. label: this.$t('next_weekend').toString(),
  105. range: {start: addDays(sunday, -1), end: sunday}
  106. }
  107. // Ce mois
  108. const month_preset: DateRangePreset = {
  109. label: this.$t('next_month').toString(),
  110. range: {start: today, end: addMonths(today, 1)}
  111. }
  112. return [today_preset, week_preset, weekend_preset, month_preset]
  113. },
  114. dateIntervalText (): string {
  115. if (this.dateStart !== null && this.dateEnd !== null) {
  116. return format(this.dateStart, 'dd/MM/yyyy') + ' ~ ' + format(this.dateEnd, 'dd/MM/yyyy')
  117. } else if (this.dateStart !== null) {
  118. return format(this.dateStart, 'dd/MM/yyyy') + ' ~ ?'
  119. } else if (this.dateEnd !== null) {
  120. return '? ~ ' + format(this.dateEnd, 'dd/MM/yyyy')
  121. } else {
  122. return ''
  123. }
  124. }
  125. }
  126. })
  127. </script>
  128. <style scoped>
  129. .date-picker {
  130. z-index: 1;
  131. position: absolute;
  132. }
  133. .presets {
  134. display: flex;
  135. flex-direction: column;
  136. padding: 12px;
  137. min-width: 120px;
  138. font-size: 14px;
  139. }
  140. .preset-link {
  141. padding: 12px 0;
  142. }
  143. .preset-link:hover {
  144. text-decoration: underline;
  145. }
  146. </style>