Bladeren bron

DatePicker: custom fisrt day of week #1061

qingwei.li 8 jaren geleden
bovenliggende
commit
9f8837ec40

+ 1 - 0
examples/docs/en-US/date-picker.md

@@ -268,6 +268,7 @@ Picking a date range is supported.
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | shortcuts | a { text, onClick } object array to set shortcut options, check the table below | object[] | — | — |
 | disabledDate | a function determining if a date is disabled with that date as its parameter. Should return a Boolean | function | — | — |
+| firstDayOfWeek | first day of week | Number | 1 to 7 | 7 |
 
 ### shortcuts
 | Attribute      | Description          | Type      | Accepted Values       | Default  |

+ 1 - 0
examples/docs/zh-CN/date-picker.md

@@ -302,6 +302,7 @@
 |---------- |-------------- |---------- |--------------------------------  |-------- |
 | shortcuts | 设置快捷选项,需要传入 { text, onClick } 对象用法参考 demo 或下表 | Object[] | - | - |
 | disabledDate | 设置禁用状态,参数为当前日期,要求返回 Boolean | Function | - | - |
+| firstDayOfWeek | 周起始日 | Number | 1 到 7 | 7 |
 
 ### Shortcuts
 | 参数      | 说明          | 类型      | 可选值                           | 默认值  |

+ 24 - 11
packages/date-picker/src/basic/date-table.vue

@@ -9,13 +9,7 @@
     <tbody>
     <tr>
       <th v-if="showWeekNumber">{{ t('el.datepicker.week') }}</th>
-      <th>{{ t('el.datepicker.weeks.sun') }}</th>
-      <th>{{ t('el.datepicker.weeks.mon') }}</th>
-      <th>{{ t('el.datepicker.weeks.tue') }}</th>
-      <th>{{ t('el.datepicker.weeks.wed') }}</th>
-      <th>{{ t('el.datepicker.weeks.thu') }}</th>
-      <th>{{ t('el.datepicker.weeks.fri') }}</th>
-      <th>{{ t('el.datepicker.weeks.sat') }}</th>
+      <th v-for="week in WEEKS">{{ t('el.datepicker.weeks.' + week) }}</th>
     </tr>
     <tr
       class="el-date-table__row"
@@ -35,6 +29,7 @@
   import { hasClass } from 'wind-dom/src/class';
   import Locale from 'element-ui/src/mixins/locale';
 
+  const WEEKS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
   const clearHours = function(time) {
     const cloneDate = new Date(time);
     cloneDate.setHours(0, 0, 0, 0);
@@ -45,6 +40,12 @@
     mixins: [Locale],
 
     props: {
+      firstDayOfWeek: {
+        default: 7,
+        type: Number,
+        validator: val => val >= 1 && val <= 7
+      },
+
       date: {},
 
       year: {},
@@ -83,6 +84,17 @@
     },
 
     computed: {
+      offsetDay() {
+        const week = this.firstDayOfWeek;
+        // 周日为界限,左右偏移的天数,3217654 例如周一就是 -1,目的是调整前两行日期的位置
+        return week > 3 ? 7 - week : -week;
+      },
+
+      WEEKS() {
+        const week = this.firstDayOfWeek;
+        return WEEKS.concat(WEEKS).slice(week, week + 7);
+      },
+
       monthDate() {
         return this.date.getDate();
       },
@@ -99,6 +111,7 @@
 
         day = (day === 0 ? 7 : day);
 
+        const offset = this.offsetDay;
         const rows = this.tableRows;
         let count = 1;
         let firstDayPosition;
@@ -125,7 +138,7 @@
             cell.type = 'normal';
 
             const index = i * 7 + j;
-            const time = startDate.getTime() + DAY_DURATION * index;
+            const time = startDate.getTime() + DAY_DURATION * (index - offset);
             cell.inRange = time >= clearHours(this.minDate) && time <= clearHours(this.maxDate);
             cell.start = this.minDate && time === clearHours(this.minDate);
             cell.end = this.maxDate && time === clearHours(this.maxDate);
@@ -135,14 +148,14 @@
               cell.type = 'today';
             }
 
-            if (i === 0) {
-              if (j >= day) {
+            if (i >= 0 && i <= 1) {
+              if (j + i * 7 >= (day + offset)) {
                 cell.text = count++;
                 if (count === 2) {
                   firstDayPosition = i * 7 + j;
                 }
               } else {
-                cell.text = dateCountOfLastMonth - (day - j % 7) + 1;
+                cell.text = dateCountOfLastMonth - (day + offset - j % 7) + 1 + i * 7;
                 cell.type = 'prev-month';
               }
             } else {

+ 2 - 0
packages/date-picker/src/panel/date.vue

@@ -88,6 +88,7 @@
               :value="value"
               :week="week"
               :selection-mode="selectionMode"
+              :first-day-of-week="firstDayOfWeek"
               :disabled-date="disabledDate">
             </date-table>
             <year-table
@@ -377,6 +378,7 @@
         visible: false,
         currentView: 'date',
         disabledDate: '',
+        firstDayOfWeek: 7,
         year: null,
         month: null,
         week: null,

+ 31 - 0
test/unit/specs/date-picker.spec.js

@@ -612,6 +612,37 @@ describe('DatePicker', () => {
     });
   });
 
+  const currentMonth = new Date(new Date().getTime());
+  currentMonth.setDate(1);
+  const FirstDayOfCurrentMonth = currentMonth.getDay();
+  const chineseWeek = ['一', '二', '三', '四', '五', '六', '日'];
+
+  const testWeek = (i) => it('picker-options:firstDayOfWeek ' + i, done => {
+    vm = createTest(DatePicker, {
+      pickerOptions: {
+        firstDayOfWeek: i
+      }
+    }, true);
+
+    const input = vm.$el.querySelector('input');
+
+    input.blur();
+    input.focus();
+
+    setTimeout(_ => {
+      const prevMonthLen = vm.picker.$el.querySelectorAll('.prev-month').length;
+      const firstWeek = vm.picker.$el.querySelector('tr th');
+      const offset = i > 3 ? 7 - i : -i;
+
+      expect(firstWeek.innerText).to.equal(chineseWeek[i - 1]);
+      expect(prevMonthLen - FirstDayOfCurrentMonth).to.equal(offset);
+      done();
+    });
+  });
+  for (var i = 1; i <= 7; i++) {
+    testWeek(i);
+  }
+
   it('picker-options:shortcuts', done => {
     let test;
     vm = createTest(DatePicker, {