123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248 |
- <template>
- <transition
- name="el-zoom-in-top"
- @after-leave="$emit('dodestroy')">
- <div
- v-show="visible"
- class="el-time-range-picker el-picker-panel el-popper"
- :class="popperClass">
- <div class="el-time-range-picker__content">
- <div class="el-time-range-picker__cell">
- <div class="el-time-range-picker__header">{{ t('el.datepicker.startTime') }}</div>
- <div
- :class="{ 'has-seconds': showSeconds, 'is-arrow': arrowControl }"
- class="el-time-range-picker__body el-time-panel__content">
- <time-spinner
- ref="minSpinner"
- :show-seconds="showSeconds"
- :am-pm-mode="amPmMode"
- @change="handleMinChange"
- :arrow-control="arrowControl"
- @select-range="setMinSelectionRange"
- :date="minDate">
- </time-spinner>
- </div>
- </div>
- <div class="el-time-range-picker__cell">
- <div class="el-time-range-picker__header">{{ t('el.datepicker.endTime') }}</div>
- <div
- :class="{ 'has-seconds': showSeconds, 'is-arrow': arrowControl }"
- class="el-time-range-picker__body el-time-panel__content">
- <time-spinner
- ref="maxSpinner"
- :show-seconds="showSeconds"
- :am-pm-mode="amPmMode"
- @change="handleMaxChange"
- :arrow-control="arrowControl"
- @select-range="setMaxSelectionRange"
- :date="maxDate">
- </time-spinner>
- </div>
- </div>
- </div>
- <div class="el-time-panel__footer">
- <button
- type="button"
- class="el-time-panel__btn cancel"
- @click="handleCancel()">{{ t('el.datepicker.cancel') }}</button>
- <button
- type="button"
- class="el-time-panel__btn confirm"
- @click="handleConfirm()"
- :disabled="btnDisabled">{{ t('el.datepicker.confirm') }}</button>
- </div>
- </div>
- </transition>
- </template>
- <script type="text/babel">
- import {
- parseDate,
- limitTimeRange,
- modifyDate,
- clearMilliseconds,
- timeWithinRange
- } from 'element-ui/src/utils/date-util';
- import Locale from 'element-ui/src/mixins/locale';
- import TimeSpinner from '../basic/time-spinner';
- const MIN_TIME = parseDate('00:00:00', 'HH:mm:ss');
- const MAX_TIME = parseDate('23:59:59', 'HH:mm:ss');
- const minTimeOfDay = function(date) {
- return modifyDate(MIN_TIME, date.getFullYear(), date.getMonth(), date.getDate());
- };
-
- const maxTimeOfDay = function(date) {
- return modifyDate(MAX_TIME, date.getFullYear(), date.getMonth(), date.getDate());
- };
- // increase time by amount of milliseconds, but within the range of day
- const advanceTime = function(date, amount) {
- return new Date(Math.min(date.getTime() + amount, maxTimeOfDay(date).getTime()));
- };
- export default {
- mixins: [Locale],
- components: { TimeSpinner },
- computed: {
- showSeconds() {
- return (this.format || '').indexOf('ss') !== -1;
- },
- offset() {
- return this.showSeconds ? 11 : 8;
- },
- spinner() {
- return this.selectionRange[0] < this.offset ? this.$refs.minSpinner : this.$refs.maxSpinner;
- },
- btnDisabled() {
- return this.minDate.getTime() > this.maxDate.getTime();
- },
- amPmMode() {
- if ((this.format || '').indexOf('A') !== -1) return 'A';
- if ((this.format || '').indexOf('a') !== -1) return 'a';
- return '';
- }
- },
- data() {
- return {
- popperClass: '',
- minDate: new Date(),
- maxDate: new Date(),
- value: [],
- oldValue: [new Date(), new Date()],
- defaultValue: null,
- format: 'HH:mm:ss',
- visible: false,
- selectionRange: [0, 2],
- arrowControl: false
- };
- },
- watch: {
- value(value) {
- if (Array.isArray(value)) {
- this.minDate = new Date(value[0]);
- this.maxDate = new Date(value[1]);
- } else {
- if (Array.isArray(this.defaultValue)) {
- this.minDate = new Date(this.defaultValue[0]);
- this.maxDate = new Date(this.defaultValue[1]);
- } else if (this.defaultValue) {
- this.minDate = new Date(this.defaultValue);
- this.maxDate = advanceTime(new Date(this.defaultValue), 60 * 60 * 1000);
- } else {
- this.minDate = new Date();
- this.maxDate = advanceTime(new Date(), 60 * 60 * 1000);
- }
- }
- },
- visible(val) {
- if (val) {
- this.oldValue = this.value;
- this.$nextTick(() => this.$refs.minSpinner.emitSelectRange('hours'));
- }
- }
- },
- methods: {
- handleClear() {
- this.$emit('pick', null);
- },
- handleCancel() {
- this.$emit('pick', this.oldValue);
- },
- handleMinChange(date) {
- this.minDate = clearMilliseconds(date);
- this.handleChange();
- },
- handleMaxChange(date) {
- this.maxDate = clearMilliseconds(date);
- this.handleChange();
- },
- handleChange() {
- if (this.isValidValue([this.minDate, this.maxDate])) {
- this.$refs.minSpinner.selectableRange = [[minTimeOfDay(this.minDate), this.maxDate]];
- this.$refs.maxSpinner.selectableRange = [[this.minDate, maxTimeOfDay(this.maxDate)]];
- this.$emit('pick', [this.minDate, this.maxDate], true);
- }
- },
- setMinSelectionRange(start, end) {
- this.$emit('select-range', start, end, 'min');
- this.selectionRange = [start, end];
- },
- setMaxSelectionRange(start, end) {
- this.$emit('select-range', start, end, 'max');
- this.selectionRange = [start + this.offset, end + this.offset];
- },
- handleConfirm(visible = false) {
- const minSelectableRange = this.$refs.minSpinner.selectableRange;
- const maxSelectableRange = this.$refs.maxSpinner.selectableRange;
- this.minDate = limitTimeRange(this.minDate, minSelectableRange, this.format);
- this.maxDate = limitTimeRange(this.maxDate, maxSelectableRange, this.format);
- this.$emit('pick', [this.minDate, this.maxDate], visible);
- },
- adjustSpinners() {
- this.$refs.minSpinner.adjustSpinners();
- this.$refs.maxSpinner.adjustSpinners();
- },
- changeSelectionRange(step) {
- const list = this.showSeconds ? [0, 3, 6, 11, 14, 17] : [0, 3, 8, 11];
- const mapping = ['hours', 'minutes'].concat(this.showSeconds ? ['seconds'] : []);
- const index = list.indexOf(this.selectionRange[0]);
- const next = (index + step + list.length) % list.length;
- const half = list.length / 2;
- if (next < half) {
- this.$refs.minSpinner.emitSelectRange(mapping[next]);
- } else {
- this.$refs.maxSpinner.emitSelectRange(mapping[next - half]);
- }
- },
- isValidValue(date) {
- return Array.isArray(date) &&
- timeWithinRange(this.minDate, this.$refs.minSpinner.selectableRange) &&
- timeWithinRange(this.maxDate, this.$refs.maxSpinner.selectableRange);
- },
- handleKeydown(event) {
- const keyCode = event.keyCode;
- const mapping = { 38: -1, 40: 1, 37: -1, 39: 1 };
- // Left or Right
- if (keyCode === 37 || keyCode === 39) {
- const step = mapping[keyCode];
- this.changeSelectionRange(step);
- event.preventDefault();
- return;
- }
- // Up or Down
- if (keyCode === 38 || keyCode === 40) {
- const step = mapping[keyCode];
- this.spinner.scrollDown(step);
- event.preventDefault();
- return;
- }
- }
- }
- };
- </script>
|