Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DatePicker: add attribute defaultTime #9094

Merged
merged 3 commits into from
Jan 16, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion examples/docs/en-US/date-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@
value8: '',
value9: '',
value10: '',
value11: ''
value11: '',
value12: '',
value13: ''
};
}
};
Expand Down Expand Up @@ -329,6 +331,50 @@ If type is `daterange`, `default-value` sets the left side calendar.
```
:::

### Default start & end time value

When picking date range on the date panel with type `datetimerange`, `00:00:00` will be used as the default time value for start & end date. We can control it with option `default-time`.

`default-time` accepts an array of string. The first item controls time value of the start date and the second item controls time value of the end date.

:::demo
```html
<template>
<div class="block">
<span class="demonstration">start date time 12:00:00</span>
<el-date-picker
v-model="value12"
type="datetimerange"
start-placeholder="Start Date"
end-placeholder="End Date"
:default-time="['12:00:00']">
</el-date-picker>
</div>
<div class="block">
<span class="demonstration">start date time 12:00:00, end date time 08:00:00</span>
<el-date-picker
v-model="value13"
type="datetimerange"
start-placeholder="Start Date"
end-placeholder="End Date"
:default-time="['12:00:00', '08:00:00']">
</el-date-picker>
</div>
</template>

<script>
export default {
data() {
return {
value12: '',
value13: ''
};
}
};
</script>
```
:::

### Formatted Value

By default, DatePicker emits `Date` object. You can use `value-format` to designate the format of emitted value, it accepts the same format string of `format` attribute.
Expand Down Expand Up @@ -394,6 +440,7 @@ This feature is at alpha stage. Feedback welcome.
| picker-options | additional options, check the table below | object | — | {} |
| range-separator | range separator | string | — | '-' |
| default-value | optional, default date of the calendar | Date | anything accepted by `new Date()` | — |
| default-time | optional, the time value to use when select datetime range in date table (type `datetimerange`) | string[] | Array with length 2, each item is a string like `12:00:00`. The first item for the start datetime and then second item for the end datetime | — |
| value-format | optional, format of binding value. If not specified, the binding value will be a Date object | string | year `yyyy`, month `MM`, day `dd`, hour `HH`, minute `mm`, second `ss`, AM/PM `A` | — |
| name | same as `name` in native input | string | — | — |
| unlink-panels | unlink two date-panels in range-picker | boolean | — | false |
Expand Down
49 changes: 48 additions & 1 deletion examples/docs/zh-CN/date-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@
value8: '',
value9: '',
value10: '',
value11: ''
value11: '',
value12: '',
value13: ''
};
}
};
Expand Down Expand Up @@ -324,6 +326,50 @@
```
:::

### 默认的起始与结束时刻

使用类型`datetimerange`选择时间范围时,在日期选择面板中选定起始与结束的日期,默认会使用该日期的`00:00:00`作为起始与结束的时刻;通过选项`default-time`可以控制选中起始与结束日期时所使用的具体时刻。

`default-time`接受一个数组,数组每项值为字符串,形如`12:00:00`,其中第一项控制起始日期的具体时刻,第二项控制结束日期的具体时刻。

:::demo
```html
<template>
<div class="block">
<span class="demonstration">起始日期时刻为 12:00:00</span>
<el-date-picker
v-model="value12"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['12:00:00']">
</el-date-picker>
</div>
<div class="block">
<span class="demonstration">起始日期时刻为 12:00:00,结束日期时刻为 08:00:00</span>
<el-date-picker
v-model="value13"
type="datetimerange"
start-placeholder="开始日期"
end-placeholder="结束日期"
:default-time="['12:00:00', '08:00:00']">
</el-date-picker>
</div>
</template>

<script>
export default {
data() {
return {
value12: '',
value13: ''
};
}
};
</script>
```
:::

### 返回值格式

默认情况下,组件接受并返回`Date`对象。
Expand Down Expand Up @@ -390,6 +436,7 @@
| picker-options | 当前时间日期选择器特有的选项参考下表 | object | — | {} |
| range-separator | 选择范围时的分隔符 | string | — | '-' |
| default-value | 可选,选择器打开时默认显示的时间 | Date | 可被`new Date()`解析 | — |
| default-time | 可选,选择器 type 为 `datetimerange`,范围选择选中日期时所使用的当日内具体时刻 | string[] | 数组,长度为 2,每项值为字符串,形如`12:00:00`,第一项指定开始日期的时刻,第二项指定结束日期的时刻,不指定会使用时刻 `00:00:00` | — |
| value-format | 可选,绑定值的格式。不指定则绑定值为 Date 对象 | string | 年 `yyyy`,月 `MM`,日 `dd`,小时 `HH`,分 `mm`,秒 `ss`,AM/PM `A` | — |
| name | 原生属性 | string | — | — |
| unlink-panels | 在范围选择器里取消两个日期面板之间的联动 | boolean | — | false |
Expand Down
33 changes: 26 additions & 7 deletions packages/date-picker/src/panel/date-range.vue
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,19 @@
}
};

const modifyWithGivenTime = (date, time) => {
if (date == null || time == null) {
return date;
}
time = parseDate(time, 'HH:mm:ss');
return modifyTime(
date,
time.getHours(),
time.getMinutes(),
time.getSeconds()
);
};

