<template>
|
<transition name="el-zoom-in-top" @after-leave="$emit('dodestroy')">
|
<div
|
v-show="visible"
|
class="el-picker-panel el-date-range-picker el-popper"
|
:class="[{
|
'has-sidebar': $slots.sidebar || shortcuts
|
}, popperClass]">
|
<div class="el-picker-panel__body-wrapper">
|
<slot name="sidebar" class="el-picker-panel__sidebar"></slot>
|
<div class="el-picker-panel__sidebar" v-if="shortcuts">
|
<button
|
type="button"
|
class="el-picker-panel__shortcut"
|
v-for="(shortcut, key) in shortcuts"
|
:key="key"
|
@click="handleShortcutClick(shortcut)">{{shortcut.text}}</button>
|
</div>
|
<div class="el-picker-panel__body">
|
<div class="el-picker-panel__content el-date-range-picker__content is-left">
|
<div class="el-date-range-picker__header">
|
<button
|
type="button"
|
@click="leftPrevYear"
|
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
<button
|
type="button"
|
v-if="unlinkPanels"
|
@click="leftNextYear"
|
:disabled="!enableYearArrow"
|
:class="{ 'is-disabled': !enableYearArrow }"
|
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
<div>{{ leftLabel }}</div>
|
</div>
|
<month-table
|
selection-mode="range"
|
:date="leftDate"
|
:default-value="defaultValue"
|
:min-date="minDate"
|
:max-date="maxDate"
|
:range-state="rangeState"
|
:disabled-date="disabledDate"
|
@changerange="handleChangeRange"
|
@pick="handleRangePick">
|
</month-table>
|
</div>
|
<div class="el-picker-panel__content el-date-range-picker__content is-right">
|
<div class="el-date-range-picker__header">
|
<button
|
type="button"
|
v-if="unlinkPanels"
|
@click="rightPrevYear"
|
:disabled="!enableYearArrow"
|
:class="{ 'is-disabled': !enableYearArrow }"
|
class="el-picker-panel__icon-btn el-icon-d-arrow-left"></button>
|
<button
|
type="button"
|
@click="rightNextYear"
|
class="el-picker-panel__icon-btn el-icon-d-arrow-right"></button>
|
<div>{{ rightLabel }}</div>
|
</div>
|
<month-table
|
selection-mode="range"
|
:date="rightDate"
|
:default-value="defaultValue"
|
:min-date="minDate"
|
:max-date="maxDate"
|
:range-state="rangeState"
|
:disabled-date="disabledDate"
|
@changerange="handleChangeRange"
|
@pick="handleRangePick">
|
</month-table>
|
</div>
|
</div>
|
</div>
|
</div>
|
</transition>
|
</template>
|
|
<script type="text/babel">
|
import {
|
isDate,
|
modifyWithTimeString,
|
prevYear,
|
nextYear,
|
nextMonth
|
} from 'element-ui/src/utils/date-util';
|
import Clickoutside from 'element-ui/src/utils/clickoutside';
|
import Locale from 'element-ui/src/mixins/locale';
|
import MonthTable from '../basic/month-table';
|
import ElInput from 'element-ui/packages/input';
|
import ElButton from 'element-ui/packages/button';
|
|
const calcDefaultValue = (defaultValue) => {
|
if (Array.isArray(defaultValue)) {
|
return [new Date(defaultValue[0]), new Date(defaultValue[1])];
|
} else if (defaultValue) {
|
return [new Date(defaultValue), nextMonth(new Date(defaultValue))];
|
} else {
|
return [new Date(), nextMonth(new Date())];
|
}
|
};
|
export default {
|
mixins: [Locale],
|
|
directives: { Clickoutside },
|
|
computed: {
|
btnDisabled() {
|
return !(this.minDate && this.maxDate && !this.selecting && this.isValidValue([this.minDate, this.maxDate]));
|
},
|
|
leftLabel() {
|
return this.leftDate.getFullYear() + ' ' + this.t('el.datepicker.year');
|
},
|
|
rightLabel() {
|
return this.rightDate.getFullYear() + ' ' + this.t('el.datepicker.year');
|
},
|
|
leftYear() {
|
return this.leftDate.getFullYear();
|
},
|
|
rightYear() {
|
return this.rightDate.getFullYear() === this.leftDate.getFullYear() ? this.leftDate.getFullYear() + 1 : this.rightDate.getFullYear();
|
},
|
|
enableYearArrow() {
|
return this.unlinkPanels && this.rightYear > this.leftYear + 1;
|
}
|
},
|
|
data() {
|
return {
|
popperClass: '',
|
value: [],
|
defaultValue: null,
|
defaultTime: null,
|
minDate: '',
|
maxDate: '',
|
leftDate: new Date(),
|
rightDate: nextYear(new Date()),
|
rangeState: {
|
endDate: null,
|
selecting: false,
|
row: null,
|
column: null
|
},
|
shortcuts: '',
|
visible: '',
|
disabledDate: '',
|
format: '',
|
arrowControl: false,
|
unlinkPanels: false
|
};
|
},
|
|
watch: {
|
value(newVal) {
|
if (!newVal) {
|
this.minDate = null;
|
this.maxDate = null;
|
} else if (Array.isArray(newVal)) {
|
this.minDate = isDate(newVal[0]) ? new Date(newVal[0]) : null;
|
this.maxDate = isDate(newVal[1]) ? new Date(newVal[1]) : null;
|
if (this.minDate) {
|
this.leftDate = this.minDate;
|
if (this.unlinkPanels && this.maxDate) {
|
const minDateYear = this.minDate.getFullYear();
|
const maxDateYear = this.maxDate.getFullYear();
|
this.rightDate = minDateYear === maxDateYear
|
? nextYear(this.maxDate)
|
: this.maxDate;
|
} else {
|
this.rightDate = nextYear(this.leftDate);
|
}
|
} else {
|
this.leftDate = calcDefaultValue(this.defaultValue)[0];
|
this.rightDate = nextYear(this.leftDate);
|
}
|
}
|
},
|
|
defaultValue(val) {
|
if (!Array.isArray(this.value)) {
|
const [left, right] = calcDefaultValue(val);
|
this.leftDate = left;
|
this.rightDate = val && val[1] && left.getFullYear() !== right.getFullYear() && this.unlinkPanels
|
? right
|
: nextYear(this.leftDate);
|
}
|
}
|
},
|
|
methods: {
|
handleClear() {
|
this.minDate = null;
|
this.maxDate = null;
|
this.leftDate = calcDefaultValue(this.defaultValue)[0];
|
this.rightDate = nextYear(this.leftDate);
|
this.$emit('pick', null);
|
},
|
|
handleChangeRange(val) {
|
this.minDate = val.minDate;
|
this.maxDate = val.maxDate;
|
this.rangeState = val.rangeState;
|
},
|
|
handleRangePick(val, close = true) {
|
const defaultTime = this.defaultTime || [];
|
const minDate = modifyWithTimeString(val.minDate, defaultTime[0]);
|
const maxDate = modifyWithTimeString(val.maxDate, defaultTime[1]);
|
if (this.maxDate === maxDate && this.minDate === minDate) {
|
return;
|
}
|
this.onPick && this.onPick(val);
|
this.maxDate = maxDate;
|
this.minDate = minDate;
|
|
// workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
|
setTimeout(() => {
|
this.maxDate = maxDate;
|
this.minDate = minDate;
|
}, 10);
|
if (!close) return;
|
this.handleConfirm();
|
},
|
|
handleShortcutClick(shortcut) {
|
if (shortcut.onClick) {
|
shortcut.onClick(this);
|
}
|
},
|
|
// leftPrev*, rightNext* need to take care of `unlinkPanels`
|
leftPrevYear() {
|
this.leftDate = prevYear(this.leftDate);
|
if (!this.unlinkPanels) {
|
this.rightDate = prevYear(this.rightDate);
|
}
|
},
|
|
rightNextYear() {
|
if (!this.unlinkPanels) {
|
this.leftDate = nextYear(this.leftDate);
|
}
|
this.rightDate = nextYear(this.rightDate);
|
},
|
|
// leftNext*, rightPrev* are called when `unlinkPanels` is true
|
leftNextYear() {
|
this.leftDate = nextYear(this.leftDate);
|
},
|
|
rightPrevYear() {
|
this.rightDate = prevYear(this.rightDate);
|
},
|
|
handleConfirm(visible = false) {
|
if (this.isValidValue([this.minDate, this.maxDate])) {
|
this.$emit('pick', [this.minDate, this.maxDate], visible);
|
}
|
},
|
|
isValidValue(value) {
|
return Array.isArray(value) &&
|
value && value[0] && value[1] &&
|
isDate(value[0]) && isDate(value[1]) &&
|
value[0].getTime() <= value[1].getTime() && (
|
typeof this.disabledDate === 'function'
|
? !this.disabledDate(value[0]) && !this.disabledDate(value[1])
|
: true
|
);
|
},
|
|
resetView() {
|
// NOTE: this is a hack to reset {min, max}Date on picker open.
|
// TODO: correct way of doing so is to refactor {min, max}Date to be dependent on value and internal selection state
|
// an alternative would be resetView whenever picker becomes visible, should also investigate date-panel's resetView
|
this.minDate = this.value && isDate(this.value[0]) ? new Date(this.value[0]) : null;
|
this.maxDate = this.value && isDate(this.value[0]) ? new Date(this.value[1]) : null;
|
}
|
},
|
|
components: { MonthTable, ElInput, ElButton }
|
};
|
</script>
|