1
1
import { Controller } from '@hotwired/stimulus' ;
2
2
import TomSelect from 'tom-select' ;
3
3
4
- /******************************************************************************
5
- Copyright (c) Microsoft Corporation.
6
-
7
- Permission to use, copy, modify, and/or distribute this software for any
8
- purpose with or without fee is hereby granted.
9
-
10
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
11
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
12
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
13
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
14
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
15
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
16
- PERFORMANCE OF THIS SOFTWARE.
17
- ***************************************************************************** */
18
-
19
- function __classPrivateFieldGet ( receiver , state , kind , f ) {
20
- if ( kind === "a" && ! f ) throw new TypeError ( "Private accessor was defined without a getter" ) ;
21
- if ( typeof state === "function" ? receiver !== state || ! f : ! state . has ( receiver ) ) throw new TypeError ( "Cannot read private member from an object whose class did not declare it" ) ;
22
- return kind === "m" ? f : kind === "a" ? f . call ( receiver ) : f ? f . value : state . get ( receiver ) ;
23
- }
24
-
25
- var _default_1_instances , _default_1_getCommonConfig , _default_1_createAutocomplete , _default_1_createAutocompleteWithHtmlContents , _default_1_createAutocompleteWithRemoteData , _default_1_stripTags , _default_1_mergeObjects , _default_1_createTomSelect ;
26
4
class default_1 extends Controller {
27
- constructor ( ) {
28
- super ( ...arguments ) ;
29
- _default_1_instances . add ( this ) ;
30
- this . isObserving = false ;
31
- this . hasLoadedChoicesPreviously = false ;
32
- this . originalOptions = [ ] ;
33
- }
5
+ static values = {
6
+ url : String ,
7
+ optionsAsHtml : Boolean ,
8
+ loadingMoreText : String ,
9
+ noResultsFoundText : String ,
10
+ noMoreResultsText : String ,
11
+ minCharacters : Number ,
12
+ tomSelectOptions : Object ,
13
+ preload : String ,
14
+ } ;
15
+ tomSelect ;
16
+ mutationObserver ;
17
+ isObserving = false ;
18
+ hasLoadedChoicesPreviously = false ;
19
+ originalOptions = [ ] ;
34
20
initialize ( ) {
35
21
if ( ! this . mutationObserver ) {
36
22
this . mutationObserver = new MutationObserver ( ( mutations ) => {
@@ -49,14 +35,14 @@ class default_1 extends Controller {
49
35
this . selectElement . setAttribute ( 'data-skip-morph' , '' ) ;
50
36
}
51
37
if ( this . urlValue ) {
52
- this . tomSelect = __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_createAutocompleteWithRemoteData ) . call ( this , this . urlValue , this . hasMinCharactersValue ? this . minCharactersValue : null ) ;
38
+ this . tomSelect = this . #createAutocompleteWithRemoteData ( this . urlValue , this . hasMinCharactersValue ? this . minCharactersValue : null ) ;
53
39
return ;
54
40
}
55
41
if ( this . optionsAsHtmlValue ) {
56
- this . tomSelect = __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_createAutocompleteWithHtmlContents ) . call ( this ) ;
42
+ this . tomSelect = this . #createAutocompleteWithHtmlContents ( ) ;
57
43
return ;
58
44
}
59
- this . tomSelect = __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_createAutocomplete ) . call ( this ) ;
45
+ this . tomSelect = this . #createAutocomplete ( ) ;
60
46
this . startMutationObserver ( ) ;
61
47
}
62
48
disconnect ( ) {
@@ -84,9 +70,126 @@ class default_1 extends Controller {
84
70
}
85
71
}
86
72
}
73
+ #getCommonConfig( ) {
74
+ const plugins = { } ;
75
+ const isMultiple = ! this . selectElement || this . selectElement . multiple ;
76
+ if ( ! this . formElement . disabled && ! isMultiple ) {
77
+ plugins . clear_button = { title : '' } ;
78
+ }
79
+ if ( isMultiple ) {
80
+ plugins . remove_button = { title : '' } ;
81
+ }
82
+ if ( this . urlValue ) {
83
+ plugins . virtual_scroll = { } ;
84
+ }
85
+ const render = {
86
+ no_results : ( ) => {
87
+ return `<div class="no-results">${ this . noResultsFoundTextValue } </div>` ;
88
+ } ,
89
+ } ;
90
+ const config = {
91
+ render,
92
+ plugins,
93
+ onItemAdd : ( ) => {
94
+ this . tomSelect . setTextboxValue ( '' ) ;
95
+ } ,
96
+ closeAfterSelect : true ,
97
+ } ;
98
+ if ( ! this . selectElement && ! this . urlValue ) {
99
+ config . shouldLoad = ( ) => false ;
100
+ }
101
+ return this . #mergeObjects( config , this . tomSelectOptionsValue ) ;
102
+ }
103
+ #createAutocomplete( ) {
104
+ const config = this . #mergeObjects( this . #getCommonConfig( ) , {
105
+ maxOptions : this . getMaxOptions ( ) ,
106
+ } ) ;
107
+ return this . #createTomSelect( config ) ;
108
+ }
109
+ #createAutocompleteWithHtmlContents( ) {
110
+ const config = this . #mergeObjects( this . #getCommonConfig( ) , {
111
+ maxOptions : this . getMaxOptions ( ) ,
112
+ score : ( search ) => {
113
+ const scoringFunction = this . tomSelect . getScoreFunction ( search ) ;
114
+ return ( item ) => {
115
+ return scoringFunction ( { ...item , text : this . #stripTags( item . text ) } ) ;
116
+ } ;
117
+ } ,
118
+ render : {
119
+ item : function ( item ) {
120
+ return `<div>${ item . text } </div>` ;
121
+ } ,
122
+ option : function ( item ) {
123
+ return `<div>${ item . text } </div>` ;
124
+ } ,
125
+ } ,
126
+ } ) ;
127
+ return this . #createTomSelect( config ) ;
128
+ }
129
+ #createAutocompleteWithRemoteData( autocompleteEndpointUrl , minCharacterLength ) {
130
+ const config = this . #mergeObjects( this . #getCommonConfig( ) , {
131
+ firstUrl : ( query ) => {
132
+ const separator = autocompleteEndpointUrl . includes ( '?' ) ? '&' : '?' ;
133
+ return `${ autocompleteEndpointUrl } ${ separator } query=${ encodeURIComponent ( query ) } ` ;
134
+ } ,
135
+ load : function ( query , callback ) {
136
+ const url = this . getUrl ( query ) ;
137
+ fetch ( url )
138
+ . then ( ( response ) => response . json ( ) )
139
+ . then ( ( json ) => {
140
+ this . setNextUrl ( query , json . next_page ) ;
141
+ callback ( json . results . options || json . results , json . results . optgroups || [ ] ) ;
142
+ } )
143
+ . catch ( ( ) => callback ( [ ] , [ ] ) ) ;
144
+ } ,
145
+ shouldLoad : ( query ) => {
146
+ if ( null !== minCharacterLength ) {
147
+ return query . length >= minCharacterLength ;
148
+ }
149
+ if ( this . hasLoadedChoicesPreviously ) {
150
+ return true ;
151
+ }
152
+ if ( query . length > 0 ) {
153
+ this . hasLoadedChoicesPreviously = true ;
154
+ }
155
+ return query . length >= 3 ;
156
+ } ,
157
+ optgroupField : 'group_by' ,
158
+ score : function ( search ) {
159
+ return function ( item ) {
160
+ return 1 ;
161
+ } ;
162
+ } ,
163
+ render : {
164
+ option : function ( item ) {
165
+ return `<div>${ item . text } </div>` ;
166
+ } ,
167
+ item : function ( item ) {
168
+ return `<div>${ item . text } </div>` ;
169
+ } ,
170
+ loading_more : ( ) => {
171
+ return `<div class="loading-more-results">${ this . loadingMoreTextValue } </div>` ;
172
+ } ,
173
+ no_more_results : ( ) => {
174
+ return `<div class="no-more-results">${ this . noMoreResultsTextValue } </div>` ;
175
+ } ,
176
+ no_results : ( ) => {
177
+ return `<div class="no-results">${ this . noResultsFoundTextValue } </div>` ;
178
+ } ,
179
+ } ,
180
+ preload : this . preload ,
181
+ } ) ;
182
+ return this . #createTomSelect( config ) ;
183
+ }
87
184
getMaxOptions ( ) {
88
185
return this . selectElement ? this . selectElement . options . length : 50 ;
89
186
}
187
+ #stripTags( string ) {
188
+ return string . replace ( / ( < ( [ ^ > ] + ) > ) / gi, '' ) ;
189
+ }
190
+ #mergeObjects( object1 , object2 ) {
191
+ return { ...object1 , ...object2 } ;
192
+ }
90
193
get selectElement ( ) {
91
194
if ( ! ( this . element instanceof HTMLSelectElement ) ) {
92
195
return null ;
@@ -99,6 +202,14 @@ class default_1 extends Controller {
99
202
}
100
203
return this . element ;
101
204
}
205
+ #createTomSelect( options ) {
206
+ const preConnectPayload = { options } ;
207
+ this . dispatchEvent ( 'pre-connect' , preConnectPayload ) ;
208
+ const tomSelect = new TomSelect ( this . formElement , options ) ;
209
+ const connectPayload = { tomSelect, options } ;
210
+ this . dispatchEvent ( 'connect' , connectPayload ) ;
211
+ return tomSelect ;
212
+ }
102
213
dispatchEvent ( name , payload ) {
103
214
this . dispatch ( name , { detail : payload , prefix : 'autocomplete' } ) ;
104
215
}
@@ -216,134 +327,5 @@ class default_1 extends Controller {
216
327
[ ...originalOptionsSet ] . every ( ( option ) => newOptionsSet . has ( option ) ) ) ;
217
328
}
218
329
}
219
- _default_1_instances = new WeakSet ( ) , _default_1_getCommonConfig = function _default_1_getCommonConfig ( ) {
220
- const plugins = { } ;
221
- const isMultiple = ! this . selectElement || this . selectElement . multiple ;
222
- if ( ! this . formElement . disabled && ! isMultiple ) {
223
- plugins . clear_button = { title : '' } ;
224
- }
225
- if ( isMultiple ) {
226
- plugins . remove_button = { title : '' } ;
227
- }
228
- if ( this . urlValue ) {
229
- plugins . virtual_scroll = { } ;
230
- }
231
- const render = {
232
- no_results : ( ) => {
233
- return `<div class="no-results">${ this . noResultsFoundTextValue } </div>` ;
234
- } ,
235
- } ;
236
- const config = {
237
- render,
238
- plugins,
239
- onItemAdd : ( ) => {
240
- this . tomSelect . setTextboxValue ( '' ) ;
241
- } ,
242
- closeAfterSelect : true ,
243
- } ;
244
- if ( ! this . selectElement && ! this . urlValue ) {
245
- config . shouldLoad = ( ) => false ;
246
- }
247
- return __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_mergeObjects ) . call ( this , config , this . tomSelectOptionsValue ) ;
248
- } , _default_1_createAutocomplete = function _default_1_createAutocomplete ( ) {
249
- const config = __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_mergeObjects ) . call ( this , __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_getCommonConfig ) . call ( this ) , {
250
- maxOptions : this . getMaxOptions ( ) ,
251
- } ) ;
252
- return __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_createTomSelect ) . call ( this , config ) ;
253
- } , _default_1_createAutocompleteWithHtmlContents = function _default_1_createAutocompleteWithHtmlContents ( ) {
254
- const config = __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_mergeObjects ) . call ( this , __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_getCommonConfig ) . call ( this ) , {
255
- maxOptions : this . getMaxOptions ( ) ,
256
- score : ( search ) => {
257
- const scoringFunction = this . tomSelect . getScoreFunction ( search ) ;
258
- return ( item ) => {
259
- return scoringFunction ( Object . assign ( Object . assign ( { } , item ) , { text : __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_stripTags ) . call ( this , item . text ) } ) ) ;
260
- } ;
261
- } ,
262
- render : {
263
- item : function ( item ) {
264
- return `<div>${ item . text } </div>` ;
265
- } ,
266
- option : function ( item ) {
267
- return `<div>${ item . text } </div>` ;
268
- } ,
269
- } ,
270
- } ) ;
271
- return __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_createTomSelect ) . call ( this , config ) ;
272
- } , _default_1_createAutocompleteWithRemoteData = function _default_1_createAutocompleteWithRemoteData ( autocompleteEndpointUrl , minCharacterLength ) {
273
- const config = __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_mergeObjects ) . call ( this , __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_getCommonConfig ) . call ( this ) , {
274
- firstUrl : ( query ) => {
275
- const separator = autocompleteEndpointUrl . includes ( '?' ) ? '&' : '?' ;
276
- return `${ autocompleteEndpointUrl } ${ separator } query=${ encodeURIComponent ( query ) } ` ;
277
- } ,
278
- load : function ( query , callback ) {
279
- const url = this . getUrl ( query ) ;
280
- fetch ( url )
281
- . then ( ( response ) => response . json ( ) )
282
- . then ( ( json ) => {
283
- this . setNextUrl ( query , json . next_page ) ;
284
- callback ( json . results . options || json . results , json . results . optgroups || [ ] ) ;
285
- } )
286
- . catch ( ( ) => callback ( [ ] , [ ] ) ) ;
287
- } ,
288
- shouldLoad : ( query ) => {
289
- if ( null !== minCharacterLength ) {
290
- return query . length >= minCharacterLength ;
291
- }
292
- if ( this . hasLoadedChoicesPreviously ) {
293
- return true ;
294
- }
295
- if ( query . length > 0 ) {
296
- this . hasLoadedChoicesPreviously = true ;
297
- }
298
- return query . length >= 3 ;
299
- } ,
300
- optgroupField : 'group_by' ,
301
- score : function ( search ) {
302
- return function ( item ) {
303
- return 1 ;
304
- } ;
305
- } ,
306
- render : {
307
- option : function ( item ) {
308
- return `<div>${ item . text } </div>` ;
309
- } ,
310
- item : function ( item ) {
311
- return `<div>${ item . text } </div>` ;
312
- } ,
313
- loading_more : ( ) => {
314
- return `<div class="loading-more-results">${ this . loadingMoreTextValue } </div>` ;
315
- } ,
316
- no_more_results : ( ) => {
317
- return `<div class="no-more-results">${ this . noMoreResultsTextValue } </div>` ;
318
- } ,
319
- no_results : ( ) => {
320
- return `<div class="no-results">${ this . noResultsFoundTextValue } </div>` ;
321
- } ,
322
- } ,
323
- preload : this . preload ,
324
- } ) ;
325
- return __classPrivateFieldGet ( this , _default_1_instances , "m" , _default_1_createTomSelect ) . call ( this , config ) ;
326
- } , _default_1_stripTags = function _default_1_stripTags ( string ) {
327
- return string . replace ( / ( < ( [ ^ > ] + ) > ) / gi, '' ) ;
328
- } , _default_1_mergeObjects = function _default_1_mergeObjects ( object1 , object2 ) {
329
- return Object . assign ( Object . assign ( { } , object1 ) , object2 ) ;
330
- } , _default_1_createTomSelect = function _default_1_createTomSelect ( options ) {
331
- const preConnectPayload = { options } ;
332
- this . dispatchEvent ( 'pre-connect' , preConnectPayload ) ;
333
- const tomSelect = new TomSelect ( this . formElement , options ) ;
334
- const connectPayload = { tomSelect, options } ;
335
- this . dispatchEvent ( 'connect' , connectPayload ) ;
336
- return tomSelect ;
337
- } ;
338
- default_1 . values = {
339
- url : String ,
340
- optionsAsHtml : Boolean ,
341
- loadingMoreText : String ,
342
- noResultsFoundText : String ,
343
- noMoreResultsText : String ,
344
- minCharacters : Number ,
345
- tomSelectOptions : Object ,
346
- preload : String ,
347
- } ;
348
330
349
331
export { default_1 as default } ;
0 commit comments