From 6aa941cd8dfb607d19f02ebd378c53debc255ab8 Mon Sep 17 00:00:00 2001 From: cagataycivici Date: Thu, 16 May 2019 12:19:03 +0300 Subject: [PATCH] Time support for Calendar --- src/components/calendar/Calendar.vue | 425 +++++++++++++++++++++++---- src/views/calendar/CalendarDemo.vue | 15 + 2 files changed, 386 insertions(+), 54 deletions(-) diff --git a/src/components/calendar/Calendar.vue b/src/components/calendar/Calendar.vue index 5986561ab..bcb19bbaa 100644 --- a/src/components/calendar/Calendar.vue +++ b/src/components/calendar/Calendar.vue @@ -4,43 +4,110 @@
-
-
- - -
- {{locale.monthNames[month.month]}} - - {{view === 'month' ? currentYear : month.year}} - + +
+
+ + 0{{currentHour}} + +
+
+ + + + {{timeSeparator}} + + + +
+
+ + 0{{currentMinute}} + +
+
+ + + + {{timeSeparator}} + + + +
+
+ + 0{{currentSecond}} + +
+
+ + + + {{timeSeparator}} + + + +
+
+ + {{pm ? 'PM' : 'AM'}} +
@@ -61,10 +128,6 @@ export default { inheritAttrs: false, props: { value: null, - defaultDate: { - type: Date, - default: null - }, selectionMode: { type: String, default: 'single' @@ -225,21 +288,10 @@ export default { } }, created() { - let viewDate = null; - if (this.defaultDate) { - viewDate = this.defaultDate; - } - else { - let propValue = this.value; - if (propValue && Array.isArray(propValue)) { - propValue = propValue[0]; - } - - viewDate = propValue || new Date(); - } - + const viewDate = this.viewDate; this.currentMonth = viewDate.getMonth(); this.currentYear = viewDate.getFullYear(); + this.initTime(viewDate); }, data() { return { @@ -248,10 +300,12 @@ export default { currentHour: null, currentMinute: null, currentSecond: null, + pm: null, overlayVisible: false } }, outsideClickListener: null, + timePickerTimer: null, methods: { isSelected(dateMeta) { if (this.value) { @@ -434,7 +488,7 @@ export default { this.currentMonth--; } - this.$emit('month-change', {month: this.currentMonth + 1, year: this.currentYear}); + this.$emit('month-change', {month: this.currentMonth, year: this.currentYear}); } }, navForward(event) { @@ -456,7 +510,7 @@ export default { this.currentMonth++; } - this.$emit('month-change', {month: this.currentMonth + 1, year: this.currentYear}); + this.$emit('month-change', {month: this.currentMonth , year: this.currentYear}); } }, decrementYear() { @@ -465,6 +519,24 @@ export default { incrementYear() { this.currentYear++; }, + initTime(date) { + this.pm = date.getHours() > 11; + + if (this.showTime) { + this.currentMinute = date.getMinutes(); + this.currentSecond = date.getSeconds(); + + if (this.hourFormat == '12') + this.currentHour = date.getHours() == 0 ? 12 : date.getHours() % 12; + else + this.currentHour = date.getHours(); + } + else if (this.timeOnly) { + this.currentMinute = 0; + this.currentHour = 0; + this.currentSecond = 0; + } + }, bindOutsideClickListener() { if (!this.outsideClickListener) { this.outsideClickListener = (event) => { @@ -788,6 +860,243 @@ export default { this.updateModel(null); this.overlayVisible = false; this.$emit('click-clear'); + }, + onTimePickerElementMouseDown(event, type, direction) { + if (!this.$attrs.disabled) { + this.repeat(event, null, type, direction); + event.preventDefault(); + } + }, + onTimePickerElementMouseUp(event) { + if (!this.$attrs.disabled) { + this.clearTimePickerTimer(); + this.updateModelTime(); + } + }, + repeat(event, interval, type, direction) { + let i = interval||500; + + this.clearTimePickerTimer(); + this.timePickerTimer = setTimeout(() => { + this.repeat(event, 100, type, direction); + }, i); + + switch(type) { + case 0: + if (direction === 1) + this.incrementHour(event); + else + this.decrementHour(event); + break; + + case 1: + if (direction === 1) + this.incrementMinute(event); + else + this.decrementMinute(event); + break; + + case 2: + if (direction === 1) + this.incrementSecond(event); + else + this.decrementSecond(event); + break; + } + }, + incrementHour(event) { + const prevHour = this.currentHour; + const newHour = this.currentHour + this.stepHour; + + if (this.validateHour(newHour)) { + if (this.hourFormat == '24') + this.currentHour = (newHour >= 24) ? (newHour - 24) : newHour; + else if (this.hourFormat == '12') { + // Before the AM/PM break, now after + if (prevHour < 12 && newHour > 11) { + this.pm = !this.pm; + } + + this.currentHour = (newHour >= 13) ? (newHour - 12) : newHour; + } + } + event.preventDefault(); + }, + decrementHour(event) { + const newHour = this.currentHour - this.stepHour; + + if (this.validateHour(newHour)) { + if (this.hourFormat == '24') + this.currentHour = (newHour < 0) ? (24 + newHour) : newHour; + else if (this.hourFormat == '12') { + // If we were at noon/midnight, then switch + if (this.currentHour === 12) { + this.pm = !this.pm; + } + this.currentHour = (newHour <= 0) ? (12 + newHour) : newHour; + } + } + + event.preventDefault(); + }, + validateHour(hour) { + let valid = true; + let value = this.value; + if (this.isRangeSelection()) { + value = this.value[1] || this.value[0]; + } + if (this.isMultipleSelection()) { + value = this.value[this.value.length - 1]; + } + let valueDateString = value ? value.toDateString() : null; + + if (this.minDate && valueDateString && this.minDate.toDateString() === valueDateString) { + if (this.minDate.getHours() > hour) { + valid = false; + } + } + + if (this.maxDate && valueDateString && this.maxDate.toDateString() === valueDateString) { + if (this.maxDate.getHours() < hour) { + valid = false; + } + } + + return valid; + }, + incrementMinute(event) { + let newMinute = this.currentMinute + this.stepMinute; + if (this.validateMinute(newMinute)) { + this.currentMinute = (newMinute > 59) ? newMinute - 60 : newMinute; + } + + event.preventDefault(); + }, + decrementMinute(event) { + let newMinute = this.currentMinute - this.stepMinute; + newMinute = (newMinute < 0) ? 60 + newMinute : newMinute; + if (this.validateMinute(newMinute)) { + this.currentMinute = newMinute; + } + + event.preventDefault(); + }, + validateMinute(minute) { + let valid = true; + let value = this.value; + if (this.isRangeSelection()) { + value = this.value[1] || this.value[0]; + } + if (this.isMultipleSelection()) { + value = this.value[this.value.length - 1]; + } + let valueDateString = value ? value.toDateString() : null; + if (this.minDate && valueDateString && this.minDate.toDateString() === valueDateString) { + if (value.getHours() == this.minDate.getHours()){ + if (this.minDate.getMinutes() > minute) { + valid = false; + } + } + } + + if (this.maxDate && valueDateString && this.maxDate.toDateString() === valueDateString) { + if (value.getHours() == this.maxDate.getHours()){ + if (this.maxDate.getMinutes() < minute) { + valid = false; + } + } + } + + return valid; + }, + incrementSecond(event) { + let newSecond = this.currentSecond + this.stepSecond; + if (this.validateSecond(newSecond)) { + this.currentSecond = (newSecond > 59) ? newSecond - 60 : newSecond; + } + + event.preventDefault(); + }, + decrementSecond(event) { + let newSecond = this.currentSecond - this.stepSecond; + newSecond = (newSecond < 0) ? 60 + newSecond : newSecond; + if (this.validateSecond(newSecond)) { + this.currentSecond = newSecond; + } + + event.preventDefault(); + }, + validateSecond(second) { + let valid = true; + let value = this.value; + if (this.isRangeSelection()) { + value = this.value[1] || this.value[0]; + } + if (this.isMultipleSelection()) { + value = this.value[this.value.length - 1]; + } + let valueDateString = value ? value.toDateString() : null; + + if (this.minDate && valueDateString && this.minDate.toDateString() === valueDateString) { + if (this.minDate.getSeconds() > second) { + valid = false; + } + } + + if (this.maxDate && valueDateString && this.maxDate.toDateString() === valueDateString) { + if (this.maxDate.getSeconds() < second) { + valid = false; + } + } + + return valid; + }, + updateModelTime() { + let value = this.value; + if (this.isRangeSelection()) { + value = this.value[1] || this.value[0]; + } + if (this.isMultipleSelection()) { + value = this.value[this.value.length - 1]; + } + value = value ? new Date(value.getTime()) : new Date(); + + if (this.hourFormat == '12') { + if (this.currentHour === 12) + value.setHours(this.pm ? 12 : 0); + else + value.setHours(this.pm ? this.currentHour + 12 : this.currentHour); + } + else { + value.setHours(this.currentHour); + } + + value.setMinutes(this.currentMinute); + value.setSeconds(this.currentSecond); + + if (this.isRangeSelection()) { + if (this.value[1]) + value = [this.value[0], value]; + else + value = [value, null]; + } + + if (this.isMultipleSelection()){ + value = [...this.value.slice(0, -1), value]; + } + + this.updateModel(value); + this.$emit('select', value); + }, + toggleAMPM(event) { + this.pm = !this.pm; + this.updateModelTime(); + event.preventDefault(); + }, + clearTimePickerTimer() { + if (this.timePickerTimer) { + clearInterval(this.timePickerTimer); + } } }, computed: { @@ -809,6 +1118,14 @@ export default { } }; }, + viewDate() { + let propValue = this.value; + if (propValue && Array.isArray(propValue)) { + propValue = propValue[0]; + } + + return propValue || new Date(); + }, containerClass() { return [ 'p-calendar', diff --git a/src/views/calendar/CalendarDemo.vue b/src/views/calendar/CalendarDemo.vue index 7b1aba8d2..4e77b2744 100644 --- a/src/views/calendar/CalendarDemo.vue +++ b/src/views/calendar/CalendarDemo.vue @@ -45,6 +45,18 @@

Button Bar

+
+

Time / 24h

+ +
+
+

Time Only / 12h

+ +
+
+

Month/Year Picker

+ +
@@ -84,6 +96,9 @@ export default { date5: null, date6: null, date7: null, + date8: null, + date9: null, + date10: null, dates1: null, dates2: null, es: {