From 656d8c0dd4c3d012cc74a84ea1000892f2341935 Mon Sep 17 00:00:00 2001 From: 07akioni <07akioni2@gmail.com> Date: Wed, 24 Jul 2019 16:30:14 +0800 Subject: [PATCH] refactor(date-picker): using time-picker --- .../datePickerDemo/basicUsage.demo.vue | 27 +- packages/common/DatePicker/src/main.vue | 138 ++----- packages/common/DatePicker/src/panel/date.vue | 328 ++++++++++++++++ .../common/DatePicker/src/panel/datetime.vue | 359 ++++++------------ packages/common/Modal/src/ModalContent.vue | 5 + packages/common/TimePicker/src/main.vue | 20 +- packages/mixins/placeable.js | 1 + styles/DatePicker.scss | 2 +- styles/TimePicker.scss | 4 +- styles/Tooltip.scss | 1 + 10 files changed, 515 insertions(+), 370 deletions(-) diff --git a/demo/components/datePickerDemo/basicUsage.demo.vue b/demo/components/datePickerDemo/basicUsage.demo.vue index b1441e077..bf38c84a4 100644 --- a/demo/components/datePickerDemo/basicUsage.demo.vue +++ b/demo/components/datePickerDemo/basicUsage.demo.vue @@ -9,13 +9,13 @@ > @@ -26,18 +26,20 @@ style="flex-wrap: nowrap;" > -
datetime v-model: {{ dateTimeTimestamp }}, date v-model: {{ dateTimestamp }}
+
datetime v-model: {{ JSON.stringify(ts1) }}, date v-model: {{ JSON.stringify(ts2) }}
@@ -48,8 +50,8 @@ export default { data () { return { - dateTimeTimestamp: 891360258000, - dateTimestamp: 891360258000 + ts1: null, + ts2: 0 } }, methods: { @@ -58,6 +60,13 @@ export default { }, onDateChange (timestamp, dateString) { this.$NMessage.success(`${timestamp}, ${dateString}`) + }, + handleInputTs1 (v) { + v = Number(v) + this.ts1 = Number.isNaN(v) ? null : v + }, + handleInputTs2 (v) { + this.ts2 = Number.isNaN(v) ? null : v } } } diff --git a/packages/common/DatePicker/src/main.vue b/packages/common/DatePicker/src/main.vue index 8cb83fad5..693d1e220 100644 --- a/packages/common/DatePicker/src/main.vue +++ b/packages/common/DatePicker/src/main.vue @@ -12,9 +12,9 @@ class="n-date-picker__input" :placeholder="placeholder" :readonly="disabled ? 'disabled' : false" - @focus="openCalendar" + @click="handleActivatorClick" @blur="handleDateTimeInputBlur" - @keyup.enter="handleDateTimeInputEnter" + @input="handleDateTimeInputInput" >
+
@@ -44,6 +52,7 @@ import NIcon from '../../Icon' import detachable from '../../../mixins/detachable' import placeable from '../../../mixins/placeable' import DatetimePanel from './panel/datetime' +import DatePanel from './panel/date' import clickoutside from '../../../directives/clickoutside' const DATE_FORMAT = { @@ -68,16 +77,13 @@ export default { }, components: { NIcon, - DatetimePanel + DatetimePanel, + DatePanel }, mixins: [ detachable, placeable ], - model: { - prop: 'value', - event: 'change' - }, props: { disabled: { type: Boolean, @@ -88,7 +94,7 @@ export default { default: 'bottom-start' }, value: { - type: [Number, String], + type: Number, required: false, default: null }, @@ -111,21 +117,14 @@ export default { data () { return { displayDateTimeString: '', - displayDateString: '', - displayTimeString: '', rightDisplayDateTimeString: '', - rightDisplayDateString: '', - rightDisplayTimeString: '', calendarDateTime: moment(), rightCalendarDateTime: moment(), currentDateTime: moment(), active: false, - showTimeSelector: false, - showRightTimeSelector: false, calendar: [], rightCalendar: [], - ...TIME_CONST, - panelValue: this.value + ...TIME_CONST } }, computed: { @@ -181,75 +180,10 @@ export default { } }, methods: { - handlePanelValueChange (value, valueString) { - this.$emit('change', value, valueString) + handlePanelInput (value, valueString) { + this.$emit('input', value, 'unavailable for now') this.refreshSelectedDateTimeString() }, - /** - * If new datetime is null or undefined, emit null to value. - * Else adjust new datetime by props.type and emit it to value. - */ - setValue (newSelectedDateTime) { - if (newSelectedDateTime === null || newSelectedDateTime === undefined) { - this.$emit('change', null) - return - } - if (newSelectedDateTime.isValid()) { - const adjustedDateTime = this.adjustDateTimeAccrodingToType(newSelectedDateTime) - if (this.computedSelectedDateTime === null || adjustedDateTime.valueOf() !== this.computedSelectedDateTime.valueOf()) { - this.$emit('change', adjustedDateTime.valueOf(), adjustedDateTime.format(this.format)) - } - } - }, - adjustDateTimeAccrodingToType (datetime) { - if (this.type === 'datetime') { - return moment(datetime).startOf('second') - } else { - return moment(datetime).startOf('date').hour(0) - } - }, - justifySelectedDateTimeAfterChangeTimeString () { - if (this.computedSelectedDateTime === null) { - // case here is impossible for now, because you can't clear time for now - } else { - const newDisplayDateTimeString = this.displayDateString + ' ' + this.displayTimeString - const newSelectedDateTime = moment(newDisplayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - } - }, - handleTimeInput (e) { - const newDisplayDateTimeString = this.displayDateString + ' ' + e.target.value - const newSelectedDateTime = moment(newDisplayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - }, - handleDateInput (e) { - const newDisplayDateTimeString = e.target.value + ' ' + this.displayTimeString - const newSelectedDateTime = moment(newDisplayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - }, - handleTimeInputBlur () { - this.refreshSelectedDateTimeString() - }, - handleDateInputBlur () { - this.refreshSelectedDateTimeString() - }, - handleTimeConfirmClick () { - this.justifySelectedDateTimeAfterChangeTimeString() - this.refreshSelectedDateTimeString() - this.closeTimeSelector() - }, - handleTimeCancelClick () { - this.closeTimeSelector() - }, - openTimeSelector () { - if (this.computedSelectedDateTime === null) { - this.setValue(moment()) - } - this.showTimeSelector = true - }, - closeTimeSelector () { - this.showTimeSelector = false - }, /** * If not selected, display nothing, * else update datetime related string @@ -260,16 +194,6 @@ export default { return } this.displayDateTimeString = this.computedSelectedDateTime.format(this.format) - this.displayDateString = this.computedSelectedDateTime.format('YYYY-MM-DD') - this.displayTimeString = this.computedSelectedDateTime.format('HH:mm:ss') - }, - /** - * If new time is invalid, do nothing. - * If valid, update. - */ - handleDateTimeInputEnter () { - const newSelectedDateTime = moment(this.displayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) }, /** * If new SelectedDateTime is valid, update `selectedDateTime` and `calendarTime` @@ -277,12 +201,18 @@ export default { */ handleDateTimeInputBlur () { const newSelectedDateTime = moment(this.displayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - /** - * If newSelectedDateTime is invalid, display string need to be restored - */ - this.refreshSelectedDateTimeString() - this.closeCalendar() + if (newSelectedDateTime.isValid()) { + this.$emit('input', newSelectedDateTime.valueOf()) + } else { + this.refreshSelectedDateTimeString() + } + }, + handleActivatorClick (e) { + if (this.active) { + e.stopPropagation() + } else { + this.openCalendar() + } }, /** * Calendar view related methods @@ -301,6 +231,12 @@ export default { }, toggleCalendar () { + }, + handleDateTimeInputInput (v) { + const newSelectedDateTime = moment(this.displayDateTimeString, this.format, true) + if (newSelectedDateTime.isValid()) { + this.$emit('input', newSelectedDateTime.valueOf()) + } } } } diff --git a/packages/common/DatePicker/src/panel/date.vue b/packages/common/DatePicker/src/panel/date.vue index e69de29bb..7f345ff99 100644 --- a/packages/common/DatePicker/src/panel/date.vue +++ b/packages/common/DatePicker/src/panel/date.vue @@ -0,0 +1,328 @@ + + + diff --git a/packages/common/DatePicker/src/panel/datetime.vue b/packages/common/DatePicker/src/panel/datetime.vue index b67e01c9b..9f403c27d 100644 --- a/packages/common/DatePicker/src/panel/datetime.vue +++ b/packages/common/DatePicker/src/panel/datetime.vue @@ -8,100 +8,20 @@
- -
- - -
-
-
-
- {{ hour }} -
-
-
-
- {{ minute }} -
-
-
-
- {{ second }} -
-
-
-
- - Cancel - - - Confirm - -
-
-
-
+ /> +
-
Confirm @@ -205,15 +125,15 @@ import NIcon from '../../../Icon' import clickoutside from '../../../../directives/clickoutside' import NButton from '../../../Button' +import NTimePicker from '../../../TimePicker' +import NInput from '../../../Input' + +const DATETIME_FORMAT = 'YYYY-MM-DD HH:mm:ss' +const DATE_FORMAT = 'YYYY-MM-DD' +const DATE_VALIDATE_FORMAT = ['YYYY-MM-DD', 'YYYY-MM-D', 'YYYY-M-D', 'YYYY-M-DD'] + +const PLACEHOLDER = 'Select date and time' -const DATE_FORMAT = { - date: 'YYYY-MM-DD', - datetime: 'YYYY-MM-DD HH:mm:ss' -} -const PLACEHOLDER = { - date: 'Select date', - datetime: 'Select date and time' -} const TIME_CONST = { weekdays: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], hours: ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12', '13', '14', '15', '16', '17', '18', '19', '20', '21', '22', '23'], @@ -224,74 +144,65 @@ const TIME_CONST = { export default { components: { NButton, - NIcon + NIcon, + NTimePicker, + NInput }, directives: { clickoutside }, - model: { - prop: 'value', - event: 'change' - }, props: { active: { type: Boolean, default: true }, value: { - type: [Number, String], + type: Number, required: false, default: null }, debug: { type: Boolean, default: false + }, + placeholder: { + type: String, + default: PLACEHOLDER + }, + format: { + type: String, + default: DATETIME_FORMAT } }, data () { return { - displayDateTimeString: '', displayDateString: '', - displayTimeString: '', - rightDisplayDateTimeString: '', - rightDisplayDateString: '', - rightDisplayTimeString: '', calendarDateTime: moment(), - rightCalendarDateTime: moment(), currentDateTime: moment(), - showTimeSelector: false, - showRightTimeSelector: false, calendar: [], - rightCalendar: [], ...TIME_CONST } }, computed: { - placeholder () { - return PLACEHOLDER[this.type] - }, - format () { - return DATE_FORMAT[this.type] - }, computedHour () { - if (this.computedSelectedDateTime) return this.computedSelectedDateTime.format('HH') + if (this.valueAsMoment) return this.valueAsMoment.format('HH') else return null }, computedMinute () { - if (this.computedSelectedDateTime) return this.computedSelectedDateTime.format('mm') + if (this.valueAsMoment) return this.valueAsMoment.format('mm') else return null }, computedSecond () { - if (this.computedSelectedDateTime) return this.computedSelectedDateTime.format('ss') + if (this.valueAsMoment) return this.valueAsMoment.format('ss') else return null }, /** * If value is valid return null. * If value is not valid, return moment(value) */ - computedSelectedDateTime () { + valueAsMoment () { if (this.value === null || this.value === undefined) return null - const newSelectedDateTime = moment(Number(this.value)) + const newSelectedDateTime = moment(this.value) if (newSelectedDateTime.isValid()) { return newSelectedDateTime } else { @@ -299,170 +210,113 @@ export default { } } }, + watch: { + valueAsMoment (newValue) { + if (newValue !== null) { + this.displayDateString = newValue.format(DATE_FORMAT) + } else { + this.displayDateString = '' + } + } + }, + created () { + if (this.valueAsMoment !== null) { + this.displayDateString = this.valueAsMoment.format(DATE_FORMAT) + } else { + this.displayDateString = '' + } + }, methods: { + dateArray, handleClickOutside () { this.closeCalendar() - console.log('clickoutside') }, - dateArray, - /** - * If new datetime is null or undefined, emit null to value. - * Else adjust new datetime by props.type and emit it to value. - */ setValue (newSelectedDateTime) { if (newSelectedDateTime === null || newSelectedDateTime === undefined) { - this.$emit('change', null) - return - } - if (newSelectedDateTime.isValid()) { - const adjustedDateTime = this.adjustDateTime(newSelectedDateTime) - if (this.computedSelectedDateTime === null || adjustedDateTime.valueOf() !== this.computedSelectedDateTime.valueOf()) { - this.refreshSelectedDateTimeString(adjustedDateTime) - this.$emit('change', adjustedDateTime.valueOf(), adjustedDateTime.format(this.format)) + this.$emit('input', null) + } else if (newSelectedDateTime.isValid()) { + const adjustedDateTime = this.adjustValue(newSelectedDateTime) + if (this.valueAsMoment === null || adjustedDateTime.valueOf() !== this.valueAsMoment.valueOf()) { + this.refreshDisplayDateString(adjustedDateTime) + this.$emit('input', adjustedDateTime.valueOf()) } } - // this.$nextTick(this.refreshSelectedDateTimeString) }, - adjustDateTime (datetime) { + adjustValue (datetime) { return moment(datetime).startOf('second') }, - justifySelectedDateTimeAfterChangeTimeString () { - if (this.computedSelectedDateTime === null) { - // case here is impossible for now, because you can't clear time for now + handleDateInput (value) { + const date = moment(value, DATE_FORMAT, true) + if (date.isValid()) { + if (!this.valueAsMoment) { + const newValue = moment() + newValue.year(date.year()) + newValue.month(date.month()) + newValue.date(date.date()) + this.$emit('input', this.adjustValue(newValue).valueOf()) + } else { + const newValue = this.valueAsMoment + newValue.year(date.year()) + newValue.month(date.month()) + newValue.date(date.date()) + this.$emit('input', this.adjustValue(newValue).valueOf()) + } } else { - const newDisplayDateTimeString = this.displayDateString + ' ' + this.displayTimeString - const newSelectedDateTime = moment(newDisplayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) + // do nothing } }, - handleTimeInput (e) { - const newDisplayDateTimeString = this.displayDateString + ' ' + e.target.value - const newSelectedDateTime = moment(newDisplayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - }, - handleDateInput (e) { - const newDisplayDateTimeString = e.target.value + ' ' + this.displayTimeString - const newSelectedDateTime = moment(newDisplayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - }, - handleTimeInputBlur () { - this.refreshSelectedDateTimeString() - }, handleDateInputBlur () { - this.refreshSelectedDateTimeString() - }, - handleTimeConfirmClick () { - this.justifySelectedDateTimeAfterChangeTimeString() - this.refreshSelectedDateTimeString() - this.closeTimeSelector() - }, - handleTimeCancelClick () { - this.closeTimeSelector() - }, - setHour (hour) { - try { - const timeArray = this.displayTimeString.split(':') - timeArray[0] = hour - this.displayTimeString = timeArray.join(':') - } catch (err) { - - } finally { - this.justifySelectedDateTimeAfterChangeTimeString() + const date = moment(this.displayDateString, DATE_VALIDATE_FORMAT, true) + if (date.isValid()) { + if (!this.valueAsMoment) { + const newValue = moment() + newValue.year(date.year()) + newValue.month(date.month()) + newValue.date(date.date()) + this.$emit('input', this.adjustValue(newValue).valueOf()) + } else { + const newValue = this.valueAsMoment + newValue.year(date.year()) + newValue.month(date.month()) + newValue.date(date.date()) + this.$emit('input', this.adjustValue(newValue).valueOf()) + } + } else { + this.refreshDisplayDateString() } }, - setMinute (minute) { - try { - const timeArray = this.displayTimeString.split(':') - timeArray[1] = minute - this.displayTimeString = timeArray.join(':') - } catch (err) { - - } finally { - this.justifySelectedDateTimeAfterChangeTimeString() - } - }, - setSecond (second) { - try { - const timeArray = this.displayTimeString.split(':') - timeArray[2] = second - this.displayTimeString = timeArray.join(':') - } catch (err) { - - } finally { - this.justifySelectedDateTimeAfterChangeTimeString() - } - }, - openTimeSelector () { - if (this.computedSelectedDateTime === null) { - this.setValue(moment()) - } - this.showTimeSelector = true - }, - closeTimeSelector () { - this.showTimeSelector = false - }, clearSelectedDateTime () { - this.setValue(null) - this.displayDateTimeString = '' + this.$emit('input', null) this.displayDateString = '' - this.displayTimeString = '' }, setSelectedDateTimeToNow () { - this.setValue(moment()) + this.$emit('input', this.adjustValue(moment()).valueOf()) this.calendarDateTime = moment() }, handleDateClick (dateItem) { let newSelectedDateTime = moment() - if (this.computedSelectedDateTime !== null) { - newSelectedDateTime = moment(this.computedSelectedDateTime) + if (this.valueAsMoment !== null) { + newSelectedDateTime = moment(this.valueAsMoment) } newSelectedDateTime = setDate(newSelectedDateTime, dateItem) - this.setValue(newSelectedDateTime) + this.$emit('input', this.adjustValue(newSelectedDateTime).valueOf()) }, /** * If not selected, display nothing, * else update datetime related string */ - refreshSelectedDateTimeString (time) { - if (this.computedSelectedDateTime === null) { - this.displayDateTimeString = '' + refreshDisplayDateString (time) { + if (this.valueAsMoment === null) { + this.displayDateString = '' return } if (time === undefined) { - time = this.computedSelectedDateTime + time = this.valueAsMoment } - this.displayDateTimeString = time.format(this.format) - this.displayDateString = time.format('YYYY-MM-DD') - this.displayTimeString = time.format('HH:mm:ss') + this.displayDateString = time.format(DATE_FORMAT) }, - /** - * If new time is invalid, do nothing. - * If valid, update. - */ - handleDateTimeInputEnter () { - const newSelectedDateTime = moment(this.displayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - }, - /** - * If new SelectedDateTime is valid, update `selectedDateTime` and `calendarTime` - * Whatever happened, refresh selectedDateTime - */ - handleDateTimeInputBlur () { - const newSelectedDateTime = moment(this.displayDateTimeString, this.format, true) - this.setValue(newSelectedDateTime) - /** - * If newSelectedDateTime is invalid, display string need to be restored - */ - this.refreshSelectedDateTimeString() - }, - handleDateInputAndTimeInputConfirmClick () { - const newDisplayDateTimeString = `${this.displayDateString.trim()} ${this.displayTimeString.trim()}` - const newSelectedDateTime = moment(newDisplayDateTimeString, this.format, true) - if (this.computedSelectedDateTime === null) { - this.setValue(moment()) - } else { - this.setValue(newSelectedDateTime) - } + handleConfirmClick () { + this.$emit('confirm') this.closeCalendar() }, closeCalendar () { @@ -485,6 +339,9 @@ export default { prevMonth () { this.calendarDateTime.subtract(1, 'month') this.$forceUpdate() + }, + handleTimePickerInput (value) { + this.$emit('input', value) } } } diff --git a/packages/common/Modal/src/ModalContent.vue b/packages/common/Modal/src/ModalContent.vue index 41bf9fa11..a4289bfd7 100644 --- a/packages/common/Modal/src/ModalContent.vue +++ b/packages/common/Modal/src/ModalContent.vue @@ -23,6 +23,11 @@ export default {