mirror of https://github.com/ElemeFE/element
DatePicker: add months And years type (#21918)
parent
71268c5bab
commit
d33c4e0c02
|
@ -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 {
|
||||
|
@ -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: ''
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -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 | — | — |
|
||||
|
|
|
@ -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 {
|
||||
|
@ -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: ''
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -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 | — | — |
|
||||
|
|
|
@ -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 {
|
||||
|
@ -119,7 +137,9 @@
|
|||
value1: '',
|
||||
value2: '',
|
||||
value3: '',
|
||||
value4: ''
|
||||
value4: '',
|
||||
value5: '',
|
||||
value6: ''
|
||||
};
|
||||
}
|
||||
};
|
||||
|
@ -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 | — | — |
|
||||
|
|
|
@ -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: {},
|
||||
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -64,7 +64,8 @@
|
|||
return val === null || (val instanceof Date && isDate(val));
|
||||
}
|
||||
},
|
||||
date: {}
|
||||
date: {},
|
||||
selectionMode: {}
|
||||
},
|
||||
|
||||
computed: {
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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';
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -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 ??
|
||||
|
@ -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 ??
|
||||
|
@ -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
|
||||
|
@ -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';
|
||||
|
@ -546,7 +558,7 @@
|
|||
},
|
||||
|
||||
footerVisible() {
|
||||
return this.showTime || this.selectionMode === 'dates';
|
||||
return this.showTime || this.selectionMode === 'dates' || this.selectionMode === 'months' || this.selectionMode === 'years';
|
||||
},
|
||||
|
||||
visibleTime() {
|
||||
|
|
|
@ -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"
|
||||
|
@ -110,6 +110,7 @@ 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',
|
||||
|
@ -117,7 +118,8 @@ const DEFAULT_FORMATS = {
|
|||
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',
|
||||
|
@ -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();
|
||||
|
@ -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 = {
|
||||
|
@ -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';
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue