update DatePicker

update DatePicker
This commit is contained in:
梁灏 2016-12-14 23:08:57 +08:00
parent d3eee3f464
commit 50637863ce
9 changed files with 343 additions and 98 deletions

View file

@ -1,43 +1,34 @@
<template>
<table
cellspacing="0"
cellpadding="0"
<div
:class="classes"
@click="handleClick"
@mousemove="handleMouseMove">
<tbody>
<tr>
<th v-if="showWeekNumber"></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
<tr :class="rowCls(row[1])" v-for="row in rows">
<td :class="getCellClasses(cell)" v-for="cell in row">{{ cell.text }}</td>
</tr>
</tbody>
</table>
<div :class="[prefixCls + '-header']">
<span></span><span></span><span></span><span></span><span></span><span></span><span></span>
</div>
<span :class="getCellCls(cell)" v-for="cell in cells"><em>{{ cell.text }}</em></span>
</div>
</template>
<script>
const prefixCls = 'ivu-date-picker-table';
import { getFirstDayOfMonth, getDayCountOfMonth, getStartDateOfMonth } from '../util';
import { deepCopy } from '../../../utils/assist';
const prefixCls = 'ivu-date-picker-cells';
const clearHours = function (time) {
const cloneDate = new Date(time);
cloneDate.setHours(0, 0, 0, 0);
return cloneDate.getTime();
};
export default {
props: {
date: {},
year: {},
month: {},
week: {},
selectionMode: {
default: 'day'
},
showWeekNumber: {
type: Boolean,
default: false
},
disabledDate: {},
minDate: {},
maxDate: {},
@ -51,7 +42,7 @@
};
}
},
value: {}
value: ''
},
data () {
return {
@ -61,11 +52,77 @@
computed: {
classes () {
return [
`${prefixCls}`,
{
[`${prefixCls}-week-mode`]: this.selectionMode === 'week'
}
`${prefixCls}`
]
},
startDate() {
return getStartDateOfMonth(this.year, this.month);
},
cells () {
const date = new Date(this.year, this.month, 1);
let day = getFirstDayOfMonth(date); // day of first day
day = (day === 0 ? 7 : day);
const today = clearHours(new Date()); // timestamp of today
const selectDay = clearHours(new Date(this.value)); // timestamp of selected day
const dateCountOfMonth = getDayCountOfMonth(date.getFullYear(), date.getMonth());
const dateCountOfLastMonth = getDayCountOfMonth(date.getFullYear(), (date.getMonth() === 0 ? 11 : date.getMonth() - 1));
const disabledDate = this.disabledDate;
let cells = [];
const cell_tmpl = {
text: '',
type: '',
selected: false,
disabled: false
};
if (day !== 7) {
for (let i = 0; i < day; i++) {
const cell = deepCopy(cell_tmpl);
cell.type = 'prev-month';
cell.text = dateCountOfLastMonth - (day - 1) + i;
let prevMonth = this.month - 1;
let prevYear = this.year;
if (this.month === 0) {
prevMonth = 11;
prevYear -= 1;
}
const time = clearHours(new Date(prevYear, prevMonth, cell.text));
cell.disabled = typeof disabledDate === 'function' && disabledDate(new Date(time));
cells.push(cell);
}
}
for (let i = 1; i <= dateCountOfMonth; i++) {
const cell = deepCopy(cell_tmpl);
const time = clearHours(new Date(this.year, this.month, i));
cell.type = time === today ? 'today' : 'normal';
cell.text = i;
cell.selected = time === selectDay;
cell.disabled = typeof disabledDate === 'function' && disabledDate(new Date(time));
cells.push(cell);
}
const nextMonthCount = 42 - cells.length;
for (let i = 1; i <= nextMonthCount; i++) {
const cell = deepCopy(cell_tmpl);
cell.type = 'next-month';
cell.text = i;
let nextMonth = this.month + 1;
let nextYear = this.year;
if (this.month === 11) {
nextMonth = 0;
nextYear += 1;
}
const time = clearHours(new Date(nextYear, nextMonth, cell.text));
cell.disabled = typeof disabledDate === 'function' && disabledDate(new Date(time));
cells.push(cell);
}
return cells;
}
},
methods: {
@ -74,26 +131,20 @@
},
handleMouseMove () {
},
rowCls (cell) {
return [
`${prefixCls}-row`,
{
[`${prefixCls}-row-current`]: this.value && this.isWeekActive(cell)
}
]
},
isWeekActive (cell) {
},
getCellCls (cell) {
return [
`${prefixCls}-cell`,
{
[`${prefixCls}-cell-today`]: cell.type === 'today'
[`${prefixCls}-cell-selected`]: cell.selected,
[`${prefixCls}-cell-disabled`]: cell.disabled,
[`${prefixCls}-cell-today`]: cell.type === 'today',
[`${prefixCls}-cell-prev-month`]: cell.type === 'prev-month',
[`${prefixCls}-cell-next-month`]: cell.type === 'next-month'
}
]
}
},
}
}
</script>

View file

@ -32,7 +32,14 @@
</div>
<div :class="[prefixCls + '-content']">
<date-table
v-show="currentView === 'date'"></date-table>
v-show="currentView === 'date'"
:year="year"
:month="month"
:date="date"
:value="value"
:week="week"
:selection-mode="selectionMode"
:disabled-date="disabledDate"></date-table>
<year-table
v-show="currentView === 'year'"></year-table>
<month-table
@ -56,10 +63,37 @@
prefixCls: prefixCls,
datePrefixCls: datePrefixCls,
shortcuts: [],
currentView: 'date'
currentView: 'date',
date: new Date(),
value: '',
showTime: false,
selectionMode: 'day',
visible: false,
disabledDate: '',
year: null,
month: null,
week: null,
showWeekNumber: false,
timePickerVisible: false
}
},
computed: {
},
watch: {
value (newVal) {
newVal = new Date(newVal);
if (!isNaN(newVal)) {
// todo
// if (typeof this.disabledDate === 'function' && this.disabledDate(new Date(newVal))) return;
this.date = newVal;
this.year = newVal.getFullYear();
this.month = newVal.getMonth();
// this.$emit('on-pick', newVal, true);
}
}
},
computed: {},
methods: {
handleShortcutClick (shortcut) {
@ -90,11 +124,18 @@
}
},
ready () {
console.log(123)
compiled () {
if (this.selectionMode === 'month') {
this.currentView = 'month';
}
if (this.date && !this.year) {
this.year = this.date.getFullYear();
this.month = this.date.getMonth();
}
},
beforeDestroy () {
console.log(456)
}
}
</script>

View file

@ -27,6 +27,7 @@
import Drop from '../../components/select/dropdown.vue';
import clickoutside from '../../directives/clickoutside';
import { oneOf } from '../../utils/assist';
import { formatDate } from './util';
const prefixCls = 'ivu-date-picker';
@ -90,7 +91,8 @@
showClose: false,
visualValue: '',
visible: false,
picker: null
picker: null,
internalValue: ''
}
},
computed: {
@ -126,6 +128,13 @@
showPicker () {
if (!this.picker) {
this.picker = new Vue(this.panel).$mount(this.$els.picker);
this.picker.value = this.internalValue;
if (this.format) this.picker.format = this.format;
const options = this.options;
for (const option in options) {
this.picker[option] = options[option];
}
}
}
},
@ -137,6 +146,12 @@
} else {
this.$refs.drop.destroy();
}
},
value: {
immediate: true,
handler (val) {
this.internalValue = formatDate(val);
}
}
},
beforeDestroy () {

View file

@ -19,9 +19,20 @@ export default {
return oneOf(value, ['year', 'month', 'week', 'date', 'daterange', 'datetime', 'datetimerange']);
},
default: 'date'
},
value: {
type: [String, Array]
}
},
created () {
if (!this.value) {
if (this.type === 'daterange' || this.type === 'datetimerange') {
this.value = ['',''];
} else {
this.value = '';
}
}
this.panel = getPanel(this.type);
}
}

View file

