@@ -45,109 +45,113 @@ export default class Select2 extends Component {
45
45
constructor ( props ) {
46
46
super ( props ) ;
47
47
this . el = null ;
48
+ this . forceUpdateValue = false ;
48
49
}
49
50
50
51
componentDidMount ( ) {
51
- this . initSelect2 ( ) ;
52
+ this . initSelect2 ( this . props ) ;
53
+ this . updateValue ( ) ;
52
54
}
53
55
54
56
componentWillReceiveProps ( nextProps ) {
55
- if ( this . el ) {
56
- this . setValue ( this . prepareValue ( nextProps . value , this . props . defaultValue ) ) ;
57
- }
57
+ this . updSelect2 ( nextProps ) ;
58
58
}
59
59
60
- componentDidUpdate ( prevProps ) {
61
- if ( ! shallowEqualFuzzy ( prevProps . data , this . props . data ) ) {
62
- this . destroySelect2 ( false ) ;
63
- this . initSelect2 ( false ) ;
64
- } else {
65
- const { options } = this . props ;
66
- if ( ! shallowEqualFuzzy ( prevProps . options , options ) ) {
67
- this . el . select2 ( this . prepareOptions ( options ) ) ;
68
- }
69
- }
70
-
71
- const handlerChanged = e => prevProps [ e [ 1 ] ] !== this . props [ e [ 1 ] ] ;
72
-
73
- if ( this . props . events . some ( handlerChanged ) ) {
74
- this . detachEventHandlers ( ) ;
75
- this . attachEventHandlers ( ) ;
76
- }
60
+ componentDidUpdate ( ) {
61
+ this . updateValue ( ) ;
77
62
}
78
63
79
64
componentWillUnmount ( ) {
80
65
this . destroySelect2 ( ) ;
81
66
}
82
67
83
- setValue ( value ) {
84
- const elVal = this . props . multiple ? this . el . val ( ) || [ ] : this . el . val ( ) ;
85
- if ( ! shallowEqualFuzzy ( elVal , value ) ) {
86
- this . el . val ( value ) . trigger ( 'change' ) ;
68
+ initSelect2 ( props , updateValue = false ) {
69
+ const { options } = props ;
70
+
71
+ this . el = $ ( ReactDOM . findDOMNode ( this ) ) ;
72
+ // fix for updating selected value when data is changing
73
+ if ( updateValue ) {
74
+ this . forceUpdateValue = true ;
75
+ this . el . off ( `change.${ namespace } ` ) . val ( null ) . trigger ( 'change' ) ;
87
76
}
77
+ this . el . select2 ( this . prepareOptions ( options ) ) ;
78
+ this . attachEventHandlers ( props ) ;
88
79
}
89
80
90
- prepareValue ( value , defaultValue ) {
91
- const issetValue = typeof value !== 'undefined' && value !== null ;
92
- const issetDefaultValue = typeof defaultValue !== 'undefined' ;
81
+ updSelect2 ( props ) {
82
+ const prevProps = this . props ;
93
83
94
- if ( ! issetValue && issetDefaultValue ) {
95
- return defaultValue ;
84
+ if ( ! shallowEqualFuzzy ( prevProps . data , props . data ) ) {
85
+ this . destroySelect2 ( false ) ;
86
+ this . initSelect2 ( props , true ) ;
87
+ } else {
88
+ const { options } = props ;
89
+ if ( ! shallowEqualFuzzy ( prevProps . options , options ) ) {
90
+ this . el . select2 ( this . prepareOptions ( options ) ) ;
91
+ }
96
92
}
97
- return value ;
98
- }
99
93
100
- prepareOptions ( options ) {
101
- const opt = options ;
102
- if ( typeof opt . dropdownParent === 'string' ) {
103
- opt . dropdownParent = $ ( opt . dropdownParent ) ;
94
+ const handlerChanged = e => prevProps [ e [ 1 ] ] !== props [ e [ 1 ] ] ;
95
+ if ( props . events . some ( handlerChanged ) ) {
96
+ this . detachEventHandlers ( props ) ;
97
+ this . attachEventHandlers ( props ) ;
104
98
}
105
- return opt ;
106
99
}
107
100
108
- initSelect2 ( withCallbacks = true ) {
109
- if ( this . el ) { return ; }
110
- const { defaultValue, value, options } = this . props ;
111
-
112
- this . el = $ ( ReactDOM . findDOMNode ( this ) ) ;
113
- this . el . select2 ( this . prepareOptions ( options ) ) ;
114
-
115
- if ( withCallbacks ) {
116
- this . attachEventHandlers ( ) ;
117
- }
101
+ updateValue ( ) {
102
+ const { value, defaultValue, multiple } = this . props ;
103
+ const newValue = this . prepareValue ( value , defaultValue ) ;
104
+ const currentValue = multiple ? this . el . val ( ) || [ ] : this . el . val ( ) ;
118
105
119
- if ( typeof defaultValue === 'undefined' && typeof value !== 'undefined' ) {
120
- this . setValue ( value ) ;
106
+ if ( ! shallowEqualFuzzy ( currentValue , newValue ) || this . forceUpdateValue ) {
107
+ this . el . val ( newValue ) . trigger ( 'change' ) ;
108
+ this . forceUpdateValue = false ;
121
109
}
122
110
}
123
111
124
112
destroySelect2 ( withCallbacks = true ) {
125
- if ( ! this . el ) { return ; }
126
-
127
113
if ( withCallbacks ) {
128
- this . detachEventHandlers ( ) ;
114
+ this . detachEventHandlers ( this . props ) ;
129
115
}
130
116
131
117
this . el . select2 ( 'destroy' ) ;
132
118
this . el = null ;
133
119
}
134
120
135
- attachEventHandlers ( ) {
136
- this . props . events . forEach ( event => {
137
- if ( typeof this . props [ event [ 1 ] ] !== 'undefined' ) {
138
- this . el . on ( event [ 0 ] , this . props [ event [ 1 ] ] ) ;
121
+ attachEventHandlers ( props ) {
122
+ props . events . forEach ( event => {
123
+ if ( typeof props [ event [ 1 ] ] !== 'undefined' ) {
124
+ this . el . on ( event [ 0 ] , props [ event [ 1 ] ] ) ;
139
125
}
140
126
} ) ;
141
127
}
142
128
143
- detachEventHandlers ( ) {
144
- this . props . events . forEach ( event => {
145
- if ( typeof this . props [ event [ 1 ] ] !== 'undefined' ) {
129
+ detachEventHandlers ( props ) {
130
+ props . events . forEach ( event => {
131
+ if ( typeof props [ event [ 1 ] ] !== 'undefined' ) {
146
132
this . el . off ( event [ 0 ] ) ;
147
133
}
148
134
} ) ;
149
135
}
150
136
137
+ prepareValue ( value , defaultValue ) {
138
+ const issetValue = typeof value !== 'undefined' && value !== null ;
139
+ const issetDefaultValue = typeof defaultValue !== 'undefined' ;
140
+
141
+ if ( ! issetValue && issetDefaultValue ) {
142
+ return defaultValue ;
143
+ }
144
+ return value ;
145
+ }
146
+
147
+ prepareOptions ( options ) {
148
+ const opt = options ;
149
+ if ( typeof opt . dropdownParent === 'string' ) {
150
+ opt . dropdownParent = $ ( opt . dropdownParent ) ;
151
+ }
152
+ return opt ;
153
+ }
154
+
151
155
isObject ( value ) {
152
156
const type = typeof value ;
153
157
return type === 'function' || ( value && type === 'object' ) || false ;
0 commit comments