Skip to content

Commit

Permalink
DatePicker: add months And years type (ElemeFE#21918)
Browse files Browse the repository at this point in the history
  • Loading branch information
tianchao1995 authored and hzsrc committed Feb 2, 2023
1 parent 6ec474e commit 43f07a6
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 19 deletions.
24 changes: 22 additions & 2 deletions examples/docs/en-US/date-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,24 @@ You can choose week, month, year or multiple dates by extending the standard dat
</el-date-picker>
</div>
</div>
<div class="container">
<div class="block">
<span class="demonstration">months</span>
<el-date-picker
type="months"
v-model="value5"
placeholder="Pick one or more months">
</el-date-picker>
</div>
<div class="block">
<span class="demonstration">years</span>
<el-date-picker
type="years"
v-model="value6"
placeholder="Pick one or more years">
</el-date-picker>
</div>
</div>

<script>
export default {
Expand All @@ -120,7 +138,9 @@ You can choose week, month, year or multiple dates by extending the standard dat
value1: '',
value2: '',
value3: '',
value4: ''
value4: '',
value5: '',
value6: ''
};
}
};
Expand Down Expand Up @@ -442,7 +462,7 @@ When picking a date range, you can assign the time part for start date and end d
| placeholder | placeholder in non-range mode | string |||
| start-placeholder | placeholder for the start date in range mode | string |||
| end-placeholder | placeholder for the end date in range mode | string |||
| type | type of the picker | string | year/month/date/dates/datetime/ week/datetimerange/daterange/ monthrange | date |
| type | type of the picker | string | year/month/date/dates/months/years/datetime/ week/datetimerange/daterange/ monthrange | date |
| format | format of the displayed value in the input box | string | see [date formats](#/en-US/component/date-picker#date-formats) | yyyy-MM-dd |
| align | alignment | left/center/right | left |
| popper-class | custom class name for DatePicker's dropdown | string |||
Expand Down
24 changes: 22 additions & 2 deletions examples/docs/es/date-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,24 @@ Puede elegir la semana, el mes, el año o varias fechas ampliando el componente
</el-date-picker>
</div>
</div>
<div class="container">
<div class="block">
<span class="demonstration">months</span>
<el-date-picker
type="months"
v-model="value5"
placeholder="Pick one or more months">
</el-date-picker>
</div>
<div class="block">
<span class="demonstration">years</span>
<el-date-picker
type="years"
v-model="value6"
placeholder="Pick one or more years">
</el-date-picker>
</div>
</div>

<script>
export default {
Expand All @@ -122,7 +140,9 @@ Puede elegir la semana, el mes, el año o varias fechas ampliando el componente
value1: '',
value2: '',
value3: '',
value4: ''
value4: '',
value5: '',
value6: ''
};
}
};
Expand Down Expand Up @@ -443,7 +463,7 @@ Al seleccionar un intervalo de fechas, puede asignar la hora para la fecha de in
| placeholder | placeholder cuando el modo NO es rango | string |||
| start-placeholder | placeholder para la fecha de inicio en modo rango | string |||
| end-placeholder | placeholder para la fecha final en modo rango | string |||
| type | tipo de picker | string | year/month/date/dates/datetime/ week/datetimerange/daterange/ monthrange | date |
| type | tipo de picker | string | year/month/date/dates/months/years/datetime/ week/datetimerange/daterange/ monthrange | date |
| format | formato en que se muestra el valor en el input | string | ver [date formats](#/es/component/date-picker#date-formats) | yyyy-MM-dd |
| align | alineación | left/center/right | left | |
| popper-class | nombre de clase personalizada para el dropdown de DatePicker | string |||
Expand Down
24 changes: 22 additions & 2 deletions examples/docs/zh-CN/date-picker.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,24 @@
</el-date-picker>
</div>
</div>
<div class="container">
<div class="block">
<span class="demonstration">多个月</span>
<el-date-picker
type="months"
v-model="value5"
placeholder="选择一个或多个月">
</el-date-picker>
</div>
<div class="block">
<span class="demonstration">多个年</span>
<el-date-picker
type="years"
v-model="value6"
placeholder="选择一个或多个年">
</el-date-picker>
</div>
</div>

<script>
export default {
Expand All @@ -119,7 +137,9 @@
value1: '',
value2: '',
value3: '',
value4: ''
value4: '',
value5: '',
value6: ''
};
}
};
Expand Down Expand Up @@ -395,7 +415,7 @@
| placeholder | 非范围选择时的占位内容 | string |||
| start-placeholder | 范围选择时开始日期的占位内容 | string |||
| end-placeholder | 范围选择时结束日期的占位内容 | string |||
| type | 显示类型 | string | year/month/date/dates/ week/datetime/datetimerange/ daterange/monthrange | date |
| type | 显示类型 | string | year/month/date/dates/months/years week/datetime/datetimerange/ daterange/monthrange | date |
| format | 显示在输入框中的格式 | string |[日期格式](#/zh-CN/component/date-picker#ri-qi-ge-shi) | yyyy-MM-dd |
| align | 对齐方式 | string | left, center, right | left |
| popper-class | DatePicker 下拉框的类名 | string |||
Expand Down
15 changes: 15 additions & 0 deletions packages/date-picker/src/basic/month-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@
return NaN;
}
};
// 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 {
props: {
disabledDate: {},
Expand Down Expand Up @@ -205,6 +213,13 @@
}
this.rangeState.selecting = false;
}
} else if (this.selectionMode === 'months') {
const value = this.value || [];
const year = this.date.getFullYear();
const newValue = arrayFindIndex(value, date => date.getFullYear() === year && date.getMonth() === month) >= 0
? removeFromArray(value, date => date.getTime() === newDate.getTime())
: [...value, newDate];
this.$emit('pick', newValue);
} else {
this.$emit('pick', month);
}
Expand Down
14 changes: 12 additions & 2 deletions packages/date-picker/src/basic/year-table.vue
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@
return val === null || (val instanceof Date && isDate(val));
}
},
date: {}
date: {},
selectionMode: {}
},
computed: {
Expand Down Expand Up @@ -93,7 +94,16 @@
if (target.tagName === 'A') {
if (hasClass(target.parentNode, 'disabled')) return;
const year = target.textContent || target.innerText;
this.$emit('pick', Number(year));
if (this.selectionMode === 'years') {
const value = this.value || [];
const idx = arrayFindIndex(value, date => date.getFullYear() === Number(year));
const newValue = idx > -1
? [...value.slice(0, idx), ...value.slice(idx + 1)]
: [...value, new Date(year)];
this.$emit('pick', newValue);
} else {
this.$emit('pick', Number(year));
}
}
}
}
Expand Down
24 changes: 18 additions & 6 deletions packages/date-picker/src/panel/date.vue
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@
<year-table
v-show="currentView === 'year'"
@pick="handleYearPick"
:selection-mode="selectionMode"
:value="value"
:default-value="defaultValue ? new Date(defaultValue) : null"
:date="date"
Expand All @@ -110,6 +111,7 @@
<month-table
v-show="currentView === 'month'"
@pick="handleMonthPick"
:selection-mode="selectionMode"
:value="value"
:default-value="defaultValue ? new Date(defaultValue) : null"
:date="date"
Expand All @@ -121,13 +123,13 @@

<div
class="el-picker-panel__footer"
v-show="footerVisible && currentView === 'date'">
v-show="footerVisible && (currentView === 'date' || currentView === 'month' || currentView === 'year')">
<el-button
size="mini"
type="text"
class="el-picker-panel__link-btn"
@click="changeToNow"
v-show="selectionMode !== 'dates'">
v-show="selectionMode !== 'dates' && selectionMode !== 'months' && selectionMode !== 'years'">
{{ t('el.datepicker.now') }}
</el-button>
<el-button
Expand Down Expand Up @@ -190,6 +192,8 @@
value(val) {
if (this.selectionMode === 'dates' && this.value) return;
if (this.selectionMode === 'months' && this.value) return;
if (this.selectionMode === 'years' && this.value) return;
if (isDate(val)) {
this.date = new Date(val);
} else {
Expand All @@ -215,6 +219,10 @@
}
} else if (newVal === 'dates') {
this.currentView = 'date';
} else if (newVal === 'years') {
this.currentView = 'year';
} else if (newVal === 'months') {
this.currentView = 'month';
}
}
},
Expand Down Expand Up @@ -328,6 +336,8 @@
if (this.selectionMode === 'month') {
this.date = modifyDate(this.date, this.year, month, 1);
this.emit(this.date);
} else if (this.selectionMode === 'months') {
this.emit(month, true);
} else {
this.date = changeYearMonthAndClampDate(this.date, this.year, month);
// TODO: should emit intermediate value ??
Expand Down Expand Up @@ -358,6 +368,8 @@
if (this.selectionMode === 'year') {
this.date = modifyDate(this.date, year, 0, 1);
this.emit(this.date);
} else if (this.selectionMode === 'years') {
this.emit(year, true);
} else {
this.date = changeYearMonthAndClampDate(this.date, year, this.month);
// TODO: should emit intermediate value ??
Expand All @@ -376,7 +388,7 @@
},
confirm() {
if (this.selectionMode === 'dates') {
if (this.selectionMode === 'dates' || this.selectionMode === 'months' || this.selectionMode === 'years') {
this.emit(this.value);
} else {
// value were emitted in handle{Date,Time}Pick, nothing to update here
Expand All @@ -390,9 +402,9 @@
},
resetView() {
if (this.selectionMode === 'month') {
if (this.selectionMode === 'month' || this.selectionMode === 'months') {
this.currentView = 'month';
} else if (this.selectionMode === 'year') {
} else if (this.selectionMode === 'year' || this.selectionMode === 'years') {
this.currentView = 'year';
} else {
this.currentView = 'date';
Expand Down Expand Up @@ -546,7 +558,7 @@
},
footerVisible() {
return this.showTime || this.selectionMode === 'dates';
return this.showTime || this.selectionMode === 'dates' || this.selectionMode === 'months' || this.selectionMode === 'years';
},
visibleTime() {
Expand Down
36 changes: 31 additions & 5 deletions packages/date-picker/src/picker.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<el-input
class="el-date-editor"
:class="'el-date-editor--' + type"
:readonly="!editable || readonly || type === 'dates' || type === 'week'"
:readonly="!editable || readonly || type === 'dates' || type === 'week' || type === 'years' || type === 'months'"
:disabled="pickerDisabled"
:size="pickerSize"
:name="name"
Expand Down Expand Up @@ -110,14 +110,16 @@ const NewPopper = {
const DEFAULT_FORMATS = {
date: 'yyyy-MM-dd',
month: 'yyyy-MM',
months: 'yyyy-MM',
datetime: 'yyyy-MM-dd HH:mm:ss',
time: 'HH:mm:ss',
week: 'yyyywWW',
timerange: 'HH:mm:ss',
daterange: 'yyyy-MM-dd',
monthrange: 'yyyy-MM',
datetimerange: 'yyyy-MM-dd HH:mm:ss',
year: 'yyyy'
year: 'yyyy',
years: 'yyyy'
};
const HAVE_TRIGGER_TYPES = [
'date',
Expand All @@ -131,7 +133,9 @@ const HAVE_TRIGGER_TYPES = [
'monthrange',
'timerange',
'datetimerange',
'dates'
'dates',
'months',
'years'
];
const DATE_FORMATTER = function(value, format) {
if (format === 'timestamp') return value.getTime();
Expand Down Expand Up @@ -255,6 +259,24 @@ const TYPE_VALUE_RESOLVER_MAP = {
return (typeof value === 'string' ? value.split(', ') : value)
.map(date => date instanceof Date ? date : DATE_PARSER(date, format));
}
},
months: {
formatter(value, format) {
return value.map(date => DATE_FORMATTER(date, format));
},
parser(value, format) {
return (typeof value === 'string' ? value.split(', ') : value)
.map(date => date instanceof Date ? date : DATE_PARSER(date, format));
}
},
years: {
formatter(value, format) {
return value.map(date => DATE_FORMATTER(date, format));
},
parser(value, format) {
return (typeof value === 'string' ? value.split(', ') : value)
.map(date => date instanceof Date ? date : DATE_PARSER(date, format));
}
}
};
const PLACEMENT_MAP = {
Expand Down Expand Up @@ -490,6 +512,10 @@ export default {
return 'year';
} else if (this.type === 'dates') {
return 'dates';
} else if (this.type === 'months') {
return 'months';
} else if (this.type === 'years') {
return 'years';
}
return 'day';
Expand All @@ -512,7 +538,7 @@ export default {
} else if (this.userInput !== null) {
return this.userInput;
} else if (formattedValue) {
return this.type === 'dates'
return (this.type === 'dates' || this.type === 'years' || this.type === 'months')
? formattedValue.join(', ')
: formattedValue;
} else {
Expand Down Expand Up @@ -714,7 +740,7 @@ export default {
if (!this.pickerVisible) return;
this.pickerVisible = false;
if (this.type === 'dates') {
if (this.type === 'dates' || this.type === 'years' || this.type === 'months') {
// restore to former value
const oldValue = parseAsFormatAndType(this.valueOnOpen, this.valueFormat, this.type, this.rangeSeparator) || this.valueOnOpen;
this.emitInput(oldValue);
Expand Down

0 comments on commit 43f07a6

Please sign in to comment.