@ -0,0 +1,103 @@
@date-picker-prefix-cls: ~"@{css-prefix}date-picker";
.@{date-picker-prefix-cls} {
position: relative;
.@{select-dropdown-prefix-cls} {
width: auto;
overflow: visible;
max-height: none;
}
&-cells{
width: 196px;
margin: 10px;
span{
display: inline-block;
width: 24px;
height: 24px;
em{
display: inline-block;
width: 24px;
height: 24px;
line-height: 24px;
margin: 2px;
font-style: normal;
border-radius: @btn-border-radius-small;
text-align: center;
transition: all @transition-time @ease-in-out;
}
}
&-header span{
line-height: 24px;
text-align: center;
margin: 2px;
color: @btn-disable-color;
}
&-cell{
span&{
width: 28px;
height: 28px;
cursor: pointer;
}
&:hover{
em{
background: @date-picker-cell-hover-bg;
}
}
&-prev-month,&-next-month{
em{
color: @btn-disable-color;
}
&:hover{
em{
background: transparent;
}
}
}
span&-disabled,span&-disabled:hover{
cursor: @cursor-disabled;
background: @btn-disable-bg;
color: @btn-disable-color;
em{
color: inherit;
background: inherit;
}
}
&-today{
em {
position: relative;
&:after{
content: '';
display: block;
width: 6px;
height: 6px;
border-radius: 50%;
background: @primary-color;
position: absolute;
top: 1px;
right: 1px;
}
}
}
&-selected,&-selected:hover {
em{
background: @primary-color;
color: #fff;
}
}
span&-disabled&-selected{
em {
background: @btn-disable-color;
color: @btn-disable-bg;
}
}
&-today&-selected{
em{
&:after{
background: #fff;
}
}
}
}
}
}

View file

@ -32,3 +32,4 @@
@import "dropdown";
@import "tabs";
@import "menu";
@import "date-picker";

View file

@ -43,6 +43,7 @@
@table-td-hover-bg : #ebf7ff;
@table-td-highlight-bg : #ebf7ff;
@menu-dark-active-bg : #313540;
@date-picker-cell-hover-bg : #e1f0fe;
// Shadow
@shadow-color : rgba(0, 0, 0, .2);

View file

@ -1,13 +1,21 @@
<template>
<div style="margin: 50px">
<date-picker style="width:200px" placeholder="请选择日期"></date-picker>
<date-picker style="width:200px" placeholder="请选择日期" :value.sync="value" :options="options"></date-picker>
</div>
</template>
<script>
export default {
props: {},
data () {
return {}
return {
value: '2016-12-18',
// value: '',
options: {
disabledDate(time) {
return time.getTime() < Date.now() - 8.64e7;
// return time && time.valueOf() < Date.now();
}
}
}
},
computed: {},
methods: {}

View file

@ -1,84 +1,98 @@
<template>
<i-table width="550" border :columns="columns2" :data="data3"></i-table>
<i-button @click="changeFilter">改变filter</i-button>
<i-table border :columns="columns6" :data="data5"></i-table>
</template>
<script>
export default {
data () {
return {
columns2: [
columns6: [
{
title: '日期',
key: 'date'
},
{
title: '姓名',
key: 'name',
width: 100,
fixed: 'left'
key: 'name'
},
{
title: '年龄',
key: 'age',
width: 100
filters: [
{
label: '大于25岁',
value: 1
},
{
title: '省份',
key: 'province',
width: 100
},
{
title: '市区',
key: 'city',
width: 100
label: '小于25岁',
value: 2
}
],
filterMultiple: false,
filterMethod (value, row) {
if (value === 1) {
return row.age > 25;
} else if (value === 2) {
return row.age < 25;
}
}
},
{
title: '地址',
key: 'address',
width: 200
filters: [
{
label: '北京',
value: '北京'
},
{
title: '邮编',
key: 'zip',
width: 100
label: '上海',
value: '上海'
},
{
title: '操作',
key: 'action',
fixed: 'right',
width: 120,
render () {
return `<i-button type="text" size="small">查看</i-button><i-button type="text" size="small">编辑</i-button>`;
label: '深圳',
value: '深圳'
}
],
filterMethod (value, row) {
return row.address.indexOf(value) > -1;
}
}
],
data3: [
data5: [
{
name: '王小明',
age: 18,
address: '北京市朝阳区芍药居',
province: '北京市',
city: '朝阳区',
zip: 100000
date: '2016-10-03'
},
{
name: '张小刚',
age: 25,
address: '北京市海淀区西二旗',
province: '北京市',
city: '海淀区',
zip: 100000
date: '2016-10-01'
},
{
name: '李小红',
age: 30,
address: '上海市浦东新区世纪大道',
province: '上海市',
city: '浦东新区',
zip: 100000
date: '2016-10-02'
},
{
name: '周小伟',
age: 26,
address: '深圳市南山区深南大道',
province: '广东',
city: '南山区',
zip: 100000
date: '2016-10-04'
}
]
}
},
methods: {
changeFilter () {
this.columns6[2].filters = [
{
label: '小于25岁',
value: 2
}
]
}