export default {
mixins: [Locale],

Expand Down Expand Up @@ -301,6 +314,7 @@
popperClass: '',
value: [],
defaultValue: null,
defaultTime: null,
minDate: '',
maxDate: '',
leftDate: new Date(),
Expand Down Expand Up @@ -412,8 +426,9 @@
},

handleChangeRange(val) {
this.minDate = val.minDate;
this.maxDate = val.maxDate;
const defaultTime = this.defaultTime || [];
this.minDate = modifyWithGivenTime(val.minDate, defaultTime[0]);
this.maxDate = modifyWithGivenTime(val.maxDate, defaultTime[1]);
this.rangeState = val.rangeState;
},

Expand Down Expand Up @@ -480,17 +495,21 @@
},

handleRangePick(val, close = true) {
if (this.maxDate === val.maxDate && this.minDate === val.minDate) {
const defaultTime = this.defaultTime || [];
const minDate = modifyWithGivenTime(val.minDate, defaultTime[0]);
const maxDate = modifyWithGivenTime(val.maxDate, defaultTime[1]);

if (this.maxDate === maxDate && this.minDate === minDate) {
return;
}
this.onPick && this.onPick(val);
this.maxDate = val.maxDate;
this.minDate = val.minDate;
this.maxDate = maxDate;
this.minDate = minDate;

// workaround for https://github.com/ElemeFE/element/issues/7539, should remove this block when we don't have to care about Chromium 55 - 57
setTimeout(() => {
this.maxDate = val.maxDate;
this.minDate = val.minDate;
this.maxDate = maxDate;
this.minDate = minDate;
}, 10);
if (!close || this.showTime) return;
this.handleConfirm();
Expand Down
2 changes: 2 additions & 0 deletions packages/date-picker/src/picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ export default {
},
value: {},
defaultValue: {},
defaultTime: {},
rangeSeparator: {
default: '-'
},
Expand Down Expand Up @@ -701,6 +702,7 @@ export default {
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;
Expand Down
91 changes: 91 additions & 0 deletions test/unit/specs/date-picker.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1246,6 +1246,97 @@ describe('DatePicker', () => {
}, DELAY);
});

it('select daterange with defaultTime min', done => {

const vmWithDefaultTime = createVue({
template: `
<el-date-picker ref="compo" type="datetimerange" v-model="value" :default-time="defaultTime"></el-date-picker>
`,
data() {
return {
value: [new Date(2000, 10, 10, 10, 10), new Date(2000, 10, 11, 10, 10)],
defaultTime: ['11:59:59']
};
}
}, true).$refs.compo;

setTimeout(_ => {
vmWithDefaultTime.$el.click();

setTimeout(_ => {
const pickers = vmWithDefaultTime.picker.$el.querySelectorAll('.el-date-range-picker__content');
const leftCell = pickers[0].querySelector('td.available');
const rightCell = pickers[1].querySelector('td.available');

triggerEvent(leftCell, 'mousemove', true);
triggerEvent(leftCell, 'click', true);
setTimeout(_ => {
triggerEvent(rightCell, 'mousemove', true);
triggerEvent(rightCell, 'click', true);

setTimeout(_ => {
const {
minDate,
maxDate
} = vmWithDefaultTime.picker;
expect(minDate.getHours()).to.be.equal(11);
expect(minDate.getMinutes()).to.be.equal(59);
expect(minDate.getSeconds()).to.be.equal(59);
expect(maxDate.getHours()).to.be.equal(0);
expect(maxDate.getMinutes()).to.be.equal(0);
expect(maxDate.getSeconds()).to.be.equal(0);
done();
}, DELAY);
}, DELAY);
}, DELAY);
}, DELAY * 2); // `DELAY * 2` to ensure this case passes in travis CI
});

it('select daterange with defaultTime min & max', done => {
const vmWithDefaultTime = createVue({
template: `
<el-date-picker ref="compo" type="datetimerange" v-model="value" :default-time="defaultTime"></el-date-picker>
`,
data() {
return {
value: [new Date(2000, 10, 10, 10, 10), new Date(2000, 10, 11, 10, 10)],
defaultTime: ['11:59:59', '18:00:00']
};
}
}, true).$refs.compo;

setTimeout(_ => {
vmWithDefaultTime.$el.click();

setTimeout(_ => {
const pickers = vmWithDefaultTime.picker.$el.querySelectorAll('.el-date-range-picker__content');
const leftCell = pickers[0].querySelector('td.available');
const rightCell = pickers[1].querySelector('td.available');

triggerEvent(leftCell, 'mousemove', true);
triggerEvent(leftCell, 'click', true);
setTimeout(_ => {
triggerEvent(rightCell, 'mousemove', true);
triggerEvent(rightCell, 'click', true);

setTimeout(_ => {
const {
minDate,
maxDate
} = vmWithDefaultTime.picker;
expect(minDate.getHours()).to.be.equal(11);
expect(minDate.getMinutes()).to.be.equal(59);
expect(minDate.getSeconds()).to.be.equal(59);
expect(maxDate.getHours()).to.be.equal(18);
expect(maxDate.getMinutes()).to.be.equal(0);
expect(maxDate.getSeconds()).to.be.equal(0);
done();
}, DELAY);
}, DELAY);
}, DELAY);
}, DELAY * 2); // `DELAY * 2` to ensure this case passes in travis CI
});

it('prev/next month button', done => {
const leftBtn = vm.picker.$el.querySelector('.is-left .el-icon-arrow-left');
const rightBtn = vm.picker.$el.querySelector('.is-right .el-icon-arrow-right');
Expand Down