123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- <template>
- <transition name="el-zoom-in-top" @before-enter="handleMenuEnter" @after-leave="$emit('dodestroy')">
- <div
- ref="popper"
- v-show="visible"
- :style="{ width: width + 'px' }"
- :class="popperClass"
- class="el-picker-panel time-select el-popper">
- <el-scrollbar noresize wrap-class="el-picker-panel__content">
- <div class="time-select-item"
- v-for="item in items"
- :class="{ selected: value === item.value, disabled: item.disabled, default: item.value === defaultValue }"
- :disabled="item.disabled"
- :key="item.value"
- @click="handleClick(item)">{{ item.value }}</div>
- </el-scrollbar>
- </div>
- </transition>
- </template>
- <script type="text/babel">
- import ElScrollbar from 'element-ui/packages/scrollbar';
- import scrollIntoView from 'element-ui/src/utils/scroll-into-view';
- const parseTime = function(time) {
- const values = (time || '').split(':');
- if (values.length >= 2) {
- const hours = parseInt(values[0], 10);
- const minutes = parseInt(values[1], 10);
- return {
- hours,
- minutes
- };
- }
- /* istanbul ignore next */
- return null;
- };
- const compareTime = function(time1, time2) {
- const value1 = parseTime(time1);
- const value2 = parseTime(time2);
- const minutes1 = value1.minutes + value1.hours * 60;
- const minutes2 = value2.minutes + value2.hours * 60;
- if (minutes1 === minutes2) {
- return 0;
- }
- return minutes1 > minutes2 ? 1 : -1;
- };
- const formatTime = function(time) {
- return (time.hours < 10 ? '0' + time.hours : time.hours) + ':' + (time.minutes < 10 ? '0' + time.minutes : time.minutes);
- };
- const nextTime = function(time, step) {
- const timeValue = parseTime(time);
- const stepValue = parseTime(step);
- const next = {
- hours: timeValue.hours,
- minutes: timeValue.minutes
- };
- next.minutes += stepValue.minutes;
- next.hours += stepValue.hours;
- next.hours += Math.floor(next.minutes / 60);
- next.minutes = next.minutes % 60;
- return formatTime(next);
- };
- export default {
- components: { ElScrollbar },
- watch: {
- value(val) {
- if (!val) return;
- this.$nextTick(() => this.scrollToOption());
- }
- },
- methods: {
- handleClick(item) {
- if (!item.disabled) {
- this.$emit('pick', item.value);
- }
- },
- handleClear() {
- this.$emit('pick', null);
- },
- scrollToOption(selector = '.selected') {
- const menu = this.$refs.popper.querySelector('.el-picker-panel__content');
- scrollIntoView(menu, menu.querySelector(selector));
- },
- handleMenuEnter() {
- const selected = this.items.map(item => item.value).indexOf(this.value) !== -1;
- const hasDefault = this.items.map(item => item.value).indexOf(this.defaultValue) !== -1;
- const option = (selected && '.selected') || (hasDefault && '.default') || '.time-select-item:not(.disabled)';
- this.$nextTick(() => this.scrollToOption(option));
- },
- scrollDown(step) {
- const items = this.items;
- const length = items.length;
- let total = items.length;
- let index = items.map(item => item.value).indexOf(this.value);
- while (total--) {
- index = (index + step + length) % length;
- if (!items[index].disabled) {
- this.$emit('pick', items[index].value, true);
- return;
- }
- }
- },
- isValidValue(date) {
- return this.items.filter(item => !item.disabled).map(item => item.value).indexOf(date) !== -1;
- },
- handleKeydown(event) {
- const keyCode = event.keyCode;
- if (keyCode === 38 || keyCode === 40) {
- const mapping = { 40: 1, 38: -1 };
- const offset = mapping[keyCode.toString()];
- this.scrollDown(offset);
- event.stopPropagation();
- return;
- }
- }
- },
- data() {
- return {
- popperClass: '',
- start: '09:00',
- end: '18:00',
- step: '00:30',
- value: '',
- defaultValue: '',
- visible: false,
- minTime: '',
- maxTime: '',
- width: 0
- };
- },
- computed: {
- items() {
- const start = this.start;
- const end = this.end;
- const step = this.step;
- const result = [];
- if (start && end && step) {
- let current = start;
- while (compareTime(current, end) <= 0) {
- result.push({
- value: current,
- disabled: compareTime(current, this.minTime || '-1:-1') <= 0 ||
- compareTime(current, this.maxTime || '100:100') >= 0
- });
- current = nextTime(current, step);
- }
- }
- return result;
- }
- }
- };
- </script>
|