Commit 801a9c9d6da5cd275b959dd9c61da376814b0055

Authored by Aresn
Committed by GitHub
2 parents d1038fce 9366c9a7

Merge pull request #3739 from SergioCrisostomo/select-patches

Select improvements for edge cases
src/components/select/select.vue
@@ -82,7 +82,7 @@ @@ -82,7 +82,7 @@
82 import FunctionalOptions from './functional-options.vue'; 82 import FunctionalOptions from './functional-options.vue';
83 83
84 const prefixCls = 'ivu-select'; 84 const prefixCls = 'ivu-select';
85 - const optionRegexp = /^i-option$|^Option$/; 85 + const optionRegexp = /^i-option$|^Option$/i;
86 const optionGroupRegexp = /option-?group/i; 86 const optionGroupRegexp = /option-?group/i;
87 87
88 const findChild = (instance, checkFn) => { 88 const findChild = (instance, checkFn) => {
@@ -99,7 +99,7 @@ @@ -99,7 +99,7 @@
99 const opts = node.componentOptions; 99 const opts = node.componentOptions;
100 if (opts && opts.tag.match(optionRegexp)) return [node]; 100 if (opts && opts.tag.match(optionRegexp)) return [node];
101 if (!node.children && (!opts || !opts.children)) return []; 101 if (!node.children && (!opts || !opts.children)) return [];
102 - const children = [...(node.children || []), ...(opts && opts.children || [])]; 102 + const children = [...(node.children || []), ...(opts && opts.children || [])];
103 const options = children.reduce( 103 const options = children.reduce(
104 (arr, el) => [...arr, ...findOptionsInVNode(el)], [] 104 (arr, el) => [...arr, ...findOptionsInVNode(el)], []
105 ).filter(Boolean); 105 ).filter(Boolean);
@@ -123,6 +123,18 @@ @@ -123,6 +123,18 @@
123 }; 123 };
124 }; 124 };
125 125
  126 + const getNestedProperty = (obj, path) => {
  127 + const keys = path.split('.');
  128 + return keys.reduce((o, key) => o && o[key] || null, obj);
  129 + };
  130 +
  131 + const getOptionLabel = option => {
  132 + const textContent = (option.componentOptions.children || []).reduce((str, child) => str + (child.text || ''), '');
  133 + const innerHTML = getNestedProperty(option, 'data.domProps.innerHTML');
  134 + return option.componentOptions.propsData.label || textContent || (typeof innerHTML === 'string' ? innerHTML : '');
  135 + };
  136 +
  137 +
126 const ANIMATION_TIMEOUT = 300; 138 const ANIMATION_TIMEOUT = 300;
127 139
128 export default { 140 export default {
@@ -210,8 +222,11 @@ @@ -210,8 +222,11 @@
210 this.$on('on-select-selected', this.onOptionClick); 222 this.$on('on-select-selected', this.onOptionClick);
211 223
212 // set the initial values if there are any 224 // set the initial values if there are any
213 - if (this.values.length > 0 && !this.remote && this.selectOptions.length > 0){  
214 - this.values = this.values.map(this.getOptionData).filter(Boolean); 225 + if (!this.remote && this.selectOptions.length > 0){
  226 + this.values = this.getInitialValue().map(value => {
  227 + if (typeof value !== 'number' && !value) return null;
  228 + return this.getOptionData(value);
  229 + }).filter(Boolean);
215 } 230 }
216 231
217 if (this.values.length > 0 && this.selectOptions.length === 0){ 232 if (this.values.length > 0 && this.selectOptions.length === 0){
@@ -222,7 +237,7 @@ @@ -222,7 +237,7 @@
222 237
223 return { 238 return {
224 prefixCls: prefixCls, 239 prefixCls: prefixCls,
225 - values: this.getInitialValue(), 240 + values: [],
226 dropDownWidth: 0, 241 dropDownWidth: 0,
227 visible: false, 242 visible: false,
228 focusIndex: -1, 243 focusIndex: -1,
@@ -400,8 +415,7 @@ @@ -400,8 +415,7 @@
400 getOptionData(value){ 415 getOptionData(value){
401 const option = this.flatOptions.find(({componentOptions}) => componentOptions.propsData.value === value); 416 const option = this.flatOptions.find(({componentOptions}) => componentOptions.propsData.value === value);
402 if (!option) return null; 417 if (!option) return null;
403 - const textContent = option.componentOptions.children.reduce((str, child) => str + (child.text || ''), '');  
404 - const label = option.componentOptions.propsData.label || textContent || ''; 418 + const label = getOptionLabel(option);
405 return { 419 return {
406 value: value, 420 value: value,
407 label: label, 421 label: label,
@@ -621,14 +635,12 @@ @@ -621,14 +635,12 @@
621 values(now, before){ 635 values(now, before){
622 const newValue = JSON.stringify(now); 636 const newValue = JSON.stringify(now);
623 const oldValue = JSON.stringify(before); 637 const oldValue = JSON.stringify(before);
624 - const shouldEmitInput = newValue !== oldValue;  
625 - 638 + // v-model is always just the value, event with labelInValue === true
  639 + const vModelValue = (this.publicValue && this.labelInValue) ?
  640 + (this.multiple ? this.publicValue.map(({value}) => value) : this.publicValue.value) :
  641 + this.publicValue;
  642 + const shouldEmitInput = newValue !== oldValue && vModelValue !== this.value;
626 if (shouldEmitInput) { 643 if (shouldEmitInput) {
627 - // v-model is always just the value, event with labelInValue === true  
628 - const vModelValue = this.labelInValue ?  
629 - (this.multiple ? this.publicValue.map(({value}) => value)  
630 - :  
631 - this.publicValue.value) : this.publicValue;  
632 this.$emit('input', vModelValue); // to update v-model 644 this.$emit('input', vModelValue); // to update v-model
633 this.$emit('on-change', this.publicValue); 645 this.$emit('on-change', this.publicValue);
634 this.dispatch('FormItem', 'on-form-change', this.publicValue); 646 this.dispatch('FormItem', 'on-form-change', this.publicValue);
test/unit/specs/select.spec.js
@@ -47,7 +47,7 @@ describe('Select.vue', () => { @@ -47,7 +47,7 @@ describe('Select.vue', () => {
47 waitForIt( 47 waitForIt(
48 () => { 48 () => {
49 const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value'); 49 const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
50 - return selectedValueSpan.textContent === 'Bar'; 50 + return selectedValueSpan && selectedValueSpan.textContent === 'Bar';
51 }, 51 },
52 () => { 52 () => {
53 const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value'); 53 const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
@@ -121,7 +121,7 @@ describe('Select.vue', () => { @@ -121,7 +121,7 @@ describe('Select.vue', () => {
121 waitForIt( 121 waitForIt(
122 () => { 122 () => {
123 const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value'); 123 const selectedValueSpan = vm.$el.querySelector('.ivu-select-selected-value');
124 - return selectedValueSpan.textContent === 'Bar'; 124 + return selectedValueSpan && selectedValueSpan.textContent === 'Bar';
125 }, 125 },
126 () => { 126 () => {
127 const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder'); 127 const placeholderSpan = vm.$el.querySelector('.ivu-select-placeholder');