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>
|
||||
<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>
|
||||
</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>
|
||||
</Select>
|
||||
|
||||
<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>
|
||||
</Select>
|
||||
<Select v-model="model10" size="large" multiple style="width:260px">
|
||||
|
@ -698,11 +698,11 @@
|
|||
<Select v-model="model10" multiple style="width:260px">
|
||||
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
||||
</Select>
|
||||
|
||||
|
||||
<br><br>
|
||||
|
||||
|
||||
<br><br>
|
||||
|
||||
|
||||
<br><br>
|
||||
<br><br>
|
||||
<br><br>
|
||||
|
@ -713,9 +713,9 @@
|
|||
<Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>
|
||||
</Select>
|
||||
<br><br>
|
||||
|
||||
|
||||
<br><br>
|
||||
|
||||
|
||||
<br><br>
|
||||
<br><br>
|
||||
<br><br>
|
||||
|
@ -761,6 +761,11 @@
|
|||
model10: [],
|
||||
model11: []
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
onClear(){
|
||||
console.log('onClear');
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
@blur="onInputFocus"
|
||||
|
||||
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>
|
||||
</div>
|
||||
</template>
|
||||
|
@ -165,6 +165,9 @@
|
|||
if (this.filterable && e.target === this.$el){
|
||||
this.$refs.input.focus();
|
||||
}
|
||||
},
|
||||
onClear(){
|
||||
this.$emit('on-clear');
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
|
@ -179,6 +182,7 @@
|
|||
// #982
|
||||
if (typeof value === 'undefined' || value === '' || value === null) this.query = '';
|
||||
else this.query = value.label;
|
||||
this.$nextTick(() => this.preventRemoteCall = false); // this should be after the query change setter above
|
||||
},
|
||||
query (val) {
|
||||
if (this.preventRemoteCall) {
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
@on-query-change="onQueryChange"
|
||||
@on-input-focus="isFocused = true"
|
||||
@on-input-blur="isFocused = false"
|
||||
@on-clear="clearSingleSelect"
|
||||
/>
|
||||
</slot>
|
||||
</div>
|
||||
|
@ -121,6 +122,8 @@
|
|||
};
|
||||
};
|
||||
|
||||
const ANIMATION_TIMEOUT = 300;
|
||||
|
||||
export default {
|
||||
name: 'iSelect',
|
||||
mixins: [ Emitter, Locale ],
|
||||
|
@ -229,6 +232,7 @@
|
|||
slotOptions: this.$slots.default,
|
||||
caretPosition: -1,
|
||||
lastRemoteQuery: '',
|
||||
unchangedQuery: true,
|
||||
hasExpectedValue: false,
|
||||
preventRemoteCall: false,
|
||||
};
|
||||
|
@ -260,6 +264,12 @@
|
|||
[`${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 () {
|
||||
if (typeof this.notFoundText === 'undefined') {
|
||||
return this.t('i.select.noMatch');
|
||||
|
@ -382,6 +392,8 @@
|
|||
}
|
||||
},
|
||||
clearSingleSelect(){ // PUBLIC API
|
||||
this.$emit('on-clear');
|
||||
this.hideMenu();
|
||||
if (this.clearable) this.values = [];
|
||||
},
|
||||
getOptionData(value){
|
||||
|
@ -423,18 +435,19 @@
|
|||
},
|
||||
|
||||
validateOption({elm, propsData}){
|
||||
if (this.queryStringMatchesSelectedOption) return true;
|
||||
const value = propsData.value;
|
||||
const label = propsData.label || '';
|
||||
const textContent = elm && elm.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) {
|
||||
if (this.disabled || this.autoComplete) {
|
||||
return false;
|
||||
}
|
||||
this.focusIndex = -1;
|
||||
|
||||
this.visible = typeof force !== 'undefined' ? force : !this.visible;
|
||||
if (this.visible){
|
||||
|
@ -444,6 +457,7 @@
|
|||
},
|
||||
hideMenu () {
|
||||
this.toggleMenu(null, false);
|
||||
setTimeout(() => this.unchangedQuery = true, ANIMATION_TIMEOUT);
|
||||
},
|
||||
onClickOutside(event){
|
||||
if (this.visible) {
|
||||
|
@ -467,6 +481,7 @@
|
|||
}
|
||||
},
|
||||
reset(){
|
||||
this.unchangedQuery = true;
|
||||
this.values = [];
|
||||
},
|
||||
handleKeydown (e) {
|
||||
|
@ -551,11 +566,17 @@
|
|||
|
||||
this.isFocused = true; // so we put back focus after clicking with mouse on option elements
|
||||
} else {
|
||||
this.query = String(option.label).trim();
|
||||
this.values = [option];
|
||||
this.lastRemoteQuery = '';
|
||||
this.hideMenu();
|
||||
}
|
||||
|
||||
this.focusIndex = this.flatOptions.findIndex((opt) => {
|
||||
if (!opt || !opt.componentOptions) return false;
|
||||
return opt.componentOptions.propsData.value === option.value;
|
||||
});
|
||||
|
||||
if (this.filterable){
|
||||
const inputField = this.$el.querySelector('input[type="text"]');
|
||||
if (!this.autoComplete) this.$nextTick(() => inputField.focus());
|
||||
|
@ -563,8 +584,9 @@
|
|||
this.broadcast('Drop', 'on-update-popper');
|
||||
},
|
||||
onQueryChange(query) {
|
||||
if (query.length > 0 && query !== this.query) this.visible = true;
|
||||
this.query = query;
|
||||
if (this.query.length > 0) this.visible = true;
|
||||
this.unchangedQuery = this.visible;
|
||||
},
|
||||
toggleHeaderFocus({type}){
|
||||
if (this.disabled) {
|
||||
|
@ -632,7 +654,7 @@
|
|||
// restore query value in filterable single selects
|
||||
const [selectedOption] = this.values;
|
||||
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) {
|
||||
this.preventRemoteCall = true;
|
||||
this.query = selectedLabel;
|
||||
|
@ -668,6 +690,9 @@
|
|||
if (this.slotOptions && this.slotOptions.length === 0){
|
||||
this.query = '';
|
||||
}
|
||||
},
|
||||
visible(state){
|
||||
this.$emit('on-open-change', state);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue