update DatePicker

update DatePicker
This commit is contained in:
梁灏 2016-12-19 14:44:07 +08:00
parent e0cd7f909a
commit 3cf7cfd1de
6 changed files with 319 additions and 34 deletions

View file

@ -36,9 +36,7 @@
default () { default () {
return { return {
endDate: null, endDate: null,
selecting: false, selecting: false
row: null,
column: null
}; };
} }
}, },
@ -64,6 +62,8 @@
day = (day === 0 ? 7 : day); day = (day === 0 ? 7 : day);
const today = clearHours(new Date()); // timestamp of today const today = clearHours(new Date()); // timestamp of today
const selectDay = clearHours(new Date(this.value)); // timestamp of selected day const selectDay = clearHours(new Date(this.value)); // timestamp of selected day
const minDay = clearHours(new Date(this.minDate));
const maxDay = clearHours(new Date(this.maxDate));
const dateCountOfMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth()); const dateCountOfMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth());
const dateCountOfLastMonth = getDayCountOfMonth(date.getFullYear(), (date.getMonth() === 0 ? 11 : date.getMonth() - 1)); const dateCountOfLastMonth = getDayCountOfMonth(date.getFullYear(), (date.getMonth() === 0 ? 11 : date.getMonth() - 1));
@ -75,7 +75,10 @@
text: '', text: '',
type: '', type: '',
selected: false, selected: false,
disabled: false disabled: false,
range: false,
start: false,
end: false
}; };
if (day !== 7) { if (day !== 7) {
for (let i = 0; i < day; i++) { for (let i = 0; i < day; i++) {
@ -102,6 +105,10 @@
cell.text = i; cell.text = i;
cell.selected = time === selectDay; cell.selected = time === selectDay;
cell.disabled = typeof disabledDate === 'function' && disabledDate(new Date(time)); cell.disabled = typeof disabledDate === 'function' && disabledDate(new Date(time));
cell.range = time >= minDay && time <= maxDay;
cell.start = this.minDate && time === minDay;
cell.end = this.maxDate && time === maxDay;
cells.push(cell); cells.push(cell);
} }
@ -156,6 +163,30 @@
if (this.selectionMode === 'range') { if (this.selectionMode === 'range') {
// todo // todo
if (this.minDate && this.maxDate) {
const minDate = new Date(newDate.getTime());
const maxDate = null;
this.$emit('on-pick', {minDate, maxDate}, false);
this.rangeState.selecting = true;
this.markRange(this.minDate);
} else if (this.minDate && !this.maxDate) {
if (newDate >= this.minDate) {
const maxDate = new Date(newDate.getTime());
this.rangeState.selecting = false;
this.$emit('on-pick', {minDate: this.minDate, maxDate});
} else {
const minDate = new Date(newDate.getTime());
this.$emit('on-pick', {minDate, maxDate: this.maxDate}, false);
}
} else if (!this.minDate) {
const minDate = new Date(newDate.getTime());
this.$emit('on-pick', {minDate, maxDate: this.maxDate}, false);
this.rangeState.selecting = true;
this.markRange(this.minDate);
}
} else { } else {
this.$emit('on-pick', newDate); this.$emit('on-pick', newDate);
} }
@ -163,16 +194,40 @@
}, },
handleMouseMove () { handleMouseMove () {
},
markRange (maxDate) {
const startDate = this.startDate;
if (!maxDate) {
maxDate = this.maxDate;
}
const rows = this.rows;
const minDate = this.minDate;
for (var i = 0, k = rows.length; i < k; i++) {
const row = rows[i];
for (var j = 0, l = row.length; j < l; j++) {
if (this.showWeekNumber && j === 0) continue;
const cell = row[j];
const index = i * 7 + j + (this.showWeekNumber ? -1 : 0);
const time = startDate.getTime() + DAY_DURATION * index;
cell.inRange = minDate && time >= clearHours(minDate) && time <= clearHours(maxDate);
cell.start = minDate && time === clearHours(minDate.getTime());
cell.end = maxDate && time === clearHours(maxDate.getTime());
}
}
}, },
getCellCls (cell) { getCellCls (cell) {
return [ return [
`${prefixCls}-cell`, `${prefixCls}-cell`,
{ {
[`${prefixCls}-cell-selected`]: cell.selected, [`${prefixCls}-cell-selected`]: cell.selected || cell.start || cell.end,
[`${prefixCls}-cell-disabled`]: cell.disabled, [`${prefixCls}-cell-disabled`]: cell.disabled,
[`${prefixCls}-cell-today`]: cell.type === 'today', [`${prefixCls}-cell-today`]: cell.type === 'today',
[`${prefixCls}-cell-prev-month`]: cell.type === 'prev-month', [`${prefixCls}-cell-prev-month`]: cell.type === 'prev-month',
[`${prefixCls}-cell-next-month`]: cell.type === 'next-month' [`${prefixCls}-cell-next-month`]: cell.type === 'next-month',
[`${prefixCls}-cell-range`]: cell.range && !cell.start && !cell.end
} }
] ]
}, },

View file

@ -1,27 +1,179 @@
<template> <template>
<div :class="classes"> <div :class="classes">
<div :class="[prefixCls + '-sidebar']" v-if="shortcuts.length">
<div
:class="[prefixCls + '-shortcut']"
v-for="shortcut in shortcuts"
@click="handleShortcutClick(shortcut)">{{ shortcut.text }}</div>
</div>
<div :class="[prefixCls + '-body']">
<div :class="[prefixCls + '-content', prefixCls + '-content-left']">
<div :class="[datePrefixCls + '-header']" v-show="currentView !== 'time'">
<span
:class="iconBtnCls('prev', '-double')"
@click="prevYear"><Icon type="ios-arrow-left"></Icon></span>
<span
:class="iconBtnCls('prev')"
@click="prevMonth"
v-show="currentView === 'date'"><Icon type="ios-arrow-left"></Icon></span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showYearPicker">{{ leftYear }} </span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showMonthPicker"
v-show="currentView === 'date'">{{ leftMonth + 1 }} </span>
</div>
<date-table
v-show="currentView === 'date'"
:year="leftYear"
:month="leftMonth"
:date="date"
:min-date="minDate"
:max-date="maxDate"
:range-state="rangeState"
:selection-mode="selectionMode"
:disabled-date="disabledDate"
@on-pick="handleDatePick"></date-table>
</div>
<div :class="[prefixCls + '-content', prefixCls + '-content-right']">
<div :class="[datePrefixCls + '-header']" v-show="currentView !== 'time'">
<span
:class="[datePrefixCls + '-header-label']"
@click="showYearPicker">{{ rightYear }} </span>
<span
:class="[datePrefixCls + '-header-label']"
@click="showMonthPicker"
v-show="currentView === 'date'">{{ rightMonth + 1 }} </span>
<span
:class="iconBtnCls('next', '-double')"
@click="nextYear"><Icon type="ios-arrow-right"></Icon></span>
<span
:class="iconBtnCls('next')"
@click="nextMonth"
v-show="currentView === 'date'"><Icon type="ios-arrow-right"></Icon></span>
</div>
<date-table
v-show="currentView === 'date'"
:year="rightYear"
:month="rightMonth"
:date="rightDate"
:min-date="minDate"
:max-date="maxDate"
:range-state="rangeState"
:selection-mode="selectionMode"
:disabled-date="disabledDate"
@on-pick="handleDatePick"></date-table>
</div>
</div>
</div> </div>
</template> </template>
<script> <script>
import Icon from '../../icon/icon.vue';
import DateTable from '../base/date-table.vue';
import { toDate } from '../util';
import Mixin from './mixin';
const prefixCls = 'ivu-picker-panel'; const prefixCls = 'ivu-picker-panel';
const datePrefixCls = 'ivu-date-picker'; const datePrefixCls = 'ivu-date-picker';
export default { export default {
props: {}, mixins: [Mixin],
components: { Icon, DateTable },
data () { data () {
return {} return {
prefixCls: prefixCls,
datePrefixCls: datePrefixCls,
shortcuts: [],
date: new Date(),
value: '',
minDate: '',
maxDate: '',
rangeState: {
endDate: null,
selecting: false
},
showTime: false,
disabledDate: '',
currentView: 'date',
selectionMode: 'range'
}
}, },
computed: { computed: {
classes () { classes () {
return [ return [
`${prefixCls}-body-wrapper`, `${prefixCls}-body-wrapper`,
`${datePrefixCls}-with-range`,
{ {
[`${prefixCls}-with-sidebar`]: this.shortcuts.length [`${prefixCls}-with-sidebar`]: this.shortcuts.length
} }
] ]
},
leftYear() {
return this.date.getFullYear();
},
leftMonth() {
return this.date.getMonth();
},
rightYear() {
return this.rightDate.getFullYear();
},
rightMonth() {
return this.rightDate.getMonth();
},
rightDate() {
const newDate = new Date(this.date);
const month = newDate.getMonth();
newDate.setDate(1);
if (month === 11) {
newDate.setFullYear(newDate.getFullYear() + 1);
newDate.setMonth(0);
} else {
newDate.setMonth(month + 1);
}
return newDate;
} }
}, },
methods: {} watch: {
value(newVal) {
if (!newVal) {
this.minDate = null;
this.maxDate = null;
} else if (Array.isArray(newVal)) {
this.minDate = newVal[0] ? toDate(newVal[0]) : null;
this.maxDate = newVal[1] ? toDate(newVal[1]) : null;
if (this.minDate) this.date = new Date(this.minDate);
// this.handleConfirm(true); // todo
}
}
},
methods: {
prevYear () {
},
nextYear () {
},
prevMonth () {
},
nextMonth () {
},
showYearPicker () {
},
showMonthPicker () {
},
handleDatePick () {
},
handleConfirm(visible) {
this.$emit('on-pick', [this.minDate, this.maxDate], visible);
}
}
} }
</script> </script>

View file

@ -1,6 +1,6 @@
<template> <template>
<div :class="classes"> <div :class="classes">
<div :class="[prefixCls + '-sidebar']" v-if="shortcuts"> <div :class="[prefixCls + '-sidebar']" v-if="shortcuts.length">
<div <div
:class="[prefixCls + '-shortcut']" :class="[prefixCls + '-shortcut']"
v-for="shortcut in shortcuts" v-for="shortcut in shortcuts"
@ -67,10 +67,13 @@
import MonthTable from '../base/month-table.vue'; import MonthTable from '../base/month-table.vue';
import { formatDate, parseDate } from '../util'; import { formatDate, parseDate } from '../util';
import Mixin from './mixin';
const prefixCls = 'ivu-picker-panel'; const prefixCls = 'ivu-picker-panel';
const datePrefixCls = 'ivu-date-picker'; const datePrefixCls = 'ivu-date-picker';
export default { export default {
mixins: [Mixin],
components: { Icon, DateTable, YearTable, MonthTable }, components: { Icon, DateTable, YearTable, MonthTable },
data () { data () {
return { return {
@ -114,13 +117,9 @@
if (!newVal) return; if (!newVal) return;
newVal = new Date(newVal); newVal = new Date(newVal);
if (!isNaN(newVal)) { if (!isNaN(newVal)) {
// todo
// if (typeof this.disabledDate === 'function' && this.disabledDate(new Date(newVal))) return;
this.date = newVal; this.date = newVal;
this.year = newVal.getFullYear(); this.year = newVal.getFullYear();
this.month = newVal.getMonth(); this.month = newVal.getMonth();
// this.$emit('on-pick', newVal, true);
} }
} }
}, },
@ -129,17 +128,6 @@
this.date = new Date(); this.date = new Date();
this.$emit('on-pick', ''); this.$emit('on-pick', '');
}, },
handleShortcutClick (shortcut) {
if (shortcut.value) this.$emit('on-pick', shortcut.value());
if (shortcut.onClick) shortcut.onClick(this);
},
iconBtnCls (direction, type = '') {
return [
`${prefixCls}-icon-btn`,
`${datePrefixCls}-${direction}-btn`,
`${datePrefixCls}-${direction}-btn-arrow${type}`,
]
},
resetDate () { resetDate () {
this.date = new Date(this.date); this.date = new Date(this.date);
}, },

View file

@ -0,0 +1,18 @@
const prefixCls = 'ivu-picker-panel';
const datePrefixCls = 'ivu-date-picker';
export default {
methods: {
iconBtnCls (direction, type = '') {
return [
`${prefixCls}-icon-btn`,
`${datePrefixCls}-${direction}-btn`,
`${datePrefixCls}-${direction}-btn-arrow${type}`,
]
},
handleShortcutClick (shortcut) {
if (shortcut.value) this.$emit('on-pick', shortcut.value());
if (shortcut.onClick) shortcut.onClick(this);
}
}
}

View file

@ -1,6 +1,8 @@
@date-picker-prefix-cls: ~"@{css-prefix}date-picker"; @date-picker-prefix-cls: ~"@{css-prefix}date-picker";
@picker-prefix-cls: ~"@{css-prefix}picker"; @picker-prefix-cls: ~"@{css-prefix}picker";
@date-picker-cells-width: 196px;
.@{date-picker-prefix-cls} { .@{date-picker-prefix-cls} {
position: relative; position: relative;
.@{select-dropdown-prefix-cls} { .@{select-dropdown-prefix-cls} {
@ -10,7 +12,7 @@
max-height: none; max-height: none;
} }
&-cells{ &-cells{
width: 196px; width: @date-picker-cells-width;
margin: 10px; margin: 10px;
span{ span{
display: inline-block; display: inline-block;
@ -81,7 +83,27 @@
} }
} }
} }
&-selected,&-selected:hover { &-range{
position: relative;
em{
position: relative;
z-index: 1;
}
&:before{
content: '';
display: block;
background: @date-picker-cell-hover-bg;
border-radius: 0;
border: 0;
position: absolute;
top: 2px;
bottom: 2px;
left: 0;
right: 0;
}
}
&-selected,&-selected:hover
{
em{ em{
background: @primary-color; background: @primary-color;
color: #fff; color: #fff;
@ -93,7 +115,8 @@
color: @btn-disable-bg; color: @btn-disable-bg;
} }
} }
&-today&-selected{ &-today&-selected
{
em{ em{
&:after{ &:after{
background: #fff; background: #fff;
@ -151,6 +174,17 @@
} }
} }
} }
&-with-range{
.@{picker-prefix-cls}-panel{
&-body{
min-width: (@date-picker-cells-width + 20) * 2;
}
&-content{
float: left;
}
}
}
} }
.@{picker-prefix-cls} { .@{picker-prefix-cls} {

View file

@ -1,5 +1,5 @@
<template> <template>
<div style="margin: 150px"> <div style="margin: 50px">
<br> <br>
<row> <row>
<i-col span="8"> <i-col span="8">
@ -11,11 +11,16 @@
:options="options" :options="options"
@on-change="change" @on-change="change"
:format="format" :format="format"
:editable="false"
@on-open-change="change2"></date-picker> @on-open-change="change2"></date-picker>
</i-col> </i-col>
<i-col span="8"> <i-col span="8">
<date-picker type="daterange" style="width:200px" placeholder="请选择日期" :value.sync="value2" :options="options2"></date-picker> <date-picker
type="daterange"
style="width:200px"
placeholder="请选择日期"
:value.sync="value2"
align="right"
:options="options2"></date-picker>
</i-col> </i-col>
</row> </row>
</div> </div>
@ -26,9 +31,42 @@
return { return {
// value: new Date(), // value: new Date(),
value: '2016-12-25', value: '2016-12-25',
value2: '', value2: ['2016-12-17', '2017-01-05'],
options2: { options2: {
shortcuts: [
{
text: '今天',
value () {
// return new Date();
return '1/2/19'
},
onClick (picker) {
console.log('点击了今天');
}
},
{
text: '昨天',
value () {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24);
return date;
},
onClick () {
console.log('点击了昨天');
}
},
{
text: '最近三个月',
value () {
const date = new Date();
date.setTime(date.getTime() - 3600 * 1000 * 24 * 7);
return date;
},
onClick () {
console.log('点击了一周前');
}
}
]
}, },
options: { options: {
disabledDate(time) { disabledDate(time) {