Merge pull request #3579 from SergioCrisostomo/refactor-select
more select improvements
This commit is contained in:
commit
930b85838e
3 changed files with 47 additions and 13 deletions
|
@ -671,16 +671,16 @@
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<Select v-model="model1" size="small" style="width:200px;">
|
<Select v-model="model1" size="small" style="width:200px;" >
|
||||||
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
||||||
</Select>
|
</Select>
|
||||||
<Select v-model="model10" size="small" multiple style="width:260px">
|
<Select v-model="model10" size="small" multiple style="width:260px" >
|
||||||
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
||||||
</Select>
|
</Select>
|
||||||
|
|
||||||
<br><br>
|
<br><br>
|
||||||
|
|
||||||
<Select v-model="model1" size="large" style="width:200px">
|
<Select v-model="model1" size="large" style="width:200px" clearable @on-clear="onClear">
|
||||||
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
||||||
</Select>
|
</Select>
|
||||||
<Select v-model="model10" size="large" multiple style="width:260px">
|
<Select v-model="model10" size="large" multiple style="width:260px">
|
||||||
|
@ -761,6 +761,11 @@
|
||||||
model10: [],
|
model10: [],
|
||||||
model11: []
|
model11: []
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClear(){
|
||||||
|
console.log('onClear');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
@blur="onInputFocus"
|
@blur="onInputFocus"
|
||||||
|
|
||||||
ref="input">
|
ref="input">
|
||||||
<Icon type="ios-close" :class="[prefixCls + '-arrow']" v-if="resetSelect" @click.native.stop="resetSelect"></Icon>
|
<Icon type="ios-close" :class="[prefixCls + '-arrow']" v-if="resetSelect" @click.native.stop="onClear"></Icon>
|
||||||
<Icon type="arrow-down-b" :class="[prefixCls + '-arrow']" v-if="!resetSelect && !remote && !disabled"></Icon>
|
<Icon type="arrow-down-b" :class="[prefixCls + '-arrow']" v-if="!resetSelect && !remote && !disabled"></Icon>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -165,6 +165,9 @@
|
||||||
if (this.filterable && e.target === this.$el){
|
if (this.filterable && e.target === this.$el){
|
||||||
this.$refs.input.focus();
|
this.$refs.input.focus();
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
onClear(){
|
||||||
|
this.$emit('on-clear');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -179,6 +182,7 @@
|
||||||
// #982
|
// #982
|
||||||
if (typeof value === 'undefined' || value === '' || value === null) this.query = '';
|
if (typeof value === 'undefined' || value === '' || value === null) this.query = '';
|
||||||
else this.query = value.label;
|
else this.query = value.label;
|
||||||
|
this.$nextTick(() => this.preventRemoteCall = false); // this should be after the query change setter above
|
||||||
},
|
},
|
||||||
query (val) {
|
query (val) {
|
||||||
if (this.preventRemoteCall) {
|
if (this.preventRemoteCall) {
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
@on-query-change="onQueryChange"
|
@on-query-change="onQueryChange"
|
||||||
@on-input-focus="isFocused = true"
|
@on-input-focus="isFocused = true"
|
||||||
@on-input-blur="isFocused = false"
|
@on-input-blur="isFocused = false"
|
||||||
|
@on-clear="clearSingleSelect"
|
||||||
/>
|
/>
|
||||||
</slot>
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
@ -121,6 +122,8 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const ANIMATION_TIMEOUT = 300;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'iSelect',
|
name: 'iSelect',
|
||||||
mixins: [ Emitter, Locale ],
|
mixins: [ Emitter, Locale ],
|
||||||
|
@ -229,6 +232,7 @@
|
||||||
slotOptions: this.$slots.default,
|
slotOptions: this.$slots.default,
|
||||||
caretPosition: -1,
|
caretPosition: -1,
|
||||||
lastRemoteQuery: '',
|
lastRemoteQuery: '',
|
||||||
|
unchangedQuery: true,
|
||||||
hasExpectedValue: false,
|
hasExpectedValue: false,
|
||||||
preventRemoteCall: false,
|
preventRemoteCall: false,
|
||||||
};
|
};
|
||||||
|
@ -260,6 +264,12 @@
|
||||||
[`${prefixCls}-selection-focused`]: this.isFocused
|
[`${prefixCls}-selection-focused`]: this.isFocused
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
queryStringMatchesSelectedOption(){
|
||||||
|
const selectedOptions = this.values[0];
|
||||||
|
if (!selectedOptions) return false;
|
||||||
|
const [query, label] = [this.query, selectedOptions.label].map(str => (str || '').trim());
|
||||||
|
return !this.multiple && this.unchangedQuery && query === label;
|
||||||
|
},
|
||||||
localeNotFoundText () {
|
localeNotFoundText () {
|
||||||
if (typeof this.notFoundText === 'undefined') {
|
if (typeof this.notFoundText === 'undefined') {
|
||||||
return this.t('i.select.noMatch');
|
return this.t('i.select.noMatch');
|
||||||
|
@ -382,6 +392,8 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
clearSingleSelect(){ // PUBLIC API
|
clearSingleSelect(){ // PUBLIC API
|
||||||
|
this.$emit('on-clear');
|
||||||
|
this.hideMenu();
|
||||||
if (this.clearable) this.values = [];
|
if (this.clearable) this.values = [];
|
||||||
},
|
},
|
||||||
getOptionData(value){
|
getOptionData(value){
|
||||||
|
@ -423,18 +435,19 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
validateOption({elm, propsData}){
|
validateOption({elm, propsData}){
|
||||||
|
if (this.queryStringMatchesSelectedOption) return true;
|
||||||
const value = propsData.value;
|
const value = propsData.value;
|
||||||
const label = propsData.label || '';
|
const label = propsData.label || '';
|
||||||
const textContent = elm && elm.textContent || '';
|
const textContent = elm && elm.textContent || '';
|
||||||
const stringValues = JSON.stringify([value, label, textContent]);
|
const stringValues = JSON.stringify([value, label, textContent]);
|
||||||
return stringValues.toLowerCase().includes(this.query.toLowerCase());
|
const query = this.query.toLowerCase().trim();
|
||||||
|
return stringValues.toLowerCase().includes(query);
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleMenu (e, force) {
|
toggleMenu (e, force) {
|
||||||
if (this.disabled || this.autoComplete) {
|
if (this.disabled || this.autoComplete) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
this.focusIndex = -1;
|
|
||||||
|
|
||||||
this.visible = typeof force !== 'undefined' ? force : !this.visible;
|
this.visible = typeof force !== 'undefined' ? force : !this.visible;
|
||||||
if (this.visible){
|
if (this.visible){
|
||||||
|
@ -444,6 +457,7 @@
|
||||||
},
|
},
|
||||||
hideMenu () {
|
hideMenu () {
|
||||||
this.toggleMenu(null, false);
|
this.toggleMenu(null, false);
|
||||||
|
setTimeout(() => this.unchangedQuery = true, ANIMATION_TIMEOUT);
|
||||||
},
|
},
|
||||||
onClickOutside(event){
|
onClickOutside(event){
|
||||||
if (this.visible) {
|
if (this.visible) {
|
||||||
|
@ -467,6 +481,7 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
reset(){
|
reset(){
|
||||||
|
this.unchangedQuery = true;
|
||||||
this.values = [];
|
this.values = [];
|
||||||
},
|
},
|
||||||
handleKeydown (e) {
|
handleKeydown (e) {
|
||||||
|
@ -551,11 +566,17 @@
|
||||||
|
|
||||||
this.isFocused = true; // so we put back focus after clicking with mouse on option elements
|
this.isFocused = true; // so we put back focus after clicking with mouse on option elements
|
||||||
} else {
|
} else {
|
||||||
|
this.query = String(option.label).trim();
|
||||||
this.values = [option];
|
this.values = [option];
|
||||||
this.lastRemoteQuery = '';
|
this.lastRemoteQuery = '';
|
||||||
this.hideMenu();
|
this.hideMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.focusIndex = this.flatOptions.findIndex((opt) => {
|
||||||
|
if (!opt || !opt.componentOptions) return false;
|
||||||
|
return opt.componentOptions.propsData.value === option.value;
|
||||||
|
});
|
||||||
|
|
||||||
if (this.filterable){
|
if (this.filterable){
|
||||||
const inputField = this.$el.querySelector('input[type="text"]');
|
const inputField = this.$el.querySelector('input[type="text"]');
|
||||||
if (!this.autoComplete) this.$nextTick(() => inputField.focus());
|
if (!this.autoComplete) this.$nextTick(() => inputField.focus());
|
||||||
|
@ -563,8 +584,9 @@
|
||||||
this.broadcast('Drop', 'on-update-popper');
|
this.broadcast('Drop', 'on-update-popper');
|
||||||
},
|
},
|
||||||
onQueryChange(query) {
|
onQueryChange(query) {
|
||||||
|
if (query.length > 0 && query !== this.query) this.visible = true;
|
||||||
this.query = query;
|
this.query = query;
|
||||||
if (this.query.length > 0) this.visible = true;
|
this.unchangedQuery = this.visible;
|
||||||
},
|
},
|
||||||
toggleHeaderFocus({type}){
|
toggleHeaderFocus({type}){
|
||||||
if (this.disabled) {
|
if (this.disabled) {
|
||||||
|
@ -632,7 +654,7 @@
|
||||||
// restore query value in filterable single selects
|
// restore query value in filterable single selects
|
||||||
const [selectedOption] = this.values;
|
const [selectedOption] = this.values;
|
||||||
if (selectedOption && this.filterable && !this.multiple && !focused){
|
if (selectedOption && this.filterable && !this.multiple && !focused){
|
||||||
const selectedLabel = selectedOption.label || selectedOption.value;
|
const selectedLabel = String(selectedOption.label || selectedOption.value).trim();
|
||||||
if (selectedLabel && this.query !== selectedLabel) {
|
if (selectedLabel && this.query !== selectedLabel) {
|
||||||
this.preventRemoteCall = true;
|
this.preventRemoteCall = true;
|
||||||
this.query = selectedLabel;
|
this.query = selectedLabel;
|
||||||
|
@ -668,6 +690,9 @@
|
||||||
if (this.slotOptions && this.slotOptions.length === 0){
|
if (this.slotOptions && this.slotOptions.length === 0){
|
||||||
this.query = '';
|
this.query = '';
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
visible(state){
|
||||||
|
this.$emit('on-open-change', state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue