Select: add allow-create

pull/1401/head
Leopoldthecoder 2016-11-29 23:11:33 +08:00
parent c058beb2be
commit 1942e63453
4 changed files with 59 additions and 20 deletions

View File

@ -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"

View File

@ -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--;
} }

View File

@ -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;
} }
}, },

View File

@ -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;
}
} }
} }