scinote-web/app/javascript/vue/shared/date_time_picker.vue
2023-11-24 12:55:22 +01:00

191 lines
5 KiB
Vue

<template>
<div class="date-time-picker grow">
<VueDatePicker
ref="datetimePicker"
:class="{
'only-time': mode == 'time',
}"
v-model="compDatetime"
:teleport="teleport"
:no-today="true"
:clearable="clearable"
:format="format"
:month-change-on-scroll="false"
:six-weeks="true"
:auto-apply="true"
:partial-flow="true"
:markers="markers"
week-start="0"
:enable-time-picker="mode == 'datetime'"
:time-picker="mode == 'time'"
:placeholder="placeholder" >
<template #arrow-right>
<img class="slot-icon" src="/images/calendar/navigate_next.svg"/>
</template>
<template #arrow-left>
<img class="slot-icon" src="/images/calendar/navigate_before.svg"/>
</template>
<template v-if="mode == 'time'" #input-icon>
<img class="input-slot-image" src="/images/calendar/clock.svg"/>
</template>
<template v-else #input-icon>
<img class="input-slot-image" src="/images/calendar/calendar.svg"/>
</template>
<template #clock-icon>
<img class="slot-icon" src="/images/calendar/clock.svg"/>
</template>
<template #calendar-icon>
<img class="slot-icon" src="/images/calendar/calendar.svg"/>
</template>
<template #arrow-up>
<img class="slot-icon" src="/images/calendar/up.svg"/>
</template>
<template #arrow-down>
<img class="slot-icon" src="/images/calendar/down.svg"/>
</template>
</VueDatePicker>
</div>
</template>
<script>
import VueDatePicker from '@vuepic/vue-datepicker';
export default {
name: 'DateTimePicker',
props: {
mode: { type: String, default: 'datetime' },
clearable: { type: Boolean, default: false },
teleport: { type: Boolean, default: true },
defaultValue: { type: Date, required: false },
placeholder: { type: String },
standAlone: { type: Boolean, default: false, required: false },
dateClassName: { type: String, default: '' },
timeClassName: { type: String, default: '' },
disabled: { type: Boolean, default: false }
},
data() {
return {
manualUpdate: false,
datetime: this.defaultValue,
time: null,
markers: [
{
date: new Date(),
type: 'dot',
color: '#3B99FD',
},
]
}
},
created() {
if (this.defaultValue) {
this.time = {
hours: this.defaultValue.getHours(),
minutes:this.defaultValue.getMinutes(),
}
}
},
components: {
VueDatePicker
},
watch: {
defaultValue: function () {
this.datetime = this.defaultValue;
if (this.defaultValue) {
this.time = {
hours: this.defaultValue.getHours(),
minutes: this.defaultValue.getMinutes()
}
}
},
datetime: function () {
if (this.mode == 'time') {
this.time = null;
if (this.datetime) {
this.time = {
hours: this.datetime.getHours(),
minutes: this.datetime.getMinutes()
}
}
return
}
if (this.manualUpdate) {
this.manualUpdate = false;
return;
}
if ( this.datetime == null) {
this.$emit('cleared');
}
if (this.defaultValue != this.datetime) {
this.$emit('change', this.datetime);
}
},
time: function () {
if (this.manualUpdate) {
this.manualUpdate = false;
return;
}
if (this.mode != 'time') return;
let newDate;
if (this.time) {
newDate = new Date();
newDate.setHours(this.time.hours);
newDate.setMinutes(this.time.minutes);
} else {
newDate = {
hours: null,
minutes: null
};
this.$emit('cleared');
}
if (this.defaultValue != newDate) {
this.$emit('change', newDate);
}
}
},
computed: {
compDatetime: {
get () {
if (this.mode == 'time') {
return this.time
} else {
return this.datetime
}
},
set (val) {
if (this.mode == 'time') {
this.time = val
} else {
this.datetime = val
}
}
},
format() {
if (this.mode == 'time') return 'HH:mm'
if (this.mode == 'date') return document.body.dataset.datetimePickerFormatVue
return `${document.body.dataset.datetimePickerFormatVue} HH:mm`
}
},
mounted() {
window.addEventListener('resize', this.close);
},
unmounted() {
window.removeEventListener('resize', this.close);
},
methods: {
close() {
this.$refs.datetimePicker.closeMenu();
},
}
}
</script>