mirror of https://github.com/ElemeFE/element
Select: add allow-create
parent
c058beb2be
commit
1942e63453
|
@ -516,8 +516,9 @@
|
||||||
<template>
|
<template>
|
||||||
<el-select
|
<el-select
|
||||||
v-model="value9"
|
v-model="value9"
|
||||||
clearable
|
multiple
|
||||||
filterable
|
filterable
|
||||||
|
allow-create
|
||||||
remote
|
remote
|
||||||
placeholder="请输入关键词"
|
placeholder="请输入关键词"
|
||||||
:remote-method="remoteMethod"
|
:remote-method="remoteMethod"
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
created: Boolean,
|
||||||
disabled: {
|
disabled: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
|
@ -105,7 +106,7 @@
|
||||||
queryChange(query) {
|
queryChange(query) {
|
||||||
// query 里如果有正则中的特殊字符,需要先将这些字符转义
|
// query 里如果有正则中的特殊字符,需要先将这些字符转义
|
||||||
let parsedQuery = query.replace(/(\^|\(|\)|\[|\]|\$|\*|\+|\.|\?|\\|\{|\}|\|)/g, '\\$1');
|
let parsedQuery = query.replace(/(\^|\(|\)|\[|\]|\$|\*|\+|\.|\?|\\|\{|\}|\|)/g, '\\$1');
|
||||||
this.visible = new RegExp(parsedQuery, 'i').test(this.currentLabel);
|
this.visible = new RegExp(parsedQuery, 'i').test(this.currentLabel) || this.created;
|
||||||
if (!this.visible) {
|
if (!this.visible) {
|
||||||
this.parent.filteredOptionsCount--;
|
this.parent.filteredOptionsCount--;
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,10 +63,18 @@
|
||||||
<el-select-menu
|
<el-select-menu
|
||||||
ref="popper"
|
ref="popper"
|
||||||
v-show="visible && emptyText !== false">
|
v-show="visible && emptyText !== false">
|
||||||
<ul class="el-select-dropdown__list" v-show="options.length > 0 && filteredOptionsCount > 0 && !loading">
|
<ul
|
||||||
|
class="el-select-dropdown__list"
|
||||||
|
:class="{ 'is-empty': !allowCreate && filteredOptionsCount === 0 }"
|
||||||
|
v-show="options.length > 0 && !loading">
|
||||||
|
<el-option
|
||||||
|
:value="query"
|
||||||
|
created
|
||||||
|
v-if="showNewOption">
|
||||||
|
</el-option>
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
</ul>
|
</ul>
|
||||||
<p class="el-select-dropdown__empty" v-if="emptyText">{{ emptyText }}</p>
|
<p class="el-select-dropdown__empty" v-if="emptyText && !allowCreate">{{ emptyText }}</p>
|
||||||
</el-select-menu>
|
</el-select-menu>
|
||||||
</transition>
|
</transition>
|
||||||
</div>
|
</div>
|
||||||
|
@ -132,6 +140,11 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
showNewOption() {
|
||||||
|
let hasExistingOption = this.options.filter(option => !option.created).some(option => option.currentLabel === this.query);
|
||||||
|
return this.filterable && this.allowCreate && this.query !== '' && !hasExistingOption;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -149,6 +162,7 @@
|
||||||
disabled: Boolean,
|
disabled: Boolean,
|
||||||
clearable: Boolean,
|
clearable: Boolean,
|
||||||
filterable: Boolean,
|
filterable: Boolean,
|
||||||
|
allowCreate: Boolean,
|
||||||
loading: Boolean,
|
loading: Boolean,
|
||||||
remote: Boolean,
|
remote: Boolean,
|
||||||
remoteMethod: Function,
|
remoteMethod: Function,
|
||||||
|
@ -183,6 +197,7 @@
|
||||||
query: '',
|
query: '',
|
||||||
voidRemoteQuery: false,
|
voidRemoteQuery: false,
|
||||||
bottomOverflowBeforeHidden: 0,
|
bottomOverflowBeforeHidden: 0,
|
||||||
|
topOverflowBeforeHidden: 0,
|
||||||
optionsAllDisabled: false,
|
optionsAllDisabled: false,
|
||||||
inputHovering: false,
|
inputHovering: false,
|
||||||
currentPlaceholder: ''
|
currentPlaceholder: ''
|
||||||
|
@ -204,7 +219,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.selected = this.getSelected();
|
this.selected = this.getSelected();
|
||||||
if (this.filterable) {
|
if (this.filterable && !this.multiple) {
|
||||||
this.inputLength = 20;
|
this.inputLength = 20;
|
||||||
}
|
}
|
||||||
this.$emit('change', val);
|
this.$emit('change', val);
|
||||||
|
@ -213,6 +228,7 @@
|
||||||
|
|
||||||
query(val) {
|
query(val) {
|
||||||
this.broadcast('ElSelectDropdown', 'updatePopper');
|
this.broadcast('ElSelectDropdown', 'updatePopper');
|
||||||
|
this.hoverIndex = -1;
|
||||||
if (this.multiple && this.filterable) {
|
if (this.multiple && this.filterable) {
|
||||||
this.resetInputHeight();
|
this.resetInputHeight();
|
||||||
}
|
}
|
||||||
|
@ -244,7 +260,10 @@
|
||||||
this.resetHoverIndex();
|
this.resetHoverIndex();
|
||||||
if (!this.multiple) {
|
if (!this.multiple) {
|
||||||
if (this.dropdownUl && this.selected && this.selected.$el) {
|
if (this.dropdownUl && this.selected && this.selected.$el) {
|
||||||
this.bottomOverflowBeforeHidden = this.selected.$el.getBoundingClientRect().bottom - this.$refs.popper.$el.getBoundingClientRect().bottom;
|
let selectedRect = this.selected.$el.getBoundingClientRect();
|
||||||
|
let popperRect = this.$refs.popper.$el.getBoundingClientRect();
|
||||||
|
this.bottomOverflowBeforeHidden = selectedRect.bottom - popperRect.bottom;
|
||||||
|
this.topOverflowBeforeHidden = selectedRect.top - popperRect.top;
|
||||||
}
|
}
|
||||||
if (this.selected && this.selected.value) {
|
if (this.selected && this.selected.value) {
|
||||||
this.selectedLabel = this.selected.currentLabel;
|
this.selectedLabel = this.selected.currentLabel;
|
||||||
|
@ -270,7 +289,13 @@
|
||||||
}
|
}
|
||||||
if (!this.multiple && this.dropdownUl) {
|
if (!this.multiple && this.dropdownUl) {
|
||||||
if (this.bottomOverflowBeforeHidden > 0) {
|
if (this.bottomOverflowBeforeHidden > 0) {
|
||||||
this.dropdownUl.scrollTop += this.bottomOverflowBeforeHidden;
|
this.$nextTick(() => {
|
||||||
|
this.dropdownUl.scrollTop += this.bottomOverflowBeforeHidden;
|
||||||
|
});
|
||||||
|
} else if (this.topOverflowBeforeHidden < 0) {
|
||||||
|
this.$nextTick(() => {
|
||||||
|
this.dropdownUl.scrollTop += this.topOverflowBeforeHidden;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -290,18 +315,20 @@
|
||||||
getSelected() {
|
getSelected() {
|
||||||
if (this.multiple) {
|
if (this.multiple) {
|
||||||
let result = [];
|
let result = [];
|
||||||
this.value.forEach(value => {
|
if (Array.isArray(this.value)) {
|
||||||
let option = this.options.filter(option => option.value === value)[0];
|
this.value.forEach(value => {
|
||||||
if (option) {
|
let option = this.options.filter(option => option.value === value)[0];
|
||||||
result.push(option);
|
if (option) {
|
||||||
} else {
|
result.push(option);
|
||||||
result.push({
|
} else {
|
||||||
value: this.value,
|
result.push({
|
||||||
currentLabel: value,
|
value: this.value,
|
||||||
hitState: false
|
currentLabel: value,
|
||||||
});
|
hitState: false
|
||||||
}
|
});
|
||||||
});
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
let option = this.options.filter(option => option.value === this.value)[0] ||
|
let option = this.options.filter(option => option.value === this.value)[0] ||
|
||||||
|
@ -405,6 +432,11 @@
|
||||||
} else if (this.multipleLimit <= 0 || this.value.length < this.multipleLimit) {
|
} else if (this.multipleLimit <= 0 || this.value.length < this.multipleLimit) {
|
||||||
this.value.push(option.value);
|
this.value.push(option.value);
|
||||||
}
|
}
|
||||||
|
if (option.created) {
|
||||||
|
this.query = '';
|
||||||
|
this.inputLength = 20;
|
||||||
|
this.$refs.input.focus();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -422,6 +454,7 @@
|
||||||
this.visible = true;
|
this.visible = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (this.options.length === 0 || this.filteredOptionsCount === 0) return;
|
||||||
if (!this.optionsAllDisabled) {
|
if (!this.optionsAllDisabled) {
|
||||||
if (direction === 'next') {
|
if (direction === 'next') {
|
||||||
this.hoverIndex++;
|
this.hoverIndex++;
|
||||||
|
@ -483,7 +516,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
onInputChange() {
|
onInputChange() {
|
||||||
if (this.filterable && this.selectedLabel !== this.value) {
|
if (this.filterable) {
|
||||||
this.query = this.selectedLabel;
|
this.query = this.selectedLabel;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -51,5 +51,9 @@
|
||||||
max-height: var(--select-dropdown-max-height);
|
max-height: var(--select-dropdown-max-height);
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
@when empty {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue