Skip to content

Commit adabeff

Browse files
ziyoungisland205
authored andcommitted
Calendar: Display correct header when range is specified (#16354)
* Calendar: display correct header when range is specified * firstOfWeek is supported * update docs * update test * update * fix typo
1 parent e13de16 commit adabeff

File tree

6 files changed

+50
-19
lines changed

6 files changed

+50
-19
lines changed

examples/docs/en-US/calendar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ Display date.
5656
| Attribute | Description | Type | Accepted Values | Default |
5757
|-----------------|------------------- |---------- |---------------------- |--------- |
5858
| value / v-model | binding value | Date/string/number |||
59-
| range | time range, including start time and end time. Start time must be Monday, end time must be Sunday, the time span cannot exceed two months | Array |||
59+
| range | time range, including start time and end time. Start time must be start day of week, end time must be end day of week, the time span cannot exceed two months. | Array |||
6060
| first-day-of-week | fisrt day of week| Number | 1 to 7 | 1 |
6161

6262
### dateCell scoped slot 参数

examples/docs/es/calendar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Muestra fechas.
5757
| Atributo | Descripción | Tipo | Valores aceptados | Por defecto |
5858
|-----------------|------------------- |---------- |---------------------- |------------ |
5959
| value / v-model | valor vinculante | Date/string/number |||
60-
| range | rango de tiempo, incluyendo el tiempo de inicio y el tiempo final. El tiempo de inicio debe ser el lunes, el tiempo final debe ser el domingo, el período no puede exceder los dos meses. | Array |||
60+
| range | rango de tiempo, incluyendo el tiempo de inicio y el tiempo final. Start time must be start day of week, end time must be end day of week, the time span cannot exceed two months | Array |||
6161
| first-day-of-week | fisrt day of week| Number | 1 to 7 | 1 |
6262

6363
### dateCell scoped slot

examples/docs/fr-FR/calendar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ Affiche un calendrier.
5757
| Attribut | Description | Type | Valeurs acceptées | Défaut |
5858
|------------------ |-------------- |---------- |---------------------- |--------- |
5959
| value / v-model | Valeur liée. | Date/string/number |||
60-
| range | Intervalle de dates, début et fin inclus. Le début doit être un lundi et la fin un dimanche, l'intervalle ne pouvant excéder deux mois. | Array |||
60+
| range | Intervalle de dates, début et fin inclus. Start time must be start day of week, end time must be end day of week, the time span cannot exceed two months. | Array |||
6161
| first-day-of-week | fisrt day of week| Number | 1 to 7 | 1 |
6262

6363
### Slot dateCell

examples/docs/zh-CN/calendar.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545

4646
### 自定义范围
4747

48-
:::demo 设置 `range` 属性指定日历的显示范围。开始时间必须是周一,结束时间必须是周日,且时间跨度不能超过两个月。
48+
:::demo 设置 `range` 属性指定日历的显示范围。开始时间必须是周起始日,结束时间必须是周结束日,且时间跨度不能超过两个月。
4949
```html
5050
<el-calendar :range="['2019-03-04', '2019-03-24']">
5151
</el-calendar>

packages/calendar/src/main.vue

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
:selected-day="realSelectedDay"
5151
:range="range"
5252
:hide-header="index !== 0"
53+
:first-day-of-week="realFirstDayOfWeek"
5354
@pick="pickDay" />
5455
</div>
5556
</div>
@@ -62,6 +63,7 @@ import DateTable from './date-table';
6263
import { validateRangeInOneMonth } from 'element-ui/src/utils/date-util';
6364
6465
const validTypes = ['prev-month', 'today', 'next-month'];
66+
const weekDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
6567
const oneDay = 86400000;
6668
6769
export default {
@@ -127,6 +129,17 @@ export default {
127129
throw new Error('invalid val');
128130
}
129131
return val instanceof Date ? val : new Date(val);
132+
},
133+
134+
rangeValidator(date, isStart) {
135+
const firstDayOfWeek = this.realFirstDayOfWeek;
136+
const expected = isStart ? firstDayOfWeek : (firstDayOfWeek === 0 ? 6 : firstDayOfWeek - 1);
137+
const message = `${isStart ? 'start' : 'end'} of range should be ${weekDays[expected]}.`;
138+
if (date.getDay() !== expected) {
139+
console.warn('[ElementCalendar]', message, 'Invalid range will be ignored.');
140+
return false;
141+
}
142+
return true;
130143
}
131144
},
132145
@@ -189,21 +202,9 @@ export default {
189202
validatedRange() {
190203
let range = this.range;
191204
if (!range) return [];
192-
const expetedMap = {
193-
0: {
194-
value: 1,
195-
message: 'start of range should be Monday.'
196-
},
197-
1: {
198-
value: 0,
199-
message: 'end of range should be Sunday.'
200-
}
201-
};
202205
range = range.reduce((prev, val, index) => {
203206
const date = this.toDate(val);
204-
if (date.getDay() !== expetedMap[index].value) {
205-
console.warn('[ElementCalendar]', expetedMap[index].message, ' invalid range will be ignored');
206-
} else {
207+
if (this.rangeValidator(date, index === 0)) {
207208
prev = prev.concat(date);
208209
}
209210
return prev;
@@ -227,12 +228,23 @@ export default {
227228
console.warn('[ElementCalendar]start time and end time interval must not exceed two months');
228229
return [];
229230
}
231+
// 第一个月的时间范围
230232
data.push([
231233
start,
232234
lastDay
233235
]);
234-
let interval = startDay.getDay();
235-
interval = interval <= 1 ? Math.abs(interval - 1) : (8 - interval);
236+
// 下一月的时间范围,需要计算一下该月的第一个周起始日
237+
const firstDayOfWeek = this.realFirstDayOfWeek;
238+
const nextMontFirstDay = startDay.getDay();
239+
let interval = 0;
240+
if (nextMontFirstDay !== firstDayOfWeek) {
241+
if (firstDayOfWeek === 0) {
242+
interval = 7 - nextMontFirstDay;
243+
} else {
244+
interval = firstDayOfWeek - nextMontFirstDay;
245+
interval = interval > 0 ? interval : 7 + interval;
246+
}
247+
}
236248
startDay = this.toDate(startDay.getTime() + interval * oneDay);
237249
if (startDay.getDate() < end.getDate()) {
238250
data.push([

test/unit/specs/calendar.spec.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,24 @@ describe('Calendar', () => {
8585
expect(firstRow.firstElementChild.innerText).to.be.equal('31');
8686
expect(firstRow.lastElementChild.innerText).to.be.equal('6');
8787
});
88+
89+
it('firstDayOfWeek in range mode', async() => {
90+
vm = createVue({
91+
template: `
92+
<el-calendar v-model="value" :first-day-of-week="7" :range="['2019-02-03', '2019-03-23']"></el-calendar>
93+
`,
94+
data() {
95+
return {
96+
value: new Date('2019-03-04')
97+
};
98+
}
99+
}, true);
100+
const head = vm.$el.querySelector('.el-calendar-table thead');
101+
expect(head.firstElementChild.innerText).to.be.equal('日');
102+
expect(head.lastElementChild.innerText).to.be.equal('六');
103+
const firstRow = vm.$el.querySelector('.el-calendar-table__row');
104+
expect(firstRow.firstElementChild.innerText).to.be.equal('3');
105+
expect(firstRow.lastElementChild.innerText).to.be.equal('9');
106+
});
88107
});
89108

0 commit comments

Comments
 (0)