Skip to content

Commit

Permalink
date-picker: refactor type='dates'
Browse files Browse the repository at this point in the history
fix issue ElemeFE#12323
{month, year} table highlights all selected dates
nuke selectedDates to provide cleaner data flow
  • Loading branch information
wacky6 committed Aug 13, 2018
1 parent 72349e1 commit ed130bf
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 49 deletions.
40 changes: 18 additions & 22 deletions packages/date-picker/src/basic/date-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
import { getFirstDayOfMonth, getDayCountOfMonth, getWeekNumber, getStartDateOfMonth, nextDate, isDate } from '../util';
import { hasClass } from 'element-ui/src/utils/dom';
import Locale from 'element-ui/src/mixins/locale';
import { arrayFindIndex, arrayFind, coerceTruthyValueToArray } from 'element-ui/src/utils/util';
const WEEKS = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
const clearHours = function(time) {
Expand All @@ -43,6 +44,14 @@
return cloneDate.getTime();
};
// remove the first element that satisfies `pred` from arr
// return a new array if modification occurs
// return the original array otherwise
const removeFromArray = function(arr, pred) {
const idx = typeof pred === 'function' ? arrayFindIndex(arr, pred) : arr.indexOf(pred);
return idx >= 0 ? [...arr.slice(0, idx), ...arr.slice(idx + 1)] : arr;
};
export default {
mixins: [Locale],
Expand Down Expand Up @@ -75,10 +84,6 @@
disabledDate: {},
selectedDate: {
type: Array
},
minDate: {},
maxDate: {},
Expand Down Expand Up @@ -135,7 +140,7 @@
const startDate = this.startDate;
const disabledDate = this.disabledDate;
const selectedDate = this.selectedDate || this.value;
const selectedDate = this.selectionMode === 'dates' ? coerceTruthyValueToArray(this.value) : [];
const now = clearHours(new Date());
for (let i = 0; i < 6; i++) {
Expand Down Expand Up @@ -188,10 +193,9 @@
}
}
let newDate = new Date(time);
cell.disabled = typeof disabledDate === 'function' && disabledDate(newDate);
cell.selected = Array.isArray(selectedDate) &&
selectedDate.filter(date => date.toString() === newDate.toString())[0];
let cellDate = new Date(time);
cell.disabled = typeof disabledDate === 'function' && disabledDate(cellDate);
cell.selected = arrayFind(selectedDate, date => date.getTime() === cellDate.getTime());
this.$set(row, this.showWeekNumber ? j + 1 : j, cell);
}
Expand Down Expand Up @@ -483,19 +487,11 @@
date: newDate
});
} else if (selectionMode === 'dates') {
let selectedDate = this.selectedDate;
if (!cell.selected) {
selectedDate.push(newDate);
} else {
selectedDate.forEach((date, index) => {
if (date.toString() === newDate.toString()) {
selectedDate.splice(index, 1);
}
});
}
this.$emit('select', selectedDate);
const value = this.value || [];
const newValue = cell.selected
? removeFromArray(value, date => date.getTime() === newDate.getTime())
: [...value, newDate];
this.$emit('pick', newValue);
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion packages/date-picker/src/basic/month-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import Locale from 'element-ui/src/mixins/locale';
import { isDate, range, getDayCountOfMonth, nextDate } from '../util';
import { hasClass } from 'element-ui/src/utils/dom';
import { arrayFindIndex, coerceTruthyValueToArray } from 'element-ui/src/utils/util';
const datesInMonth = (year, month) => {
const numOfDays = getDayCountOfMonth(year, month);
Expand Down Expand Up @@ -80,7 +81,7 @@
style.disabled = typeof this.disabledDate === 'function'
? datesInMonth(year, month).every(this.disabledDate)
: false;
style.current = this.value.getFullYear() === year && this.value.getMonth() === month;
style.current = arrayFindIndex(coerceTruthyValueToArray(this.value), date => date.getFullYear() === year && date.getMonth() === month) >= 0;
style.today = today.getFullYear() === year && today.getMonth() === month;
style.default = this.defaultValue &&
this.defaultValue.getFullYear() === year &&
Expand Down
3 changes: 2 additions & 1 deletion packages/date-picker/src/basic/year-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<script type="text/babel">
import { hasClass } from 'element-ui/src/utils/dom';
import { isDate, range, nextDate, getDayCountOfYear } from '../util';
import { arrayFindIndex, coerceTruthyValueToArray } from 'element-ui/src/utils/util';
const datesInYear = year => {
const numOfDays = getDayCountOfYear(year);
Expand Down Expand Up @@ -80,7 +81,7 @@
style.disabled = typeof this.disabledDate === 'function'
? datesInYear(year).every(this.disabledDate)
: false;
style.current = this.value.getFullYear() === year;
style.current = arrayFindIndex(coerceTruthyValueToArray(this.value), date => date.getFullYear() === year) >= 0;
style.today = today.getFullYear() === year;
style.default = this.defaultValue && this.defaultValue.getFullYear() === year;
Expand Down
21 changes: 7 additions & 14 deletions packages/date-picker/src/panel/date.vue
Original file line number Diff line number Diff line change
Expand Up @@ -91,27 +91,25 @@
<date-table
v-show="currentView === 'date'"
@pick="handleDatePick"
@select="handleDateSelect"
:selection-mode="selectionMode"
:first-day-of-week="firstDayOfWeek"
:value="new Date(value)"
:value="value"
:default-value="defaultValue ? new Date(defaultValue) : null"
:date="date"
:disabled-date="disabledDate"
:selected-date="selectedDate">
:disabled-date="disabledDate">
</date-table>
<year-table
v-show="currentView === 'year'"
@pick="handleYearPick"
:value="new Date(value)"
:value="value"
:default-value="defaultValue ? new Date(defaultValue) : null"
:date="date"
:disabled-date="disabledDate">
</year-table>
<month-table
v-show="currentView === 'month'"
@pick="handleMonthPick"
:value="new Date(value)"
:value="value"
:default-value="defaultValue ? new Date(defaultValue) : null"
:date="date"
:disabled-date="disabledDate">
Expand Down Expand Up @@ -333,12 +331,6 @@
}
},
handleDateSelect(value) {
if (this.selectionMode === 'dates') {
this.selectedDate = value;
}
},
handleDatePick(value) {
if (this.selectionMode === 'day') {
this.date = this.value
Expand All @@ -347,6 +339,8 @@
this.emit(this.date, this.showTime);
} else if (this.selectionMode === 'week') {
this.emit(value.date);
} else if (this.selectionMode === 'dates') {
this.emit(value, true); // set false to keep panel open
}
},
Expand All @@ -373,7 +367,7 @@
confirm() {
if (this.selectionMode === 'dates') {
this.emit(this.selectedDate);
this.emit(this.value);
} else {
// value were emitted in handle{Date,Time}Pick, nothing to update here
// deal with the scenario where: user opens the picker, then confirm without doing anything
Expand Down Expand Up @@ -506,7 +500,6 @@
visible: false,
currentView: 'date',
disabledDate: '',
selectedDate: [],
firstDayOfWeek: 7,
showWeekNumber: false,
timePickerVisible: false,
Expand Down
16 changes: 5 additions & 11 deletions packages/date-picker/src/picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,6 @@ export default {
handler(val) {
if (this.picker) {
this.picker.value = val;
this.picker.selectedDate = Array.isArray(val) ? val : [];
}
}
},
Expand Down Expand Up @@ -705,15 +704,11 @@ export default {
handleClose() {
if (!this.pickerVisible) return;
this.pickerVisible = false;
const {
type,
valueOnOpen,
valueFormat,
rangeSeparator
} = this;
if (type === 'dates' && this.picker) {
this.picker.selectedDate = parseAsFormatAndType(valueOnOpen, valueFormat, type, rangeSeparator) || valueOnOpen;
this.emitInput(this.picker.selectedDate);
if (this.type === 'dates') {
// restore to former value
const oldValue = parseAsFormatAndType(this.valueOnOpen, this.valueFormat, this.type, this.rangeSeparator) || this.valueOnOpen;
this.emitInput(oldValue);
}
},
Expand Down Expand Up @@ -828,7 +823,6 @@ export default {
this.picker.selectionMode = this.selectionMode;
this.picker.unlinkPanels = this.unlinkPanels;
this.picker.arrowControl = this.arrowControl || this.timeArrowControl || false;
this.picker.selectedDate = Array.isArray(this.value) && this.value || [];
this.$watch('format', (format) => {
this.picker.format = format;
});
Expand Down
26 changes: 26 additions & 0 deletions src/utils/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,3 +84,29 @@ export const valueEquals = (a, b) => {
};

export const escapeRegexpString = (value = '') => String(value).replace(/[|\\{}()[\]^$+*?.]/g, '\\$&');

// TODO: use native Array.find, Array.findIndex when IE support is dropped
export const arrayFindIndex = function(arr, pred) {
for (let i = 0; i !== arr.length; ++i) {
if (pred(arr[i])) {
return i;
}
}
return -1;
};

export const arrayFind = function(arr, pred) {
const idx = arrayFindIndex(arr, pred);
return idx !== -1 ? arr[idx] : undefined;
};

// coerce truthy value to array
export const coerceTruthyValueToArray = function(val) {
if (Array.isArray(val)) {
return val;
} else if (val) {
return [val];
} else {
return [];
}
};

0 comments on commit ed130bf

Please sign in to comment.