element/packages/date-picker/src/picker.vue

922 lines
24 KiB
Vue
Raw Normal View History

2016-07-27 06:15:02 +00:00
<template>
<el-input
2016-07-27 06:15:02 +00:00
class="el-date-editor"
:class="'el-date-editor--' + type"
:readonly="!editable || readonly || type === 'dates'"
2018-01-29 09:54:38 +00:00
:disabled="pickerDisabled"
2017-10-12 09:50:06 +00:00
:size="pickerSize"
:name="name"
v-bind="firstInputId"
v-if="!ranged"
2016-08-09 02:10:33 +00:00
v-clickoutside="handleClose"
:placeholder="placeholder"
@focus="handleFocus"
@keydown.native="handleKeydown"
:value="displayValue"
@input="value => userInput = value"
@change="handleChange"
@mouseenter.native="handleMouseEnter"
@mouseleave.native="showClose = false"
:validateEvent="false"
ref="reference">
<i slot="prefix"
class="el-input__icon"
:class="triggerClass"
@click="handleFocus">
</i>
2017-09-14 11:34:15 +00:00
<i slot="suffix"
class="el-input__icon"
@click="handleClickIcon"
:class="[showClose ? '' + clearIcon : '']"
2016-07-27 06:15:02 +00:00
v-if="haveTrigger">
</i>
</el-input>
<div
class="el-date-editor el-range-editor el-input__inner"
:class="[
'el-date-editor--' + type,
2017-10-18 11:20:48 +00:00
pickerSize ? `el-range-editor--${ pickerSize }` : '',
2018-01-29 09:54:38 +00:00
pickerDisabled ? 'is-disabled' : '',
pickerVisible ? 'is-active' : ''
]"
@click="handleRangeClick"
@mouseenter="handleMouseEnter"
@mouseleave="showClose = false"
@keydown="handleKeydown"
ref="reference"
v-clickoutside="handleClose"
v-else>
<i :class="['el-input__icon', 'el-range__icon', triggerClass]"></i>
<input
:placeholder="startPlaceholder"
:value="displayValue && displayValue[0]"
2018-01-29 09:54:38 +00:00
:disabled="pickerDisabled"
v-bind="firstInputId"
:readonly="!editable || readonly"
:name="name && name[0]"
@input="handleStartInput"
@change="handleStartChange"
@focus="handleFocus"
class="el-range-input">
<span class="el-range-separator">{{ rangeSeparator }}</span>
<input
:placeholder="endPlaceholder"
:value="displayValue && displayValue[1]"
2018-01-29 09:54:38 +00:00
:disabled="pickerDisabled"
v-bind="secondInputId"
:readonly="!editable || readonly"
:name="name && name[1]"
@input="handleEndInput"
@change="handleEndChange"
@focus="handleFocus"
class="el-range-input">
<i
@click="handleClickIcon"
v-if="haveTrigger"
:class="[showClose ? '' + clearIcon : '']"
class="el-input__icon el-range__close-icon">
</i>
</div>
2016-07-27 06:15:02 +00:00
</template>
<script>
import Vue from 'vue';
2016-10-13 03:12:24 +00:00
import Clickoutside from 'element-ui/src/utils/clickoutside';
import { formatDate, parseDate, isDateObject, getWeekNumber } from './util';
2016-10-13 03:12:24 +00:00
import Popper from 'element-ui/src/utils/vue-popper';
2016-10-27 09:31:22 +00:00
import Emitter from 'element-ui/src/mixins/emitter';
import ElInput from 'element-ui/packages/input';
import merge from 'element-ui/src/utils/merge';
2016-07-27 06:15:02 +00:00
2016-10-27 09:31:22 +00:00
const NewPopper = {
props: {
appendToBody: Popper.props.appendToBody,
offset: Popper.props.offset,
2018-01-18 10:25:42 +00:00
boundariesPadding: Popper.props.boundariesPadding,
arrowOffset: Popper.props.arrowOffset
},
methods: Popper.methods,
data() {
return merge({ visibleArrow: true }, Popper.data);
},
beforeDestroy: Popper.beforeDestroy
};
2016-07-27 06:15:02 +00:00
const DEFAULT_FORMATS = {
date: 'yyyy-MM-dd',
month: 'yyyy-MM',
datetime: 'yyyy-MM-dd HH:mm:ss',
time: 'HH:mm:ss',
week: 'yyyywWW',
2016-07-27 06:15:02 +00:00
timerange: 'HH:mm:ss',
daterange: 'yyyy-MM-dd',
datetimerange: 'yyyy-MM-dd HH:mm:ss',
year: 'yyyy'
2016-07-27 06:15:02 +00:00
};
const HAVE_TRIGGER_TYPES = [
'date',
'datetime',
'time',
'time-select',
'week',
'month',
'year',
'daterange',
'timerange',
'datetimerange',
'dates'
2016-07-27 06:15:02 +00:00
];
const DATE_FORMATTER = function(value, format) {
2018-01-17 10:46:18 +00:00
if (format === 'timestamp') return value.getTime();
2016-07-27 06:15:02 +00:00
return formatDate(value, format);
};
const DATE_PARSER = function(text, format) {
2018-01-17 10:46:18 +00:00
if (format === 'timestamp') return new Date(Number(text));
2016-07-27 06:15:02 +00:00
return parseDate(text, format);
};
const RANGE_FORMATTER = function(value, format) {
2016-07-27 06:15:02 +00:00
if (Array.isArray(value) && value.length === 2) {
const start = value[0];
const end = value[1];
if (start && end) {
2018-01-17 10:46:18 +00:00
return [DATE_FORMATTER(start, format), DATE_FORMATTER(end, format)];
2016-07-27 06:15:02 +00:00
}
}
return '';
};
const RANGE_PARSER = function(array, format, separator) {
if (!Array.isArray(array)) {
array = array.split(separator);
}
2016-07-27 06:15:02 +00:00
if (array.length === 2) {
const range1 = array[0];
const range2 = array[1];
2018-01-17 10:46:18 +00:00
return [DATE_PARSER(range1, format), DATE_PARSER(range2, format)];
2016-07-27 06:15:02 +00:00
}
return [];
};
const TYPE_VALUE_RESOLVER_MAP = {
default: {
formatter(value) {
if (!value) return '';
return '' + value;
},
parser(text) {
if (text === undefined || text === '') return null;
return text;
}
},
week: {
formatter(value, format) {
let week = getWeekNumber(value);
let month = value.getMonth();
const trueDate = new Date(value);
if (week === 1 && month === 11) {
trueDate.setHours(0, 0, 0, 0);
trueDate.setDate(trueDate.getDate() + 3 - (trueDate.getDay() + 6) % 7);
}
let date = formatDate(trueDate, format);
date = /WW/.test(date)
? date.replace(/WW/, week < 10 ? '0' + week : week)
: date.replace(/W/, week);
return date;
2016-07-27 06:15:02 +00:00
},
parser(text) {
const array = (text || '').split('w');
if (array.length === 2) {
const year = Number(array[0]);
const month = Number(array[1]);
if (!isNaN(year) && !isNaN(month) && month < 54) {
return text;
}
}
return null;
}
},
date: {
formatter: DATE_FORMATTER,
parser: DATE_PARSER
},
datetime: {
formatter: DATE_FORMATTER,
parser: DATE_PARSER
},
daterange: {
formatter: RANGE_FORMATTER,
parser: RANGE_PARSER
},
datetimerange: {
formatter: RANGE_FORMATTER,
parser: RANGE_PARSER
},
timerange: {
formatter: RANGE_FORMATTER,
parser: RANGE_PARSER
},
time: {
formatter: DATE_FORMATTER,
parser: DATE_PARSER
},
month: {
formatter: DATE_FORMATTER,
parser: DATE_PARSER
},
year: {
formatter: DATE_FORMATTER,
parser: DATE_PARSER
2016-07-27 06:15:02 +00:00
},
number: {
formatter(value) {
if (!value) return '';
return '' + value;
},
parser(text) {
let result = Number(text);
if (!isNaN(text)) {
return result;
} else {
return null;
}
}
},
dates: {
formatter(value, format) {
return value.map(date => DATE_FORMATTER(date, format));
},
parser(value, format) {
return (typeof value === 'string' ? value.split(', ') : value)
.map(date => date instanceof Date ? date : DATE_PARSER(date, format));
}
2016-07-27 06:15:02 +00:00
}
};
2016-09-21 04:46:53 +00:00
const PLACEMENT_MAP = {
left: 'bottom-start',
2017-07-20 03:27:01 +00:00
center: 'bottom',
2016-09-21 04:46:53 +00:00
right: 'bottom-end'
};
2016-07-27 06:15:02 +00:00
const parseAsFormatAndType = (value, customFormat, type, rangeSeparator = '-') => {
if (!value) return null;
const parser = (
TYPE_VALUE_RESOLVER_MAP[type] ||
TYPE_VALUE_RESOLVER_MAP['default']
).parser;
const format = customFormat || DEFAULT_FORMATS[type];
return parser(value, format, rangeSeparator);
};
const formatAsFormatAndType = (value, customFormat, type) => {
if (!value) return null;
const formatter = (
TYPE_VALUE_RESOLVER_MAP[type] ||
TYPE_VALUE_RESOLVER_MAP['default']
).formatter;
const format = customFormat || DEFAULT_FORMATS[type];
return formatter(value, format);
};
/*
* Considers:
* 1. Date object
* 2. date string
* 3. array of 1 or 2
*/
const valueEquals = function(a, b) {
// considers Date object and string
const dateEquals = function(a, b) {
const aIsDate = a instanceof Date;
const bIsDate = b instanceof Date;
if (aIsDate && bIsDate) {
return a.getTime() === b.getTime();
}
if (!aIsDate && !bIsDate) {
return a === b;
}
return false;
};
const aIsArray = a instanceof Array;
const bIsArray = b instanceof Array;
if (aIsArray && bIsArray) {
if (a.length !== b.length) {
return false;
}
return a.every((item, index) => dateEquals(item, b[index]));
}
if (!aIsArray && !bIsArray) {
return dateEquals(a, b);
}
return false;
};
const isString = function(val) {
return typeof val === 'string' || val instanceof String;
};
2017-10-26 03:15:41 +00:00
const validator = function(val) {
// either: String, Array of String, null / undefined
return (
val === null ||
val === undefined ||
isString(val) ||
(Array.isArray(val) && val.length === 2 && val.every(isString))
);
};
2016-07-27 06:15:02 +00:00
export default {
mixins: [Emitter, NewPopper],
2016-08-29 11:19:14 +00:00
inject: {
2018-01-29 09:54:38 +00:00
elForm: {
default: ''
},
elFormItem: {
default: ''
}
},
2017-10-12 09:50:06 +00:00
2016-07-27 06:15:02 +00:00
props: {
size: String,
2016-07-27 06:15:02 +00:00
format: String,
valueFormat: String,
2016-07-27 06:15:02 +00:00
readonly: Boolean,
placeholder: String,
startPlaceholder: String,
endPlaceholder: String,
prefixIcon: String,
clearIcon: {
type: String,
default: 'el-icon-circle-close'
},
name: {
default: '',
2017-10-26 03:15:41 +00:00
validator
},
disabled: Boolean,
2016-12-26 15:02:40 +00:00
clearable: {
type: Boolean,
default: true
},
2017-10-26 03:15:41 +00:00
id: {
default: '',
validator
},
popperClass: String,
editable: {
type: Boolean,
default: true
},
2016-09-21 04:46:53 +00:00
align: {
type: String,
default: 'left'
},
2016-07-27 06:15:02 +00:00
value: {},
defaultValue: {},
defaultTime: {},
rangeSeparator: {
default: '-'
},
2017-10-19 06:09:05 +00:00
pickerOptions: {},
unlinkPanels: Boolean
2016-07-27 06:15:02 +00:00
},
components: { ElInput },
directives: { Clickoutside },
2016-07-27 06:15:02 +00:00
data() {
return {
pickerVisible: false,
showClose: false,
userInput: null,
valueOnOpen: null, // value when picker opens, used to determine whether to emit change
unwatchPickerOptions: null
2016-07-27 06:15:02 +00:00
};
},
watch: {
pickerVisible(val) {
2018-01-29 09:54:38 +00:00
if (this.readonly || this.pickerDisabled) return;
if (val) {
this.showPicker();
this.valueOnOpen = Array.isArray(this.value) ? [...this.value] : this.value;
} else {
this.hidePicker();
this.emitChange(this.value);
this.userInput = null;
this.dispatch('ElFormItem', 'el.form.blur');
2017-12-12 07:46:19 +00:00
this.$emit('blur', this);
this.blur();
}
},
parsedValue: {
immediate: true,
handler(val) {
if (this.picker) {
this.picker.value = val;
this.picker.selectedDate = Array.isArray(val) ? val : [];
}
}
},
defaultValue(val) {
// NOTE: should eventually move to jsx style picker + panel ?
if (this.picker) {
this.picker.defaultValue = val;
}
2016-07-27 06:15:02 +00:00
}
},
computed: {
ranged() {
return this.type.indexOf('range') > -1;
},
reference() {
const reference = this.$refs.reference;
return reference.$el || reference;
},
refInput() {
if (this.reference) {
return [].slice.call(this.reference.querySelectorAll('input'));
}
return [];
},
valueIsEmpty() {
const val = this.value;
if (Array.isArray(val)) {
for (let i = 0, len = val.length; i < len; i++) {
if (val[i]) {
return false;
}
}
} else {
if (val) {
return false;
}
}
return true;
},
2016-07-27 06:15:02 +00:00
triggerClass() {
return this.prefixIcon || (this.type.indexOf('time') !== -1 ? 'el-icon-time' : 'el-icon-date');
2016-07-27 06:15:02 +00:00
},
selectionMode() {
if (this.type === 'week') {
return 'week';
} else if (this.type === 'month') {
return 'month';
} else if (this.type === 'year') {
return 'year';
} else if (this.type === 'dates') {
return 'dates';
2016-07-27 06:15:02 +00:00
}
return 'day';
},
haveTrigger() {
if (typeof this.showTrigger !== 'undefined') {
return this.showTrigger;
}
return HAVE_TRIGGER_TYPES.indexOf(this.type) !== -1;
},
displayValue() {
const formattedValue = formatAsFormatAndType(this.parsedValue, this.format, this.type, this.rangeSeparator);
if (Array.isArray(this.userInput)) {
return [
this.userInput[0] || (formattedValue && formattedValue[0]) || '',
this.userInput[1] || (formattedValue && formattedValue[1]) || ''
];
} else if (this.userInput !== null) {
return this.userInput;
} else if (formattedValue) {
return this.type === 'dates'
? formattedValue.join(', ')
: formattedValue;
} else {
return '';
}
},
2016-07-27 06:15:02 +00:00
parsedValue() {
if (!this.value) return this.value; // component value is not set
if (this.type === 'time-select') return this.value; // time-select does not require parsing, this might change in next major version
const valueIsDateObject = isDateObject(this.value) || (Array.isArray(this.value) && this.value.every(isDateObject));
if (valueIsDateObject) {
return this.value;
2016-07-27 06:15:02 +00:00
}
if (this.valueFormat) {
return parseAsFormatAndType(this.value, this.valueFormat, this.type, this.rangeSeparator) || this.value;
}
// NOTE: deal with common but incorrect usage, should remove in next major version
// user might provide string / timestamp without value-format, coerce them into date (or array of date)
return Array.isArray(this.value) ? this.value.map(val => new Date(val)) : new Date(this.value);
2017-10-12 09:50:06 +00:00
},
_elFormItemSize() {
return (this.elFormItem || {}).elFormItemSize;
},
pickerSize() {
return this.size || this._elFormItemSize || (this.$ELEMENT || {}).size;
2018-01-29 09:54:38 +00:00
},
pickerDisabled() {
return this.disabled || (this.elForm || {}).disabled;
},
firstInputId() {
const obj = {};
let id;
if (this.ranged) {
id = this.id && this.id[0];
} else {
id = this.id;
}
if (id) obj.id = id;
return obj;
},
secondInputId() {
const obj = {};
let id;
if (this.ranged) {
id = this.id && this.id[1];
}
if (id) obj.id = id;
return obj;
2016-07-27 06:15:02 +00:00
}
},
created() {
// vue-popper
this.popperOptions = {
boundariesPadding: 0,
gpuAcceleration: false
};
this.placement = PLACEMENT_MAP[this.align] || PLACEMENT_MAP.left;
this.$on('fieldReset', this.handleFieldReset);
},
2016-07-27 06:15:02 +00:00
methods: {
focus() {
if (!this.ranged) {
this.$refs.reference.focus();
} else {
this.handleFocus();
}
},
blur() {
this.refInput.forEach(input => input.blur());
},
// {parse, formatTo} Value deals maps component value with internal Date
parseValue(value) {
const isParsed = isDateObject(value) || (Array.isArray(value) && value.every(isDateObject));
if (this.valueFormat && !isParsed) {
return parseAsFormatAndType(value, this.valueFormat, this.type, this.rangeSeparator) || value;
} else {
return value;
}
},
formatToValue(date) {
const isFormattable = isDateObject(date) || (Array.isArray(date) && date.every(isDateObject));
if (this.valueFormat && isFormattable) {
return formatAsFormatAndType(date, this.valueFormat, this.type, this.rangeSeparator);
} else {
return date;
}
},
// {parse, formatTo} String deals with user input
parseString(value) {
const type = Array.isArray(value) ? this.type : this.type.replace('range', '');
return parseAsFormatAndType(value, this.format, type);
},
formatToString(value) {
const type = Array.isArray(value) ? this.type : this.type.replace('range', '');
return formatAsFormatAndType(value, this.format, type);
},
handleMouseEnter() {
2018-01-29 09:54:38 +00:00
if (this.readonly || this.pickerDisabled) return;
2016-12-26 15:02:40 +00:00
if (!this.valueIsEmpty && this.clearable) {
this.showClose = true;
}
},
handleChange() {
if (this.userInput) {
const value = this.parseString(this.displayValue);
if (value) {
this.picker.value = value;
if (this.isValidValue(value)) {
this.emitInput(value);
this.userInput = null;
}
}
}
if (this.userInput === '') {
this.emitInput(null);
this.emitChange(null);
this.userInput = null;
}
},
handleStartInput(event) {
if (this.userInput) {
this.userInput = [event.target.value, this.userInput[1]];
} else {
this.userInput = [event.target.value, null];
}
},
handleEndInput(event) {
if (this.userInput) {
this.userInput = [this.userInput[0], event.target.value];
} else {
this.userInput = [null, event.target.value];
}
},
handleStartChange(event) {
const value = this.parseString(this.userInput && this.userInput[0]);
if (value) {
this.userInput = [this.formatToString(value), this.displayValue[1]];
const newValue = [value, this.picker.value && this.picker.value[1]];
this.picker.value = newValue;
if (this.isValidValue(newValue)) {
this.emitInput(newValue);
this.userInput = null;
}
}
},
handleEndChange(event) {
const value = this.parseString(this.userInput && this.userInput[1]);
if (value) {
this.userInput = [this.displayValue[0], this.formatToString(value)];
const newValue = [this.picker.value && this.picker.value[0], value];
this.picker.value = newValue;
if (this.isValidValue(newValue)) {
this.emitInput(newValue);
this.userInput = null;
}
}
},
handleClickIcon(event) {
2018-01-29 09:54:38 +00:00
if (this.readonly || this.pickerDisabled) return;
2016-12-26 15:02:40 +00:00
if (this.showClose) {
this.valueOnOpen = this.value;
event.stopPropagation();
this.emitInput(null);
this.emitChange(null);
this.showClose = false;
if (this.picker && typeof this.picker.handleClear === 'function') {
this.picker.handleClear();
}
} else {
this.pickerVisible = !this.pickerVisible;
}
},
2016-08-09 02:10:33 +00:00
handleClose() {
if (!this.pickerVisible) return;
2016-08-09 02:10:33 +00:00
this.pickerVisible = false;
const {
type,
valueOnOpen,
valueFormat,
rangeSeparator
} = this;
if (type === 'dates' && this.picker) {
this.picker.selectedDate = parseAsFormatAndType(valueOnOpen, valueFormat, type, rangeSeparator) || valueOnOpen;
this.emitInput(this.picker.selectedDate);
}
2016-08-09 02:10:33 +00:00
},
handleFieldReset(initialValue) {
this.userInput = initialValue;
},
2016-07-27 06:15:02 +00:00
handleFocus() {
const type = this.type;
if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
this.pickerVisible = true;
2016-07-27 06:15:02 +00:00
}
this.$emit('focus', this);
},
handleKeydown(event) {
const keyCode = event.keyCode;
// ESC
if (keyCode === 27) {
2016-10-13 08:11:06 +00:00
this.pickerVisible = false;
2017-05-29 13:01:00 +00:00
event.stopPropagation();
return;
}
// Tab
if (keyCode === 9) {
if (!this.ranged) {
this.handleChange();
this.pickerVisible = this.picker.visible = false;
this.blur();
event.stopPropagation();
} else {
// user may change focus between two input
setTimeout(() => {
if (this.refInput.indexOf(document.activeElement) === -1) {
this.pickerVisible = false;
this.blur();
event.stopPropagation();
}
}, 0);
}
return;
}
// Enter
if (keyCode === 13) {
if (this.userInput === '' || this.isValidValue(this.parseString(this.displayValue))) {
this.handleChange();
this.pickerVisible = this.picker.visible = false;
this.blur();
}
event.stopPropagation();
return;
}
// if user is typing, do not let picker handle key input
if (this.userInput) {
event.stopPropagation();
return;
}
// delegate other keys to panel
if (this.picker && this.picker.handleKeydown) {
this.picker.handleKeydown(event);
2016-07-27 06:15:02 +00:00
}
},
handleRangeClick() {
const type = this.type;
if (HAVE_TRIGGER_TYPES.indexOf(type) !== -1 && !this.pickerVisible) {
this.pickerVisible = true;
}
this.$emit('focus', this);
},
2016-07-27 06:15:02 +00:00
hidePicker() {
if (this.picker) {
this.picker.resetView && this.picker.resetView();
this.pickerVisible = this.picker.visible = false;
this.destroyPopper();
}
},
showPicker() {
2016-12-26 02:45:20 +00:00
if (this.$isServer) return;
2016-07-27 06:15:02 +00:00
if (!this.picker) {
this.mountPicker();
2016-07-27 06:15:02 +00:00
}
this.pickerVisible = this.picker.visible = true;
2016-07-27 06:15:02 +00:00
this.updatePopper();
2016-07-27 06:15:02 +00:00
this.picker.value = this.parsedValue;
this.picker.resetView && this.picker.resetView();
2016-07-27 06:15:02 +00:00
this.$nextTick(() => {
this.picker.adjustSpinners && this.picker.adjustSpinners();
2016-07-27 06:15:02 +00:00
});
},
mountPicker() {
this.picker = new Vue(this.panel).$mount();
this.picker.defaultValue = this.defaultValue;
this.picker.defaultTime = this.defaultTime;
this.picker.popperClass = this.popperClass;
this.popperElm = this.picker.$el;
this.picker.width = this.reference.getBoundingClientRect().width;
this.picker.showTime = this.type === 'datetime' || this.type === 'datetimerange';
this.picker.selectionMode = this.selectionMode;
2017-10-19 06:09:05 +00:00
this.picker.unlinkPanels = this.unlinkPanels;
2017-10-11 10:00:58 +00:00
this.picker.arrowControl = this.arrowControl || this.timeArrowControl || false;
this.picker.selectedDate = Array.isArray(this.value) && this.value || [];
this.$watch('format', (format) => {
this.picker.format = format;
});
const updateOptions = () => {
const options = this.pickerOptions;
if (options && options.selectableRange) {
let ranges = options.selectableRange;
const parser = TYPE_VALUE_RESOLVER_MAP.datetimerange.parser;
const format = DEFAULT_FORMATS.timerange;
ranges = Array.isArray(ranges) ? ranges : [ranges];
this.picker.selectableRange = ranges.map(range => parser(range, format, this.rangeSeparator));
}
for (const option in options) {
if (options.hasOwnProperty(option) &&
// 忽略 time-picker 的该配置项
option !== 'selectableRange') {
this.picker[option] = options[option];
}
}
// main format must prevail over undocumented pickerOptions.format
if (this.format) {
this.picker.format = this.format;
}
};
updateOptions();
this.unwatchPickerOptions = this.$watch('pickerOptions', () => updateOptions(), { deep: true });
this.$el.appendChild(this.picker.$el);
this.picker.resetView && this.picker.resetView();
this.picker.$on('dodestroy', this.doDestroy);
this.picker.$on('pick', (date = '', visible = false) => {
this.userInput = null;
this.pickerVisible = this.picker.visible = visible;
this.emitInput(date);
this.picker.resetView && this.picker.resetView();
});
this.picker.$on('select-range', (start, end, pos) => {
if (this.refInput.length === 0) return;
if (!pos || pos === 'min') {
this.refInput[0].setSelectionRange(start, end);
this.refInput[0].focus();
} else if (pos === 'max') {
this.refInput[1].setSelectionRange(start, end);
this.refInput[1].focus();
}
});
},
unmountPicker() {
if (this.picker) {
this.picker.$destroy();
this.picker.$off();
if (typeof this.unwatchPickerOptions === 'function') {
this.unwatchPickerOptions();
}
this.picker.$el.parentNode.removeChild(this.picker.$el);
}
},
emitChange(val) {
// determine user real change only
if (!valueEquals(val, this.valueOnOpen)) {
this.$emit('change', val);
this.dispatch('ElFormItem', 'el.form.change', val);
this.valueOnOpen = val;
}
},
emitInput(val) {
const formatted = this.formatToValue(val);
if (!valueEquals(this.value, formatted)) {
this.$emit('input', formatted);
}
},
isValidValue(value) {
if (!this.picker) {
this.mountPicker();
}
if (this.picker.isValidValue) {
return value && this.picker.isValidValue(value);
} else {
return true;
}
2016-07-27 06:15:02 +00:00
}
}
};
</script>