2019-10-05 21:17:18 +02:00
|
|
|
<docs>
|
|
|
|
### Datetime Picker
|
|
|
|
|
|
|
|
> We're wrapping the Buefy datepicker & an input
|
|
|
|
|
|
|
|
### Defaults
|
|
|
|
- step: 10
|
|
|
|
|
|
|
|
### Example
|
|
|
|
```vue
|
|
|
|
<DateTimePicker :value="new Date()" />
|
|
|
|
```
|
|
|
|
</docs>
|
2019-06-07 17:19:30 +02:00
|
|
|
<template>
|
2020-02-18 08:57:00 +01:00
|
|
|
<div class="field is-horizontal">
|
|
|
|
<div class="field-label is-normal">
|
|
|
|
<label class="label">{{ label }}</label>
|
2019-11-04 16:37:57 +01:00
|
|
|
</div>
|
2020-02-18 08:57:00 +01:00
|
|
|
<div class="field-body">
|
|
|
|
<div class="field is-narrow is-grouped calendar-picker">
|
|
|
|
<b-datepicker
|
|
|
|
:day-names="localeShortWeekDayNamesProxy"
|
|
|
|
:month-names="localeMonthNamesProxy"
|
|
|
|
:first-day-of-week="parseInt($t('firstDayOfWeek'), 10)"
|
|
|
|
:min-date="minDatetime"
|
|
|
|
:max-date="maxDatetime"
|
|
|
|
v-model="dateWithTime"
|
|
|
|
:placeholder="$t('Click to select')"
|
|
|
|
:years-range="[-2, 10]"
|
|
|
|
icon="calendar"
|
|
|
|
class="is-narrow"
|
|
|
|
/>
|
|
|
|
<b-timepicker
|
|
|
|
placeholder="Type or select a time..."
|
|
|
|
icon="clock"
|
|
|
|
v-model="dateWithTime"
|
2020-07-07 09:21:00 +02:00
|
|
|
:min-time="minTime"
|
|
|
|
:max-time="maxTime"
|
2020-02-18 08:57:00 +01:00
|
|
|
size="is-small"
|
|
|
|
inline
|
|
|
|
>
|
|
|
|
</b-timepicker>
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
</div>
|
2019-06-07 17:19:30 +02:00
|
|
|
</template>
|
|
|
|
<script lang="ts">
|
2020-02-18 08:57:00 +01:00
|
|
|
import { Component, Prop, Vue, Watch } from "vue-property-decorator";
|
|
|
|
import { localeMonthNames, localeShortWeekDayNames } from "@/utils/datetime";
|
2019-10-11 18:41:29 +02:00
|
|
|
|
2019-09-26 16:38:58 +02:00
|
|
|
@Component
|
2019-06-07 17:19:30 +02:00
|
|
|
export default class DateTimePicker extends Vue {
|
2019-10-05 21:17:18 +02:00
|
|
|
/**
|
|
|
|
* @model
|
|
|
|
* The DateTime value
|
|
|
|
*/
|
|
|
|
@Prop({ required: true, type: Date, default: () => new Date() }) value!: Date;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* What's shown besides the picker
|
|
|
|
*/
|
2020-02-18 08:57:00 +01:00
|
|
|
@Prop({ required: false, type: String, default: "Datetime" }) label!: string;
|
2019-10-05 21:17:18 +02:00
|
|
|
|
|
|
|
/**
|
|
|
|
* The step for the time input
|
|
|
|
*/
|
2019-06-07 17:19:30 +02:00
|
|
|
@Prop({ required: false, type: Number, default: 1 }) step!: number;
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
/**
|
|
|
|
* Earliest date available for selection
|
|
|
|
*/
|
2019-12-10 00:10:12 +01:00
|
|
|
@Prop({ required: false, type: Date, default: null }) minDatetime!: Date;
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
/**
|
|
|
|
* Latest date available for selection
|
|
|
|
*/
|
2019-12-10 00:10:12 +01:00
|
|
|
@Prop({ required: false, type: Date, default: null }) maxDatetime!: Date;
|
2019-10-11 18:41:29 +02:00
|
|
|
|
2019-12-10 00:10:12 +01:00
|
|
|
dateWithTime: Date = this.value;
|
2019-06-07 17:19:30 +02:00
|
|
|
|
2019-10-11 18:41:29 +02:00
|
|
|
localeShortWeekDayNamesProxy = localeShortWeekDayNames();
|
2020-02-18 08:57:00 +01:00
|
|
|
|
2019-10-11 18:41:29 +02:00
|
|
|
localeMonthNamesProxy = localeMonthNames();
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
@Watch("value")
|
2020-10-01 15:07:15 +02:00
|
|
|
updateValue(): void {
|
2019-12-10 00:10:12 +01:00
|
|
|
this.dateWithTime = this.value;
|
2019-09-18 17:32:37 +02:00
|
|
|
}
|
|
|
|
|
2020-02-18 08:57:00 +01:00
|
|
|
@Watch("dateWithTime")
|
2020-10-01 15:07:15 +02:00
|
|
|
updateDateWithTimeWatcher(): void {
|
2019-10-14 19:29:18 +02:00
|
|
|
this.updateDateTime();
|
2019-09-18 17:32:37 +02:00
|
|
|
}
|
|
|
|
|
2020-10-01 15:07:15 +02:00
|
|
|
updateDateTime(): void {
|
2019-10-05 21:17:18 +02:00
|
|
|
/**
|
|
|
|
* Returns the updated date
|
|
|
|
*
|
2019-10-09 12:54:09 +02:00
|
|
|
* @type {Date}
|
2019-10-05 21:17:18 +02:00
|
|
|
*/
|
2020-02-18 08:57:00 +01:00
|
|
|
this.$emit("input", this.dateWithTime);
|
2019-06-07 17:19:30 +02:00
|
|
|
}
|
2020-07-07 09:21:00 +02:00
|
|
|
|
|
|
|
get minTime(): Date | null {
|
|
|
|
if (this.minDatetime && this.datesAreOnSameDay(this.dateWithTime, this.minDatetime)) {
|
|
|
|
return this.minDatetime;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
get maxTime(): Date | null {
|
|
|
|
if (this.maxDatetime && this.datesAreOnSameDay(this.dateWithTime, this.maxDatetime)) {
|
|
|
|
return this.maxDatetime;
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
2020-10-01 15:07:15 +02:00
|
|
|
// eslint-disable-next-line class-methods-use-this
|
2020-07-07 09:21:00 +02:00
|
|
|
private datesAreOnSameDay(first: Date, second: Date): boolean {
|
|
|
|
return (
|
|
|
|
first.getFullYear() === second.getFullYear() &&
|
|
|
|
first.getMonth() === second.getMonth() &&
|
|
|
|
first.getDate() === second.getDate()
|
|
|
|
);
|
|
|
|
}
|
2019-06-07 17:19:30 +02:00
|
|
|
}
|
|
|
|
</script>
|
2019-10-14 19:29:18 +02:00
|
|
|
|
|
|
|
<style lang="scss" scoped>
|
2020-02-18 08:57:00 +01:00
|
|
|
.timepicker {
|
2020-11-16 10:04:47 +01:00
|
|
|
::v-deep .dropdown-content {
|
2020-02-18 08:57:00 +01:00
|
|
|
padding: 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
.calendar-picker {
|
2020-11-16 10:04:47 +01:00
|
|
|
::v-deep .dropdown-menu {
|
2020-02-18 08:57:00 +01:00
|
|
|
z-index: 200;
|
|
|
|
}
|
|
|
|
}
|
2019-11-04 16:37:57 +01:00
|
|
|
</style>
|