Select improvements for edge cases
This commit is contained in:
parent
ece49d8038
commit
9366c9a772
2 changed files with 28 additions and 16 deletions
|
@ -82,7 +82,7 @@
|
||||||
import FunctionalOptions from './functional-options.vue';
|
import FunctionalOptions from './functional-options.vue';
|
||||||
|
|
||||||
const prefixCls = 'ivu-select';
|
const prefixCls = 'ivu-select';
|
||||||
const optionRegexp = /^i-option$|^Option$/;
|
const optionRegexp = /^i-option$|^Option$/i;
|
||||||
const optionGroupRegexp = /option-?group/i;
|
const optionGroupRegexp = /option-?group/i;
|
||||||
|
|
||||||
const findChild = (instance, checkFn) => {
|
const findChild = (instance, checkFn) => {
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
const opts = node.componentOptions;
|
const opts = node.componentOptions;
|
||||||
if (opts && opts.tag.match(optionRegexp)) return [node];
|
if (opts && opts.tag.match(optionRegexp)) return [node];
|
||||||
if (!node.children && (!opts || !opts.children)) return [];
|
if (!node.children && (!opts || !opts.children)) return [];
|
||||||
const children = [...(node.children || []), ...(opts && opts.children || [])];
|
const children = [...(node.children || []), ...(opts && opts.children || [])];
|
||||||
const options = children.reduce(
|
const options = children.reduce(
|
||||||
(arr, el) => [...arr, ...findOptionsInVNode(el)], []
|
(arr, el) => [...arr, ...findOptionsInVNode(el)], []
|
||||||
).filter(Boolean);
|
).filter(Boolean);
|
||||||
|
@ -123,6 +123,18 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const getNestedProperty = (obj, path) => {
|
||||||
|
const keys = path.split('.');
|
||||||
|
return keys.reduce((o, key) => o && o[key] || null, obj);
|
||||||
|
};
|
||||||
|
|
||||||
|
const getOptionLabel = option => {
|
||||||
|
const textContent = (option.componentOptions.children || []).reduce((str, child) => str + (child.text || ''), '');
|
||||||
|
const innerHTML = getNestedProperty(option, 'data.domProps.innerHTML');
|
||||||
|
return option.componentOptions.propsData.label || textContent || (typeof innerHTML === 'string' ? innerHTML : '');
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
const ANIMATION_TIMEOUT = 300;
|
const ANIMATION_TIMEOUT = 300;
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -210,8 +222,11 @@
|
||||||
this.$on('on-select-selected', this.onOptionClick);
|
this.$on('on-select-selected', this.onOptionClick);
|
||||||
|
|
||||||
// set the initial values if there are any
|
// set the initial values if there are any
|
||||||
if (this.values.length > 0 && !this.remote && this.selectOptions.length > 0){
|
if (!this.remote && this.selectOptions.length > 0){
|
||||||
this.values = this.values.map(this.getOptionData).filter(Boolean);
|
this.values = this.getInitialValue().map(value => {
|
||||||
|
if (typeof value !== 'number' && !value) return null;
|
||||||
|
return this.getOptionData(value);
|
||||||
|
}).filter(Boolean);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.values.length > 0 && this.selectOptions.length === 0){
|
if (this.values.length > 0 && this.selectOptions.length === 0){
|
||||||
|
@ -222,7 +237,7 @@
|
||||||
|
|
||||||
return {
|
return {
|
||||||
prefixCls: prefixCls,
|
prefixCls: prefixCls,
|
||||||
values: this.getInitialValue(),
|
values: [],
|
||||||
dropDownWidth: 0,
|
dropDownWidth: 0,
|
||||||
visible: false,
|
visible: false,
|
||||||
focusIndex: -1,
|
focusIndex: -1,
|
||||||
|
@ -400,8 +415,7 @@
|
||||||
getOptionData(value){
|
getOptionData(value){
|
||||||
const option = this.flatOptions.find(({componentOptions}) => componentOptions.propsData.value === value);
|
const option = this.flatOptions.find(({componentOptions}) => componentOptions.propsData.value === value);
|
||||||
if (!option) return null;
|
if (!option) return null;
|
||||||
const textContent = option.componentOptions.children.reduce((str, child) => str + (child.text || ''), '');
|
const label = getOptionLabel(option);
|
||||||
const label = option.componentOptions.propsData.label || textContent || '';
|
|
||||||
return {
|
return {
|
||||||
value: value,
|
value: value,
|
||||||
label: label,
|
label: label,
|
||||||
|
@ -619,14 +633,12 @@
|
||||||
values(now, before){
|
values(now, before){
|
||||||
const newValue = JSON.stringify(now);
|
const newValue = JSON.stringify(now);
|
||||||
const oldValue = JSON.stringify(before);
|
const oldValue = JSON.stringify(before);
|
||||||
const shouldEmitInput = newValue !== oldValue;
|
// v-model is always just the value, event with labelInValue === true
|
||||||
|
const vModelValue = (this.publicValue && this.labelInValue) ?
|
||||||
|
(this.multiple ? this.publicValue.map(({value}) => value) : this.publicValue.value) :
|
||||||
|
this.publicValue;
|
||||||
|
const shouldEmitInput = newValue !== oldValue && vModelValue !== this.value;
|
||||||
if (shouldEmitInput) {
|
if (shouldEmitInput) {
|
||||||
// v-model is always just the value, event with labelInValue === true
|
|
||||||
const vModelValue = this.labelInValue ?
|
|
||||||
(this.multiple ? this.publicValue.map(({value}) => value)
|
|
||||||
:
|
|
||||||
this.publicValue.value) : this.publicValue;
|
|
||||||
this.$emit('input', vModelValue); // to update v-model
|
this.$emit('input', vModelValue); // to update v-model
|
||||||
this.$emit('on-change', this.publicValue);
|
this.$emit('on-change', this.publicValue);
|
||||||
this.dispatch('FormItem', 'on-form-change', this.publicValue);
|
this.dispatch('FormItem', 'on-form-change', this.publicValue);
|
||||||
|
|
|
@ -47,7 +47,7 @@ describe('Select.vue', () => {
|
||||||
waitForIt(
|
waitForIt(
|
||||||
() => {
|
() => {
|
||||||
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
|
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
|
||||||
return selectedValueSpan.textContent === 'Bar';
|
return selectedValueSpan && selectedValueSpan.textContent === 'Bar';
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
|
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
|
||||||
|
@ -121,7 +121,7 @@ describe('Select.vue', () => {
|
||||||
waitForIt(
|
waitForIt(
|
||||||
() => {
|
() => {
|
||||||
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
|
const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
|
||||||
return selectedValueSpan.textContent === 'Bar';
|
return selectedValueSpan && selectedValueSpan.textContent === 'Bar';
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
|
const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');
|
||||||
|
|
Loading…
Add table
Reference in a new issue