@kamranbaylarov/one-select 1.1.0 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +979 -891
- package/css/one-select.min.css +41 -37
- package/js/one-select.js +1412 -1186
- package/js/one-select.min.js +1 -7
- package/package.json +41 -41
package/js/one-select.js
CHANGED
|
@@ -1,1186 +1,1412 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* OneSelect - jQuery Multi-Select Dropdown Plugin
|
|
3
|
-
* Version: 1.
|
|
4
|
-
* https://github.com/your-repo/one-select
|
|
5
|
-
*
|
|
6
|
-
* Copyright
|
|
7
|
-
* Licensed under MIT
|
|
8
|
-
*
|
|
9
|
-
* A powerful, flexible, and feature-rich multi-select dropdown component for jQuery.
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
(function(factory) {
|
|
13
|
-
'use strict';
|
|
14
|
-
|
|
15
|
-
if (typeof define === 'function' && define.amd) {
|
|
16
|
-
// AMD
|
|
17
|
-
define(['jquery'], factory);
|
|
18
|
-
} else if (typeof module === 'object' && module.exports) {
|
|
19
|
-
// CommonJS
|
|
20
|
-
module.exports = function(root, jQuery) {
|
|
21
|
-
if (jQuery === undefined) {
|
|
22
|
-
if (typeof window !== 'undefined') {
|
|
23
|
-
jQuery = require('jquery');
|
|
24
|
-
} else {
|
|
25
|
-
jQuery = require('jquery')(root);
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
factory(jQuery);
|
|
29
|
-
return jQuery;
|
|
30
|
-
};
|
|
31
|
-
} else {
|
|
32
|
-
// Browser globals
|
|
33
|
-
factory(window.jQuery || window.$);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
}(function($) {
|
|
37
|
-
'use strict';
|
|
38
|
-
|
|
39
|
-
// Global registry for all instances
|
|
40
|
-
var instances = {};
|
|
41
|
-
var pluginName = 'oneSelect';
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Debounce utility function
|
|
45
|
-
* @param {Function} func - Function to debounce
|
|
46
|
-
* @param {Number} delay - Delay in milliseconds
|
|
47
|
-
* @returns {Function} Debounced function
|
|
48
|
-
*/
|
|
49
|
-
function debounce(func, delay) {
|
|
50
|
-
var timeoutId;
|
|
51
|
-
return function() {
|
|
52
|
-
var context = this;
|
|
53
|
-
var args = arguments;
|
|
54
|
-
clearTimeout(timeoutId);
|
|
55
|
-
timeoutId = setTimeout(function() {
|
|
56
|
-
func.apply(context, args);
|
|
57
|
-
}, delay);
|
|
58
|
-
};
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* OneSelect Constructor
|
|
63
|
-
* @param {HTMLElement} element - The DOM element
|
|
64
|
-
* @param {Object} options - Configuration options
|
|
65
|
-
*/
|
|
66
|
-
var OneSelect = function(element, options) {
|
|
67
|
-
this.element = element;
|
|
68
|
-
this.$element = $(element);
|
|
69
|
-
|
|
70
|
-
// Generate unique instance ID for control
|
|
71
|
-
this.instanceId = 'ones-' + Math.random().toString(36).substr(2, 9);
|
|
72
|
-
|
|
73
|
-
// Read data attributes from element (highest priority)
|
|
74
|
-
var dataOptions = this.readDataAttributes();
|
|
75
|
-
|
|
76
|
-
// Merge: defaults -> options (JS) -> dataOptions (HTML attributes)
|
|
77
|
-
this.settings = $.extend({}, OneSelect.defaults, options, dataOptions);
|
|
78
|
-
this.init();
|
|
79
|
-
};
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Default configuration options
|
|
83
|
-
*/
|
|
84
|
-
OneSelect.defaults = {
|
|
85
|
-
placeholder: 'Select options...',
|
|
86
|
-
selectAllText: 'Select All',
|
|
87
|
-
okText: 'OK',
|
|
88
|
-
cancelText: 'Cancel',
|
|
89
|
-
data: [],
|
|
90
|
-
value: null, // Single value or array of values to pre-select (index-based)
|
|
91
|
-
showCheckbox: true,
|
|
92
|
-
showBadges: false,
|
|
93
|
-
showBadgesExternal: null,
|
|
94
|
-
showSearch: false, // Show search input in dropdown
|
|
95
|
-
searchPlaceholder: 'Search...',
|
|
96
|
-
searchUrl: null, // URL for AJAX search (GET request)
|
|
97
|
-
searchDebounceDelay: 300,// Delay in milliseconds for search debounce
|
|
98
|
-
closeOnScroll: false,
|
|
99
|
-
closeOnOutside: true, // Close dropdown when clicking outside (default: true)
|
|
100
|
-
submitForm: false,
|
|
101
|
-
submitOnOutside: false,
|
|
102
|
-
formId: null,
|
|
103
|
-
name: null,
|
|
104
|
-
multiple: true,
|
|
105
|
-
ajax: null,
|
|
106
|
-
autoLoad: true,
|
|
107
|
-
beforeLoad: null,
|
|
108
|
-
afterLoad: null,
|
|
109
|
-
onLoadError: null,
|
|
110
|
-
onChange: null,
|
|
111
|
-
onSelect: null,
|
|
112
|
-
onOk: null,
|
|
113
|
-
onCancel: null
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
var
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
'ones-
|
|
132
|
-
'ones-
|
|
133
|
-
'ones-
|
|
134
|
-
'ones-
|
|
135
|
-
'ones-
|
|
136
|
-
'ones-
|
|
137
|
-
'ones-
|
|
138
|
-
'ones-
|
|
139
|
-
'ones-show-
|
|
140
|
-
'ones-
|
|
141
|
-
'ones-
|
|
142
|
-
'ones-search
|
|
143
|
-
'ones-
|
|
144
|
-
'ones-
|
|
145
|
-
'ones-
|
|
146
|
-
'ones-
|
|
147
|
-
'ones-
|
|
148
|
-
'ones-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
this.
|
|
241
|
-
|
|
242
|
-
this.wrapper.
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
this
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
this.
|
|
249
|
-
|
|
250
|
-
this.
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
if
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
} else {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
var
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
var
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
var
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
//
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
return;
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
//
|
|
624
|
-
if (
|
|
625
|
-
self.
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
self.
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
}
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
}
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
this.optionsContainer.
|
|
738
|
-
.
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
if (
|
|
799
|
-
console.warn('OneSelect:
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
}
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
this.
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
this.
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
this.
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
var
|
|
943
|
-
|
|
944
|
-
if (
|
|
945
|
-
console.
|
|
946
|
-
return;
|
|
947
|
-
}
|
|
948
|
-
|
|
949
|
-
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
var
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
986
|
-
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
this.
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
},
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
this.
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
this.
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
}
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
|
|
1186
|
-
|
|
1
|
+
/**
|
|
2
|
+
* OneSelect - jQuery Multi-Select Dropdown Plugin
|
|
3
|
+
* Version: 1.2.0
|
|
4
|
+
* https://github.com/your-repo/one-select
|
|
5
|
+
*
|
|
6
|
+
* Copyright 2026
|
|
7
|
+
* Licensed under MIT
|
|
8
|
+
*
|
|
9
|
+
* A powerful, flexible, and feature-rich multi-select dropdown component for jQuery.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
(function (factory) {
|
|
13
|
+
'use strict';
|
|
14
|
+
|
|
15
|
+
if (typeof define === 'function' && define.amd) {
|
|
16
|
+
// AMD
|
|
17
|
+
define(['jquery'], factory);
|
|
18
|
+
} else if (typeof module === 'object' && module.exports) {
|
|
19
|
+
// CommonJS
|
|
20
|
+
module.exports = function (root, jQuery) {
|
|
21
|
+
if (jQuery === undefined) {
|
|
22
|
+
if (typeof window !== 'undefined') {
|
|
23
|
+
jQuery = require('jquery');
|
|
24
|
+
} else {
|
|
25
|
+
jQuery = require('jquery')(root);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
factory(jQuery);
|
|
29
|
+
return jQuery;
|
|
30
|
+
};
|
|
31
|
+
} else {
|
|
32
|
+
// Browser globals
|
|
33
|
+
factory(window.jQuery || window.$);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
}(function ($) {
|
|
37
|
+
'use strict';
|
|
38
|
+
|
|
39
|
+
// Global registry for all instances
|
|
40
|
+
var instances = {};
|
|
41
|
+
var pluginName = 'oneSelect';
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Debounce utility function
|
|
45
|
+
* @param {Function} func - Function to debounce
|
|
46
|
+
* @param {Number} delay - Delay in milliseconds
|
|
47
|
+
* @returns {Function} Debounced function
|
|
48
|
+
*/
|
|
49
|
+
function debounce(func, delay) {
|
|
50
|
+
var timeoutId;
|
|
51
|
+
return function () {
|
|
52
|
+
var context = this;
|
|
53
|
+
var args = arguments;
|
|
54
|
+
clearTimeout(timeoutId);
|
|
55
|
+
timeoutId = setTimeout(function () {
|
|
56
|
+
func.apply(context, args);
|
|
57
|
+
}, delay);
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* OneSelect Constructor
|
|
63
|
+
* @param {HTMLElement} element - The DOM element
|
|
64
|
+
* @param {Object} options - Configuration options
|
|
65
|
+
*/
|
|
66
|
+
var OneSelect = function (element, options) {
|
|
67
|
+
this.element = element;
|
|
68
|
+
this.$element = $(element);
|
|
69
|
+
|
|
70
|
+
// Generate unique instance ID for control
|
|
71
|
+
this.instanceId = 'ones-' + Math.random().toString(36).substr(2, 9);
|
|
72
|
+
|
|
73
|
+
// Read data attributes from element (highest priority)
|
|
74
|
+
var dataOptions = this.readDataAttributes();
|
|
75
|
+
|
|
76
|
+
// Merge: defaults -> options (JS) -> dataOptions (HTML attributes)
|
|
77
|
+
this.settings = $.extend({}, OneSelect.defaults, options, dataOptions);
|
|
78
|
+
this.init();
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Default configuration options
|
|
83
|
+
*/
|
|
84
|
+
OneSelect.defaults = {
|
|
85
|
+
placeholder: 'Select options...',
|
|
86
|
+
selectAllText: 'Select All',
|
|
87
|
+
okText: 'OK',
|
|
88
|
+
cancelText: 'Cancel',
|
|
89
|
+
data: [],
|
|
90
|
+
value: null, // Single value or array of values to pre-select (index-based)
|
|
91
|
+
showCheckbox: true,
|
|
92
|
+
showBadges: false,
|
|
93
|
+
showBadgesExternal: null,
|
|
94
|
+
showSearch: false, // Show search input in dropdown
|
|
95
|
+
searchPlaceholder: 'Search...',
|
|
96
|
+
searchUrl: null, // URL for AJAX search (GET request)
|
|
97
|
+
searchDebounceDelay: 300,// Delay in milliseconds for search debounce
|
|
98
|
+
closeOnScroll: false,
|
|
99
|
+
closeOnOutside: true, // Close dropdown when clicking outside (default: true)
|
|
100
|
+
submitForm: false,
|
|
101
|
+
submitOnOutside: false,
|
|
102
|
+
formId: null,
|
|
103
|
+
name: null,
|
|
104
|
+
multiple: true,
|
|
105
|
+
ajax: null,
|
|
106
|
+
autoLoad: true,
|
|
107
|
+
beforeLoad: null,
|
|
108
|
+
afterLoad: null,
|
|
109
|
+
onLoadError: null,
|
|
110
|
+
onChange: null,
|
|
111
|
+
onSelect: null,
|
|
112
|
+
onOk: null,
|
|
113
|
+
onCancel: null,
|
|
114
|
+
infinityScroll: false,
|
|
115
|
+
onInfinityScroll: null,
|
|
116
|
+
loading: false
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* OneSelect Prototype
|
|
121
|
+
*/
|
|
122
|
+
OneSelect.prototype = {
|
|
123
|
+
/**
|
|
124
|
+
* Read data attributes from HTML element
|
|
125
|
+
*/
|
|
126
|
+
readDataAttributes: function () {
|
|
127
|
+
var self = this;
|
|
128
|
+
var dataOptions = {};
|
|
129
|
+
|
|
130
|
+
var attributeMap = {
|
|
131
|
+
'ones-placeholder': 'placeholder',
|
|
132
|
+
'ones-select-all-text': 'selectAllText',
|
|
133
|
+
'ones-ok-text': 'okText',
|
|
134
|
+
'ones-cancel-text': 'cancelText',
|
|
135
|
+
'ones-data': 'data',
|
|
136
|
+
'ones-value': 'value',
|
|
137
|
+
'ones-name': 'name',
|
|
138
|
+
'ones-multiple': 'multiple',
|
|
139
|
+
'ones-show-checkbox': 'showCheckbox',
|
|
140
|
+
'ones-show-badges': 'showBadges',
|
|
141
|
+
'ones-show-badges-external': 'showBadgesExternal',
|
|
142
|
+
'ones-show-search': 'showSearch',
|
|
143
|
+
'ones-search-placeholder': 'searchPlaceholder',
|
|
144
|
+
'ones-search-url': 'searchUrl',
|
|
145
|
+
'ones-search-debounce-delay': 'searchDebounceDelay',
|
|
146
|
+
'ones-close-on-scroll': 'closeOnScroll',
|
|
147
|
+
'ones-close-on-outside': 'closeOnOutside',
|
|
148
|
+
'ones-submit-form': 'submitForm',
|
|
149
|
+
'ones-submit-on-outside': 'submitOnOutside',
|
|
150
|
+
'ones-form-id': 'formId',
|
|
151
|
+
'ones-auto-load': 'autoLoad',
|
|
152
|
+
'ones-infinity-scroll': 'infinityScroll'
|
|
153
|
+
};
|
|
154
|
+
|
|
155
|
+
$.each(attributeMap, function (attr, setting) {
|
|
156
|
+
var value = self.$element.data(attr);
|
|
157
|
+
|
|
158
|
+
if (value === undefined) {
|
|
159
|
+
return;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
if (setting === 'data' || setting === 'value') {
|
|
163
|
+
if (typeof value === 'string') {
|
|
164
|
+
try {
|
|
165
|
+
dataOptions[setting] = JSON.parse(value);
|
|
166
|
+
} catch (e) {
|
|
167
|
+
console.warn('OneSelect: Invalid JSON for ' + attr, value);
|
|
168
|
+
dataOptions[setting] = value;
|
|
169
|
+
}
|
|
170
|
+
} else {
|
|
171
|
+
dataOptions[setting] = value;
|
|
172
|
+
}
|
|
173
|
+
} else if (setting === 'multiple' || setting === 'showCheckbox' ||
|
|
174
|
+
setting === 'showBadges' || setting === 'showSearch' ||
|
|
175
|
+
setting === 'closeOnScroll' || setting === 'closeOnOutside' ||
|
|
176
|
+
setting === 'submitForm' || setting === 'submitOnOutside' ||
|
|
177
|
+
setting === 'autoLoad' || setting === 'infinityScroll') {
|
|
178
|
+
if (typeof value === 'string') {
|
|
179
|
+
dataOptions[setting] = value === 'true' || value === '1';
|
|
180
|
+
} else {
|
|
181
|
+
dataOptions[setting] = !!value;
|
|
182
|
+
}
|
|
183
|
+
} else if (setting === 'searchDebounceDelay') {
|
|
184
|
+
// Parse as number
|
|
185
|
+
if (typeof value === 'string') {
|
|
186
|
+
dataOptions[setting] = parseInt(value, 10) || 300;
|
|
187
|
+
} else {
|
|
188
|
+
dataOptions[setting] = value || 300;
|
|
189
|
+
}
|
|
190
|
+
} else {
|
|
191
|
+
dataOptions[setting] = value;
|
|
192
|
+
}
|
|
193
|
+
});
|
|
194
|
+
|
|
195
|
+
var ajaxData = this.$element.data('ones-ajax');
|
|
196
|
+
if (ajaxData) {
|
|
197
|
+
if (typeof ajaxData === 'string') {
|
|
198
|
+
// String URL olarak kullan, default GET method ile
|
|
199
|
+
dataOptions.ajax = {
|
|
200
|
+
url: ajaxData,
|
|
201
|
+
method: 'GET'
|
|
202
|
+
};
|
|
203
|
+
} else if (typeof ajaxData === 'object') {
|
|
204
|
+
// Object olarak kullan (detaylı konfigürasyon için)
|
|
205
|
+
dataOptions.ajax = ajaxData;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return dataOptions;
|
|
210
|
+
},
|
|
211
|
+
|
|
212
|
+
init: function () {
|
|
213
|
+
// Register instance in global registry
|
|
214
|
+
instances[this.instanceId] = this;
|
|
215
|
+
|
|
216
|
+
// Convert value to array if needed and sanitize
|
|
217
|
+
if (this.settings.value !== null && this.settings.value !== undefined) {
|
|
218
|
+
if (!Array.isArray(this.settings.value)) {
|
|
219
|
+
this.settings.value = [this.settings.value];
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// Remove null/undefined and duplicates
|
|
223
|
+
var seen = {};
|
|
224
|
+
this.settings.value = this.settings.value.filter(function (v) {
|
|
225
|
+
if (v === null || v === undefined) return false;
|
|
226
|
+
var strV = String(v).trim();
|
|
227
|
+
if (seen[strV]) return false;
|
|
228
|
+
seen[strV] = true;
|
|
229
|
+
return true;
|
|
230
|
+
});
|
|
231
|
+
} else {
|
|
232
|
+
this.settings.value = [];
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Sync initial value to data attribute
|
|
236
|
+
this.updateDataValueAttribute();
|
|
237
|
+
|
|
238
|
+
// Initialize pagination state for infinity scroll
|
|
239
|
+
this.currentPage = 1;
|
|
240
|
+
this.hasNextPage = false;
|
|
241
|
+
|
|
242
|
+
this.wrapper = this.createWrapper();
|
|
243
|
+
this.trigger = this.createTrigger();
|
|
244
|
+
this.dropdown = this.createDropdown();
|
|
245
|
+
this.searchInput = this.createSearchInput();
|
|
246
|
+
this.optionsContainer = this.createOptionsContainer();
|
|
247
|
+
this.preloader = this.createPreloader();
|
|
248
|
+
this.buttons = this.createButtons();
|
|
249
|
+
|
|
250
|
+
this.build();
|
|
251
|
+
this.attachEvents();
|
|
252
|
+
|
|
253
|
+
if (this.settings.ajax && this.settings.autoLoad) {
|
|
254
|
+
this.loadData();
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
|
|
258
|
+
build: function () {
|
|
259
|
+
// Add search input at the top of dropdown if enabled
|
|
260
|
+
if (this.settings.showSearch) {
|
|
261
|
+
this.dropdown.append(this.searchInput);
|
|
262
|
+
}
|
|
263
|
+
this.dropdown.append(this.optionsContainer);
|
|
264
|
+
this.dropdown.append(this.preloader);
|
|
265
|
+
this.dropdown.append(this.buttons);
|
|
266
|
+
this.wrapper.append(this.trigger);
|
|
267
|
+
|
|
268
|
+
// Append wrapper to $element, dropdown to body
|
|
269
|
+
this.$element.append(this.wrapper);
|
|
270
|
+
$('body').append(this.dropdown);
|
|
271
|
+
|
|
272
|
+
this.renderOptions();
|
|
273
|
+
this.updateTriggerText();
|
|
274
|
+
this.updateHiddenInputs();
|
|
275
|
+
},
|
|
276
|
+
|
|
277
|
+
updateHiddenInputs: function () {
|
|
278
|
+
if (!this.settings.name) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
var form = null;
|
|
283
|
+
if (this.settings.formId) {
|
|
284
|
+
form = $('#' + this.settings.formId);
|
|
285
|
+
} else {
|
|
286
|
+
form = this.$element.closest('form');
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
var container = form.length ? form : this.wrapper;
|
|
290
|
+
|
|
291
|
+
container.find('input.cms-hidden-input[data-cms-input="' + this.settings.name + '"]').remove();
|
|
292
|
+
|
|
293
|
+
var inputName = this.settings.name;
|
|
294
|
+
if (this.settings.multiple && inputName.indexOf('[') === -1) {
|
|
295
|
+
inputName += '[]';
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
var selectedValues = this.getSelectedValues();
|
|
299
|
+
|
|
300
|
+
// Filter out null/undefined/empty to prevent backend errors
|
|
301
|
+
if (Array.isArray(selectedValues)) {
|
|
302
|
+
selectedValues = selectedValues.filter(function (v) {
|
|
303
|
+
return v !== null && v !== undefined && String(v).trim() !== '';
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (this.settings.multiple) {
|
|
308
|
+
if (selectedValues.length === 0) {
|
|
309
|
+
var hiddenInput = $('<input type="hidden" class="cms-hidden-input">')
|
|
310
|
+
.attr('name', this.settings.name)
|
|
311
|
+
.attr('value', '')
|
|
312
|
+
.attr('data-cms-input', this.settings.name);
|
|
313
|
+
container.append(hiddenInput);
|
|
314
|
+
} else {
|
|
315
|
+
$.each(selectedValues, function (index, value) {
|
|
316
|
+
var hiddenInput = $('<input type="hidden" class="cms-hidden-input">')
|
|
317
|
+
.attr('name', inputName)
|
|
318
|
+
.attr('value', value)
|
|
319
|
+
.attr('data-cms-input', this.settings.name)
|
|
320
|
+
.attr('data-cms-value', value);
|
|
321
|
+
container.append(hiddenInput);
|
|
322
|
+
}.bind(this));
|
|
323
|
+
}
|
|
324
|
+
} else {
|
|
325
|
+
var value = selectedValues.length > 0 ? selectedValues[0] : '';
|
|
326
|
+
var hiddenInput = $('<input type="hidden" class="cms-hidden-input">')
|
|
327
|
+
.attr('name', inputName)
|
|
328
|
+
.attr('value', value)
|
|
329
|
+
.attr('data-cms-input', this.settings.name);
|
|
330
|
+
container.append(hiddenInput);
|
|
331
|
+
}
|
|
332
|
+
},
|
|
333
|
+
|
|
334
|
+
createWrapper: function () {
|
|
335
|
+
return $('<div class="cms-wrapper"></div>');
|
|
336
|
+
},
|
|
337
|
+
|
|
338
|
+
createTrigger: function () {
|
|
339
|
+
return $('<div class="cms-trigger"><span class="cms-selected-text cms-placeholder">' +
|
|
340
|
+
this.settings.placeholder + '</span></div>');
|
|
341
|
+
},
|
|
342
|
+
|
|
343
|
+
createDropdown: function () {
|
|
344
|
+
return $('<div class="cms-dropdown"></div>');
|
|
345
|
+
},
|
|
346
|
+
|
|
347
|
+
createSearchInput: function () {
|
|
348
|
+
return $('<div class="cms-search-wrapper">' +
|
|
349
|
+
'<input type="text" class="cms-search-input" placeholder="' +
|
|
350
|
+
this.settings.searchPlaceholder + '" /></div>');
|
|
351
|
+
},
|
|
352
|
+
|
|
353
|
+
createOptionsContainer: function () {
|
|
354
|
+
return $('<div class="cms-options-container"></div>');
|
|
355
|
+
},
|
|
356
|
+
|
|
357
|
+
createPreloader: function () {
|
|
358
|
+
return $('<div class="cms-infinity-preloader"><div class="cms-spinner"></div></div>');
|
|
359
|
+
},
|
|
360
|
+
|
|
361
|
+
createButtons: function () {
|
|
362
|
+
var container = $('<div class="cms-buttons"></div>');
|
|
363
|
+
this.okBtn = $('<button class="cms-btn cms-btn-ok">' + this.settings.okText + '</button>');
|
|
364
|
+
this.cancelBtn = $('<button class="cms-btn cms-btn-cancel">' + this.settings.cancelText + '</button>');
|
|
365
|
+
|
|
366
|
+
container.append(this.okBtn);
|
|
367
|
+
container.append(this.cancelBtn);
|
|
368
|
+
|
|
369
|
+
return container;
|
|
370
|
+
},
|
|
371
|
+
|
|
372
|
+
renderOptions: function () {
|
|
373
|
+
this.optionsContainer.empty();
|
|
374
|
+
|
|
375
|
+
var selectAllOption = this.createOption('select-all', this.settings.selectAllText, false);
|
|
376
|
+
this.optionsContainer.append(selectAllOption);
|
|
377
|
+
|
|
378
|
+
var self = this;
|
|
379
|
+
$.each(this.settings.data, function (key, label) {
|
|
380
|
+
// For object: key = form value, label = display text
|
|
381
|
+
// For array: key = index, label = item
|
|
382
|
+
var value = key;
|
|
383
|
+
var label = label;
|
|
384
|
+
|
|
385
|
+
var isSelected = self.isValueSelected(value);
|
|
386
|
+
var option = self.createOption(value, label, isSelected);
|
|
387
|
+
self.optionsContainer.append(option);
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
this.updateSelectAllState();
|
|
391
|
+
},
|
|
392
|
+
htmlEncode: function (str) {
|
|
393
|
+
return String(str)
|
|
394
|
+
.replace(/&/g, "&")
|
|
395
|
+
.replace(/</g, "<")
|
|
396
|
+
.replace(/>/g, ">")
|
|
397
|
+
.replace(/"/g, """)
|
|
398
|
+
.replace(/'/g, "'");
|
|
399
|
+
},
|
|
400
|
+
|
|
401
|
+
isValueSelected: function (value) {
|
|
402
|
+
if (!this.settings.value) return false;
|
|
403
|
+
if (Array.isArray(this.settings.value)) {
|
|
404
|
+
var strValue = String(value).trim();
|
|
405
|
+
return this.settings.value.some(function (v) {
|
|
406
|
+
return String(v).trim() === strValue;
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
return String(this.settings.value).trim() === String(value).trim();
|
|
410
|
+
},
|
|
411
|
+
|
|
412
|
+
/**
|
|
413
|
+
* Update the data-ones-value attribute to keep it in sync with settings.value
|
|
414
|
+
* Removes attribute if value is empty, otherwise sets it to JSON array
|
|
415
|
+
*/
|
|
416
|
+
updateDataValueAttribute: function () {
|
|
417
|
+
if (!this.settings.value || this.settings.value.length === 0) {
|
|
418
|
+
// Remove attribute completely when empty
|
|
419
|
+
this.$element.removeAttr('data-ones-value');
|
|
420
|
+
} else {
|
|
421
|
+
// Update with current value as JSON
|
|
422
|
+
this.$element.attr('data-ones-value', JSON.stringify(this.settings.value));
|
|
423
|
+
}
|
|
424
|
+
},
|
|
425
|
+
|
|
426
|
+
/**
|
|
427
|
+
* Append new options to existing list (for pagination)
|
|
428
|
+
* @param {Object} data - New data to append
|
|
429
|
+
*/
|
|
430
|
+
appendOptions: function (data) {
|
|
431
|
+
var self = this;
|
|
432
|
+
$.each(data, function (key, label) {
|
|
433
|
+
var value = key;
|
|
434
|
+
var label = label;
|
|
435
|
+
|
|
436
|
+
// Check if option already exists
|
|
437
|
+
var existingOption = self.optionsContainer.find('.cms-option[data-value="' + self.htmlEncode(value) + '"]');
|
|
438
|
+
if (existingOption.length > 0) {
|
|
439
|
+
return; // Skip if already exists
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
var isSelected = self.isValueSelected(value);
|
|
443
|
+
var option = self.createOption(value, label, isSelected);
|
|
444
|
+
self.optionsContainer.append(option);
|
|
445
|
+
});
|
|
446
|
+
|
|
447
|
+
this.updateSelectAllState();
|
|
448
|
+
},
|
|
449
|
+
|
|
450
|
+
createOption: function (value, label, checked) {
|
|
451
|
+
var optionClass = 'cms-option';
|
|
452
|
+
if (!this.settings.showCheckbox) {
|
|
453
|
+
optionClass += ' cms-hide-checkbox';
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (checked && value !== 'select-all') {
|
|
457
|
+
optionClass += ' selected';
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
var option = $('<div class="' + optionClass + '" data-value="' + this.htmlEncode(value) + '"></div>');
|
|
461
|
+
var checkbox = $('<input type="checkbox" value="' + this.htmlEncode(value) + '"' +
|
|
462
|
+
(checked ? ' checked' : '') + '>');
|
|
463
|
+
var labelEl = $('<label>' + label + '</label>');
|
|
464
|
+
|
|
465
|
+
option.append(checkbox);
|
|
466
|
+
option.append(labelEl);
|
|
467
|
+
|
|
468
|
+
return option;
|
|
469
|
+
},
|
|
470
|
+
|
|
471
|
+
/**
|
|
472
|
+
* Filter options based on search text
|
|
473
|
+
* @param {String} searchText - Search text to filter by
|
|
474
|
+
*/
|
|
475
|
+
filterOptions: function (searchText) {
|
|
476
|
+
var self = this;
|
|
477
|
+
var options = this.optionsContainer.find('.cms-option:not([data-value="select-all"])');
|
|
478
|
+
|
|
479
|
+
if (searchText === '') {
|
|
480
|
+
// Show all options if search is empty
|
|
481
|
+
options.show();
|
|
482
|
+
} else {
|
|
483
|
+
// Filter options by label
|
|
484
|
+
options.each(function () {
|
|
485
|
+
var option = $(this);
|
|
486
|
+
var label = option.find('label').text().toLowerCase();
|
|
487
|
+
|
|
488
|
+
if (label.indexOf(searchText) !== -1) {
|
|
489
|
+
option.show();
|
|
490
|
+
} else {
|
|
491
|
+
option.hide();
|
|
492
|
+
}
|
|
493
|
+
});
|
|
494
|
+
}
|
|
495
|
+
},
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Perform AJAX search
|
|
499
|
+
* @param {String} searchText - Search text to send to server
|
|
500
|
+
*/
|
|
501
|
+
performAjaxSearch: function (searchText) {
|
|
502
|
+
var self = this;
|
|
503
|
+
|
|
504
|
+
// Show loading state
|
|
505
|
+
this.optionsContainer.addClass('cms-loading');
|
|
506
|
+
|
|
507
|
+
$.ajax({
|
|
508
|
+
url: this.settings.searchUrl,
|
|
509
|
+
method: 'GET',
|
|
510
|
+
data: { q: searchText },
|
|
511
|
+
dataType: 'json',
|
|
512
|
+
success: function (response) {
|
|
513
|
+
// Handle different response formats
|
|
514
|
+
var data = response;
|
|
515
|
+
if (typeof response === 'object' && response.data) {
|
|
516
|
+
data = response.data;
|
|
517
|
+
} else if (typeof response === 'object' && response.results) {
|
|
518
|
+
data = response.results;
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
// Update dropdown with search results
|
|
522
|
+
self.updateSearchResults(data || []);
|
|
523
|
+
|
|
524
|
+
self.optionsContainer.removeClass('cms-loading');
|
|
525
|
+
},
|
|
526
|
+
error: function (xhr, status, error) {
|
|
527
|
+
console.error('OneSelect: Search error', error);
|
|
528
|
+
self.optionsContainer.removeClass('cms-loading');
|
|
529
|
+
|
|
530
|
+
if (self.settings.onLoadError) {
|
|
531
|
+
self.settings.onLoadError.call(self, xhr, status, error);
|
|
532
|
+
}
|
|
533
|
+
}
|
|
534
|
+
});
|
|
535
|
+
},
|
|
536
|
+
|
|
537
|
+
/**
|
|
538
|
+
* Update dropdown with search results
|
|
539
|
+
* @param {Array} data - Search results data
|
|
540
|
+
*/
|
|
541
|
+
updateSearchResults: function (data) {
|
|
542
|
+
// Clear existing options (except select-all)
|
|
543
|
+
this.optionsContainer.find('.cms-option:not([data-value="select-all"])').remove();
|
|
544
|
+
|
|
545
|
+
var self = this;
|
|
546
|
+
$.each(data, function (key, label) {
|
|
547
|
+
// For object: key = form value, label = display text
|
|
548
|
+
// For array: key = index, label = item
|
|
549
|
+
var value = key;
|
|
550
|
+
var label = label;
|
|
551
|
+
|
|
552
|
+
var isSelected = self.isValueSelected(value);
|
|
553
|
+
var option = self.createOption(value, label, isSelected);
|
|
554
|
+
self.optionsContainer.append(option);
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
// Update select-all state
|
|
558
|
+
this.updateSelectAllState();
|
|
559
|
+
},
|
|
560
|
+
|
|
561
|
+
attachEvents: function () {
|
|
562
|
+
var self = this;
|
|
563
|
+
|
|
564
|
+
this.trigger.on('click', function (e) {
|
|
565
|
+
e.stopPropagation();
|
|
566
|
+
self.toggle();
|
|
567
|
+
});
|
|
568
|
+
|
|
569
|
+
// Search input event listener
|
|
570
|
+
if (this.settings.showSearch) {
|
|
571
|
+
if (this.settings.searchUrl) {
|
|
572
|
+
// AJAX search with debounce
|
|
573
|
+
var debouncedSearch = debounce(function (searchText) {
|
|
574
|
+
self.performAjaxSearch(searchText);
|
|
575
|
+
}, this.settings.searchDebounceDelay);
|
|
576
|
+
|
|
577
|
+
this.searchInput.find('.cms-search-input').on('keyup', function () {
|
|
578
|
+
var searchText = $(this).val();
|
|
579
|
+
if (searchText.length > 0) {
|
|
580
|
+
debouncedSearch(searchText);
|
|
581
|
+
} else {
|
|
582
|
+
// Show original data when search is empty
|
|
583
|
+
self.filterOptions('');
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
} else {
|
|
587
|
+
// Local filtering (default)
|
|
588
|
+
this.searchInput.find('.cms-search-input').on('keyup', function () {
|
|
589
|
+
var searchText = $(this).val().toLowerCase();
|
|
590
|
+
self.filterOptions(searchText);
|
|
591
|
+
});
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
$(window).on('resize.cms', function () {
|
|
596
|
+
if (self.wrapper.hasClass('open')) {
|
|
597
|
+
self.updateDropdownPosition();
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
|
|
601
|
+
if (this.settings.closeOnScroll) {
|
|
602
|
+
$(window).on('scroll.cms', function () {
|
|
603
|
+
if (self.wrapper.hasClass('open')) {
|
|
604
|
+
self.close();
|
|
605
|
+
}
|
|
606
|
+
});
|
|
607
|
+
} else {
|
|
608
|
+
// Update dropdown position on vertical scroll
|
|
609
|
+
$(window).on('scroll.cms', function () {
|
|
610
|
+
if (self.wrapper.hasClass('open')) {
|
|
611
|
+
self.updateDropdownPosition();
|
|
612
|
+
}
|
|
613
|
+
});
|
|
614
|
+
}
|
|
615
|
+
|
|
616
|
+
// Global horizontal scroll handler - close dropdown on any horizontal scroll
|
|
617
|
+
// Listen for wheel events with horizontal delta
|
|
618
|
+
$(document).on('wheel.onescroll', function (e) {
|
|
619
|
+
if (!self.wrapper.hasClass('open')) {
|
|
620
|
+
return;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Check if horizontal scrolling (deltaX != 0)
|
|
624
|
+
if (e.originalEvent && Math.abs(e.originalEvent.deltaX) > 0) {
|
|
625
|
+
self.close();
|
|
626
|
+
}
|
|
627
|
+
});
|
|
628
|
+
|
|
629
|
+
// Also listen for scroll events on all elements to detect horizontal scroll
|
|
630
|
+
// Using MutationObserver to detect when elements with overflow scroll
|
|
631
|
+
self._detectHorizontalScroll = function () {
|
|
632
|
+
if (!self.wrapper.hasClass('open')) return;
|
|
633
|
+
|
|
634
|
+
// Check window horizontal scroll
|
|
635
|
+
if (window.scrollX !== self._lastWindowScrollX) {
|
|
636
|
+
self._lastWindowScrollX = window.scrollX;
|
|
637
|
+
if (self._lastWindowScrollX > 0) {
|
|
638
|
+
self.close();
|
|
639
|
+
return;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
// Check all scrollable elements for horizontal scroll
|
|
644
|
+
var scrollableElements = document.querySelectorAll('*');
|
|
645
|
+
for (var i = 0; i < scrollableElements.length; i++) {
|
|
646
|
+
var el = scrollableElements[i];
|
|
647
|
+
var key = getElementKey(el);
|
|
648
|
+
|
|
649
|
+
if (self._elementScrollPositions[key] !== undefined) {
|
|
650
|
+
var currentScroll = el.scrollLeft;
|
|
651
|
+
if (currentScroll !== self._elementScrollPositions[key]) {
|
|
652
|
+
// Horizontal scroll detected
|
|
653
|
+
self.close();
|
|
654
|
+
return;
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
};
|
|
659
|
+
|
|
660
|
+
// Store scroll positions and track changes
|
|
661
|
+
self._elementScrollPositions = {};
|
|
662
|
+
self._lastWindowScrollX = window.scrollX;
|
|
663
|
+
|
|
664
|
+
function getElementKey(el) {
|
|
665
|
+
if (el === document) return 'document';
|
|
666
|
+
if (el === document.documentElement) return 'html';
|
|
667
|
+
if (el === document.body) return 'body';
|
|
668
|
+
return el.tagName + '-' + (el.id || el.className || Math.random().toString(36).substr(2, 9));
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
// Override open to initialize tracking
|
|
672
|
+
var originalOpen = self.open.bind(self);
|
|
673
|
+
self.open = function () {
|
|
674
|
+
// Store initial scroll positions
|
|
675
|
+
self._elementScrollPositions = {};
|
|
676
|
+
self._lastWindowScrollX = window.scrollX;
|
|
677
|
+
|
|
678
|
+
var scrollableElements = document.querySelectorAll('*');
|
|
679
|
+
for (var i = 0; i < scrollableElements.length; i++) {
|
|
680
|
+
var el = scrollableElements[i];
|
|
681
|
+
if (el.scrollWidth > el.clientWidth || el.scrollHeight > el.clientHeight) {
|
|
682
|
+
self._elementScrollPositions[getElementKey(el)] = el.scrollLeft;
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
|
|
686
|
+
// Start checking periodically
|
|
687
|
+
if (self._horizontalScrollInterval) {
|
|
688
|
+
clearInterval(self._horizontalScrollInterval);
|
|
689
|
+
}
|
|
690
|
+
self._horizontalScrollInterval = setInterval(function () {
|
|
691
|
+
self._detectHorizontalScroll();
|
|
692
|
+
}, 50);
|
|
693
|
+
|
|
694
|
+
originalOpen();
|
|
695
|
+
};
|
|
696
|
+
|
|
697
|
+
// Override close to stop tracking
|
|
698
|
+
var originalClose = self.close.bind(self);
|
|
699
|
+
self.close = function () {
|
|
700
|
+
if (self._horizontalScrollInterval) {
|
|
701
|
+
clearInterval(self._horizontalScrollInterval);
|
|
702
|
+
self._horizontalScrollInterval = null;
|
|
703
|
+
}
|
|
704
|
+
self._elementScrollPositions = {};
|
|
705
|
+
originalClose();
|
|
706
|
+
};
|
|
707
|
+
|
|
708
|
+
// Window click handler - close dropdown when clicking outside
|
|
709
|
+
$(window).on('click.ones', function (e) {
|
|
710
|
+
if (!self.settings.closeOnOutside) {
|
|
711
|
+
return;
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
if (!self.wrapper.hasClass('open')) {
|
|
715
|
+
return;
|
|
716
|
+
}
|
|
717
|
+
|
|
718
|
+
var $target = $(e.target);
|
|
719
|
+
// Don't close if clicked inside dropdown or wrapper elements
|
|
720
|
+
if ($target.closest('.cms-wrapper').length > 0 ||
|
|
721
|
+
$target.closest('.cms-dropdown').length > 0) {
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
|
|
725
|
+
// Submit form if submitOnOutside is enabled
|
|
726
|
+
if (self.settings.submitOnOutside) {
|
|
727
|
+
self.updateTriggerText();
|
|
728
|
+
if (self.settings.onOk) {
|
|
729
|
+
self.settings.onOk.call(self, self.getSelectedValues(), self.getSelectedLabels());
|
|
730
|
+
}
|
|
731
|
+
self.submitForm();
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
self.close();
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
this.optionsContainer.on('click', '.cms-option', function (e) {
|
|
738
|
+
var $target = $(e.target);
|
|
739
|
+
|
|
740
|
+
// If clicking label or checkbox, browser already handles toggle
|
|
741
|
+
if ($target.is('input[type="checkbox"]') || $target.closest('label').length > 0 || $target.closest('button').length > 0) {
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
|
|
745
|
+
e.preventDefault();
|
|
746
|
+
e.stopPropagation();
|
|
747
|
+
|
|
748
|
+
var option = $(this);
|
|
749
|
+
var checkbox = option.find('input[type="checkbox"]');
|
|
750
|
+
checkbox.prop('checked', !checkbox.prop('checked')).trigger('change');
|
|
751
|
+
});
|
|
752
|
+
|
|
753
|
+
this.optionsContainer.on('change', 'input[type="checkbox"]', function (e) {
|
|
754
|
+
e.stopPropagation();
|
|
755
|
+
var checkbox = $(this);
|
|
756
|
+
var option = checkbox.closest('.cms-option');
|
|
757
|
+
var value = option.data('value');
|
|
758
|
+
|
|
759
|
+
if (value === 'select-all') {
|
|
760
|
+
self.handleSelectAll(checkbox.prop('checked'));
|
|
761
|
+
} else {
|
|
762
|
+
self.handleOptionChange(option);
|
|
763
|
+
}
|
|
764
|
+
});
|
|
765
|
+
|
|
766
|
+
this.okBtn.on('click', function (e) {
|
|
767
|
+
e.stopPropagation();
|
|
768
|
+
self.handleOk();
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
this.cancelBtn.on('click', function (e) {
|
|
772
|
+
e.stopPropagation();
|
|
773
|
+
self.handleCancel();
|
|
774
|
+
});
|
|
775
|
+
|
|
776
|
+
// Infinity Scroll with Debounce - only activate if AJAX is configured
|
|
777
|
+
if (this.settings.infinityScroll && this.settings.ajax && this.settings.ajax.url) {
|
|
778
|
+
var debouncedScroll = debounce(function () {
|
|
779
|
+
// Check if we have more pages to load
|
|
780
|
+
if (!self.hasNextPage) {
|
|
781
|
+
return;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
if (!self.settings.loading) { // Double check loading state
|
|
785
|
+
self.loadNextPage();
|
|
786
|
+
}
|
|
787
|
+
}, 200); // 200ms debounce delay
|
|
788
|
+
|
|
789
|
+
this.optionsContainer.on('scroll', function () {
|
|
790
|
+
var container = $(this);
|
|
791
|
+
if (container.scrollTop() + container.innerHeight() >= container[0].scrollHeight - 50) {
|
|
792
|
+
debouncedScroll();
|
|
793
|
+
}
|
|
794
|
+
});
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
// Legacy onInfinityScroll callback support (deprecated)
|
|
798
|
+
if (this.settings.infinityScroll && this.settings.onInfinityScroll && !this.settings.ajax) {
|
|
799
|
+
console.warn('OneSelect: infinityScroll requires ajax configuration. onInfinityScroll callback is deprecated.');
|
|
800
|
+
}
|
|
801
|
+
},
|
|
802
|
+
|
|
803
|
+
handleOptionChange: function (option) {
|
|
804
|
+
var value = option.data('value');
|
|
805
|
+
var checkbox = option.find('input[type="checkbox"]');
|
|
806
|
+
var isChecked = checkbox.prop('checked');
|
|
807
|
+
|
|
808
|
+
if (isChecked) {
|
|
809
|
+
this.select(value);
|
|
810
|
+
} else {
|
|
811
|
+
this.unselect(value);
|
|
812
|
+
}
|
|
813
|
+
|
|
814
|
+
if (this.settings.onChange) {
|
|
815
|
+
this.settings.onChange.call(this, this.getSelectedValues(), this.getSelectedLabels());
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
if (this.settings.onSelect) {
|
|
819
|
+
this.settings.onSelect.call(this, this.getSelectedValues());
|
|
820
|
+
}
|
|
821
|
+
},
|
|
822
|
+
|
|
823
|
+
handleSelectAll: function (checked) {
|
|
824
|
+
var self = this;
|
|
825
|
+
if (!checked) {
|
|
826
|
+
// Clear all selection (including hidden ones)
|
|
827
|
+
if (Array.isArray(this.settings.value)) {
|
|
828
|
+
this.settings.value = [];
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
this.optionsContainer.find('.cms-option:not([data-value="select-all"])').each(function () {
|
|
833
|
+
var option = $(this);
|
|
834
|
+
option.find('input[type="checkbox"]').prop('checked', checked);
|
|
835
|
+
if (checked) {
|
|
836
|
+
option.addClass('selected');
|
|
837
|
+
// Add to settings.value if not exists
|
|
838
|
+
var val = option.find('input[type="checkbox"]').val();
|
|
839
|
+
if (Array.isArray(self.settings.value)) {
|
|
840
|
+
if (!self.isValueSelected(val)) {
|
|
841
|
+
self.settings.value.push(val);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
} else {
|
|
845
|
+
option.removeClass('selected');
|
|
846
|
+
}
|
|
847
|
+
});
|
|
848
|
+
|
|
849
|
+
this.updateSelectAllState();
|
|
850
|
+
this.updateTriggerText();
|
|
851
|
+
this.updateHiddenInputs();
|
|
852
|
+
this.updateDataValueAttribute();
|
|
853
|
+
},
|
|
854
|
+
|
|
855
|
+
updateSelectAllState: function () {
|
|
856
|
+
var allOptions = this.optionsContainer.find('.cms-option:not([data-value="select-all"]) input[type="checkbox"]');
|
|
857
|
+
var checkedOptions = allOptions.filter(':checked');
|
|
858
|
+
var totalCount = allOptions.length;
|
|
859
|
+
var checkedCount = checkedOptions.length;
|
|
860
|
+
|
|
861
|
+
var selectAllCheckbox = this.optionsContainer.find('.cms-option[data-value="select-all"] input[type="checkbox"]');
|
|
862
|
+
|
|
863
|
+
selectAllCheckbox.prop('indeterminate', false);
|
|
864
|
+
selectAllCheckbox.prop('checked', false);
|
|
865
|
+
|
|
866
|
+
if (checkedCount === 0) {
|
|
867
|
+
// Nothing selected
|
|
868
|
+
} else if (checkedCount === totalCount && totalCount > 0) {
|
|
869
|
+
selectAllCheckbox.prop('checked', true);
|
|
870
|
+
} else {
|
|
871
|
+
selectAllCheckbox.prop('indeterminate', true);
|
|
872
|
+
}
|
|
873
|
+
},
|
|
874
|
+
|
|
875
|
+
getSelectedValues: function () {
|
|
876
|
+
// Return unique sanitized settings.value
|
|
877
|
+
if (!Array.isArray(this.settings.value)) {
|
|
878
|
+
return [];
|
|
879
|
+
}
|
|
880
|
+
return this.settings.value;
|
|
881
|
+
},
|
|
882
|
+
|
|
883
|
+
getSelectedLabels: function () {
|
|
884
|
+
var labels = [];
|
|
885
|
+
this.optionsContainer.find('.cms-option:not([data-value="select-all"]) input[type="checkbox"]:checked')
|
|
886
|
+
.siblings('label')
|
|
887
|
+
.each(function () {
|
|
888
|
+
labels.push($(this).text());
|
|
889
|
+
});
|
|
890
|
+
return labels;
|
|
891
|
+
},
|
|
892
|
+
|
|
893
|
+
updateTriggerText: function () {
|
|
894
|
+
var labels = this.getSelectedLabels();
|
|
895
|
+
var values = this.getSelectedValues();
|
|
896
|
+
var totalCount = this.settings.value ? this.settings.value.length : 0;
|
|
897
|
+
|
|
898
|
+
var textSpan = this.trigger.find('.cms-selected-text');
|
|
899
|
+
|
|
900
|
+
if (labels.length === 0) {
|
|
901
|
+
textSpan.empty().text(this.settings.placeholder).addClass('cms-placeholder');
|
|
902
|
+
} else if (this.settings.showBadges) {
|
|
903
|
+
textSpan.empty().removeClass('cms-placeholder');
|
|
904
|
+
|
|
905
|
+
var self = this;
|
|
906
|
+
var self = this;
|
|
907
|
+
$.each(values, function (index, value) {
|
|
908
|
+
var badge = $('<span class="cms-badge"></span>');
|
|
909
|
+
|
|
910
|
+
// Find label from DOM (if exists) or fallback to value
|
|
911
|
+
var labelText = value;
|
|
912
|
+
var option = self.optionsContainer.find('.cms-option[data-value="' + self.htmlEncode(value) + '"]');
|
|
913
|
+
if (option.length) {
|
|
914
|
+
labelText = option.find('label').text();
|
|
915
|
+
}
|
|
916
|
+
|
|
917
|
+
var labelSpan = $('<span></span>').text(labelText);
|
|
918
|
+
var removeBtn = $('<button type="button" class="cms-badge-remove">×</button>');
|
|
919
|
+
|
|
920
|
+
removeBtn.on('click', function (e) {
|
|
921
|
+
e.stopPropagation();
|
|
922
|
+
self.unselect(value);
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
badge.append(labelSpan);
|
|
926
|
+
badge.append(removeBtn);
|
|
927
|
+
textSpan.append(badge);
|
|
928
|
+
});
|
|
929
|
+
} else {
|
|
930
|
+
textSpan.empty().removeClass('cms-placeholder');
|
|
931
|
+
textSpan.text(totalCount + ' items selected');
|
|
932
|
+
}
|
|
933
|
+
|
|
934
|
+
this.updateExternalBadges(values, labels);
|
|
935
|
+
},
|
|
936
|
+
|
|
937
|
+
updateExternalBadges: function (values, labels) {
|
|
938
|
+
if (!this.settings.showBadgesExternal) {
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
|
|
942
|
+
var $externalContainer = $('#' + this.settings.showBadgesExternal);
|
|
943
|
+
|
|
944
|
+
if ($externalContainer.length === 0) {
|
|
945
|
+
console.warn('OneSelect: External container not found - #' + this.settings.showBadgesExternal);
|
|
946
|
+
return;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
$externalContainer.empty();
|
|
950
|
+
|
|
951
|
+
if (values.length === 0) {
|
|
952
|
+
return;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
var self = this;
|
|
956
|
+
$.each(values, function (index, value) {
|
|
957
|
+
var badge = $('<span class="cms-badge"></span>');
|
|
958
|
+
var labelSpan = $('<span></span>').text(labels[index]);
|
|
959
|
+
var removeBtn = $('<button type="button" class="cms-badge-remove">×</button>');
|
|
960
|
+
|
|
961
|
+
removeBtn.on('click', function (e) {
|
|
962
|
+
e.preventDefault();
|
|
963
|
+
e.stopPropagation();
|
|
964
|
+
self.unselect(value);
|
|
965
|
+
});
|
|
966
|
+
|
|
967
|
+
badge.append(labelSpan);
|
|
968
|
+
badge.append(removeBtn);
|
|
969
|
+
$externalContainer.append(badge);
|
|
970
|
+
});
|
|
971
|
+
},
|
|
972
|
+
|
|
973
|
+
toggle: function () {
|
|
974
|
+
if (this.wrapper.hasClass('open')) {
|
|
975
|
+
this.close();
|
|
976
|
+
} else {
|
|
977
|
+
this.open();
|
|
978
|
+
}
|
|
979
|
+
},
|
|
980
|
+
|
|
981
|
+
open: function () {
|
|
982
|
+
// Close other open dropdowns
|
|
983
|
+
$('.cms-wrapper.open').not(this.wrapper).removeClass('open');
|
|
984
|
+
$('.cms-dropdown.open').not(this.dropdown).removeClass('open');
|
|
985
|
+
|
|
986
|
+
// Calculate position
|
|
987
|
+
this.updateDropdownPosition();
|
|
988
|
+
|
|
989
|
+
this.wrapper.addClass('open');
|
|
990
|
+
this.dropdown.addClass('open');
|
|
991
|
+
},
|
|
992
|
+
|
|
993
|
+
updateDropdownPosition: function () {
|
|
994
|
+
var rect = this.wrapper[0].getBoundingClientRect();
|
|
995
|
+
var wrapperHeight = this.wrapper.outerHeight();
|
|
996
|
+
var wrapperWidth = this.wrapper.outerWidth();
|
|
997
|
+
|
|
998
|
+
this.dropdown.css({
|
|
999
|
+
position: 'fixed',
|
|
1000
|
+
top: rect.bottom + 'px',
|
|
1001
|
+
left: rect.left + 'px',
|
|
1002
|
+
width: wrapperWidth + 'px'
|
|
1003
|
+
});
|
|
1004
|
+
},
|
|
1005
|
+
|
|
1006
|
+
close: function () {
|
|
1007
|
+
this.wrapper.removeClass('open');
|
|
1008
|
+
this.dropdown.removeClass('open');
|
|
1009
|
+
},
|
|
1010
|
+
|
|
1011
|
+
handleOk: function () {
|
|
1012
|
+
this.updateTriggerText();
|
|
1013
|
+
|
|
1014
|
+
var values = this.getSelectedValues();
|
|
1015
|
+
var labels = this.getSelectedLabels();
|
|
1016
|
+
|
|
1017
|
+
if (this.settings.onOk) {
|
|
1018
|
+
this.settings.onOk.call(this, values, labels);
|
|
1019
|
+
}
|
|
1020
|
+
|
|
1021
|
+
if (this.settings.submitForm) {
|
|
1022
|
+
this.submitForm();
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
this.updateDataValueAttribute();
|
|
1026
|
+
this.close();
|
|
1027
|
+
},
|
|
1028
|
+
|
|
1029
|
+
submitForm: function () {
|
|
1030
|
+
var form = null;
|
|
1031
|
+
|
|
1032
|
+
if (this.settings.formId) {
|
|
1033
|
+
form = $('#' + this.settings.formId);
|
|
1034
|
+
if (form.length === 0) {
|
|
1035
|
+
console.warn('OneSelect: Form with ID "' + this.settings.formId + '" not found');
|
|
1036
|
+
return;
|
|
1037
|
+
}
|
|
1038
|
+
} else {
|
|
1039
|
+
form = this.$element.closest('form');
|
|
1040
|
+
if (form.length === 0) {
|
|
1041
|
+
console.warn('OneSelect: No parent form found');
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
}
|
|
1045
|
+
|
|
1046
|
+
form[0].submit();
|
|
1047
|
+
},
|
|
1048
|
+
|
|
1049
|
+
handleCancel: function () {
|
|
1050
|
+
this.settings.value = [];
|
|
1051
|
+
this.optionsContainer.find('input[type="checkbox"]').prop('checked', false);
|
|
1052
|
+
this.optionsContainer.find('.cms-option').removeClass('selected');
|
|
1053
|
+
this.updateSelectAllState();
|
|
1054
|
+
this.updateTriggerText();
|
|
1055
|
+
this.updateHiddenInputs();
|
|
1056
|
+
this.updateDataValueAttribute();
|
|
1057
|
+
|
|
1058
|
+
if (this.settings.onCancel) {
|
|
1059
|
+
this.settings.onCancel.call(this);
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
if (this.settings.submitForm) {
|
|
1063
|
+
this.submitForm();
|
|
1064
|
+
}
|
|
1065
|
+
|
|
1066
|
+
this.close();
|
|
1067
|
+
},
|
|
1068
|
+
|
|
1069
|
+
setValue: function (values) {
|
|
1070
|
+
this.settings.value = values || [];
|
|
1071
|
+
this.renderOptions();
|
|
1072
|
+
this.updateTriggerText();
|
|
1073
|
+
this.updateHiddenInputs();
|
|
1074
|
+
this.updateDataValueAttribute();
|
|
1075
|
+
},
|
|
1076
|
+
|
|
1077
|
+
getValue: function () {
|
|
1078
|
+
return this.getSelectedValues();
|
|
1079
|
+
},
|
|
1080
|
+
|
|
1081
|
+
updateData: function (data) {
|
|
1082
|
+
this.settings.data = data || [];
|
|
1083
|
+
this.settings.value = [];
|
|
1084
|
+
this.renderOptions();
|
|
1085
|
+
this.updateTriggerText();
|
|
1086
|
+
this.updateHiddenInputs();
|
|
1087
|
+
this.updateDataValueAttribute();
|
|
1088
|
+
},
|
|
1089
|
+
|
|
1090
|
+
loadData: function (customAjaxConfig, onSuccess, onError, appendData) {
|
|
1091
|
+
var self = this;
|
|
1092
|
+
var ajaxConfig = customAjaxConfig || this.settings.ajax;
|
|
1093
|
+
|
|
1094
|
+
if (!ajaxConfig || !ajaxConfig.url) {
|
|
1095
|
+
console.error('OneSelect: Ajax configuration or url is missing');
|
|
1096
|
+
return;
|
|
1097
|
+
}
|
|
1098
|
+
|
|
1099
|
+
if (this.settings.beforeLoad) {
|
|
1100
|
+
this.settings.beforeLoad.call(this);
|
|
1101
|
+
}
|
|
1102
|
+
|
|
1103
|
+
if (!appendData) {
|
|
1104
|
+
this.trigger.find('.cms-selected-text').text('Loading...');
|
|
1105
|
+
}
|
|
1106
|
+
|
|
1107
|
+
var request = $.extend(true, {
|
|
1108
|
+
url: ajaxConfig.url,
|
|
1109
|
+
method: ajaxConfig.method || 'GET',
|
|
1110
|
+
data: ajaxConfig.data || {},
|
|
1111
|
+
dataType: ajaxConfig.dataType || 'json',
|
|
1112
|
+
success: function (response) {
|
|
1113
|
+
var data = response;
|
|
1114
|
+
if (typeof response === 'object' && response.data) {
|
|
1115
|
+
data = response.data;
|
|
1116
|
+
} else if (typeof response === 'object' && response.results) {
|
|
1117
|
+
data = response.results;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
// Handle hasNextPage from response
|
|
1121
|
+
if (response && typeof response.hasNextPage !== 'undefined') {
|
|
1122
|
+
self.hasNextPage = response.hasNextPage;
|
|
1123
|
+
} else {
|
|
1124
|
+
self.hasNextPage = false;
|
|
1125
|
+
}
|
|
1126
|
+
|
|
1127
|
+
// Handle currentPage from response (optional)
|
|
1128
|
+
if (response && typeof response.currentPage !== 'undefined') {
|
|
1129
|
+
self.currentPage = response.currentPage;
|
|
1130
|
+
}
|
|
1131
|
+
|
|
1132
|
+
// Append or replace data
|
|
1133
|
+
if (appendData) {
|
|
1134
|
+
// Merge new data with existing data
|
|
1135
|
+
self.settings.data = $.extend({}, self.settings.data, data || {});
|
|
1136
|
+
self.appendOptions(data || {});
|
|
1137
|
+
} else {
|
|
1138
|
+
self.settings.data = data || [];
|
|
1139
|
+
self.renderOptions();
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1142
|
+
self.updateTriggerText();
|
|
1143
|
+
|
|
1144
|
+
if (self.settings.afterLoad) {
|
|
1145
|
+
self.settings.afterLoad.call(self, data, response);
|
|
1146
|
+
}
|
|
1147
|
+
|
|
1148
|
+
if (onSuccess) {
|
|
1149
|
+
onSuccess.call(self, data, response);
|
|
1150
|
+
}
|
|
1151
|
+
},
|
|
1152
|
+
error: function (xhr, status, error) {
|
|
1153
|
+
if (!appendData) {
|
|
1154
|
+
self.trigger.find('.cms-selected-text').text('Error loading data');
|
|
1155
|
+
}
|
|
1156
|
+
|
|
1157
|
+
if (self.settings.onLoadError) {
|
|
1158
|
+
self.settings.onLoadError.call(self, xhr, status, error);
|
|
1159
|
+
}
|
|
1160
|
+
|
|
1161
|
+
if (onError) {
|
|
1162
|
+
onError.call(self, xhr, status, error);
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
}, ajaxConfig);
|
|
1166
|
+
|
|
1167
|
+
if (ajaxConfig.success) {
|
|
1168
|
+
var originalSuccess = request.success;
|
|
1169
|
+
request.success = function (response) {
|
|
1170
|
+
ajaxConfig.success(response);
|
|
1171
|
+
originalSuccess(response);
|
|
1172
|
+
};
|
|
1173
|
+
}
|
|
1174
|
+
|
|
1175
|
+
if (ajaxConfig.error) {
|
|
1176
|
+
var originalError = request.error;
|
|
1177
|
+
request.error = function (xhr, status, error) {
|
|
1178
|
+
ajaxConfig.error(xhr, status, error);
|
|
1179
|
+
originalError(xhr, status, error);
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
$.ajax(request);
|
|
1184
|
+
},
|
|
1185
|
+
|
|
1186
|
+
loadNextPage: function () {
|
|
1187
|
+
var self = this;
|
|
1188
|
+
this.settings.loading = true;
|
|
1189
|
+
this.preloader.show();
|
|
1190
|
+
|
|
1191
|
+
var ajaxConfig = $.extend(true, {}, this.settings.ajax);
|
|
1192
|
+
ajaxConfig.data = ajaxConfig.data || {};
|
|
1193
|
+
ajaxConfig.data.page = this.currentPage + 1;
|
|
1194
|
+
|
|
1195
|
+
this.loadData(ajaxConfig, function (data, response) {
|
|
1196
|
+
self.settings.loading = false;
|
|
1197
|
+
self.preloader.hide();
|
|
1198
|
+
|
|
1199
|
+
if (!response.currentPage) {
|
|
1200
|
+
self.currentPage++;
|
|
1201
|
+
}
|
|
1202
|
+
}, function () {
|
|
1203
|
+
self.settings.loading = false;
|
|
1204
|
+
self.preloader.hide();
|
|
1205
|
+
}, true);
|
|
1206
|
+
},
|
|
1207
|
+
|
|
1208
|
+
reload: function () {
|
|
1209
|
+
if (this.settings.ajax) {
|
|
1210
|
+
this.loadData();
|
|
1211
|
+
} else {
|
|
1212
|
+
console.warn('OneSelect: No ajax configuration found');
|
|
1213
|
+
}
|
|
1214
|
+
},
|
|
1215
|
+
|
|
1216
|
+
select: function (value) {
|
|
1217
|
+
var self = this;
|
|
1218
|
+
var checkbox = this.optionsContainer.find('.cms-option:not([data-value="select-all"]) input[type="checkbox"][value="' + this.htmlEncode(value) + '"]');
|
|
1219
|
+
|
|
1220
|
+
if (checkbox.length) {
|
|
1221
|
+
checkbox.prop('checked', true);
|
|
1222
|
+
checkbox.closest('.cms-option').addClass('selected');
|
|
1223
|
+
}
|
|
1224
|
+
|
|
1225
|
+
if (Array.isArray(this.settings.value)) {
|
|
1226
|
+
if (!this.isValueSelected(value)) {
|
|
1227
|
+
this.settings.value.push(value);
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
this.updateSelectAllState();
|
|
1232
|
+
this.updateTriggerText();
|
|
1233
|
+
this.updateHiddenInputs();
|
|
1234
|
+
this.updateDataValueAttribute();
|
|
1235
|
+
},
|
|
1236
|
+
|
|
1237
|
+
unselect: function (value) {
|
|
1238
|
+
var self = this;
|
|
1239
|
+
var checkbox = this.optionsContainer.find('.cms-option:not([data-value="select-all"]) input[type="checkbox"][value="' + this.htmlEncode(value) + '"]');
|
|
1240
|
+
|
|
1241
|
+
if (checkbox.length) {
|
|
1242
|
+
checkbox.prop('checked', false);
|
|
1243
|
+
checkbox.closest('.cms-option').removeClass('selected');
|
|
1244
|
+
}
|
|
1245
|
+
|
|
1246
|
+
if (Array.isArray(this.settings.value)) {
|
|
1247
|
+
var strValue = String(value).trim();
|
|
1248
|
+
this.settings.value = this.settings.value.filter(function (v) {
|
|
1249
|
+
return String(v).trim() !== strValue;
|
|
1250
|
+
});
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
this.updateSelectAllState();
|
|
1254
|
+
this.updateTriggerText();
|
|
1255
|
+
this.updateHiddenInputs();
|
|
1256
|
+
this.updateDataValueAttribute();
|
|
1257
|
+
},
|
|
1258
|
+
|
|
1259
|
+
selectAll: function () {
|
|
1260
|
+
this.handleSelectAll(true);
|
|
1261
|
+
},
|
|
1262
|
+
|
|
1263
|
+
unselectAll: function () {
|
|
1264
|
+
this.handleSelectAll(false);
|
|
1265
|
+
},
|
|
1266
|
+
|
|
1267
|
+
toggleSelection: function (value) {
|
|
1268
|
+
var checkbox = this.optionsContainer.find('.cms-option:not([data-value="select-all"]) input[type="checkbox"][value="' + this.htmlEncode(value) + '"]');
|
|
1269
|
+
if (checkbox.length) {
|
|
1270
|
+
var isChecked = checkbox.prop('checked');
|
|
1271
|
+
checkbox.prop('checked', !isChecked);
|
|
1272
|
+
|
|
1273
|
+
var option = checkbox.closest('.cms-option');
|
|
1274
|
+
if (!isChecked) {
|
|
1275
|
+
option.addClass('selected');
|
|
1276
|
+
if (Array.isArray(this.settings.value)) {
|
|
1277
|
+
if (!this.isValueSelected(value)) {
|
|
1278
|
+
this.settings.value.push(value);
|
|
1279
|
+
}
|
|
1280
|
+
}
|
|
1281
|
+
} else {
|
|
1282
|
+
option.removeClass('selected');
|
|
1283
|
+
if (Array.isArray(this.settings.value)) {
|
|
1284
|
+
var strValue = String(value).trim();
|
|
1285
|
+
this.settings.value = this.settings.value.filter(function (v) { return String(v).trim() !== strValue });
|
|
1286
|
+
}
|
|
1287
|
+
}
|
|
1288
|
+
|
|
1289
|
+
this.updateSelectAllState();
|
|
1290
|
+
this.updateTriggerText();
|
|
1291
|
+
this.updateHiddenInputs();
|
|
1292
|
+
}
|
|
1293
|
+
},
|
|
1294
|
+
|
|
1295
|
+
getInstanceId: function () {
|
|
1296
|
+
return this.instanceId;
|
|
1297
|
+
},
|
|
1298
|
+
|
|
1299
|
+
destroy: function () {
|
|
1300
|
+
delete instances[this.instanceId];
|
|
1301
|
+
|
|
1302
|
+
$(window).off('.cms');
|
|
1303
|
+
$(window).off('.ones');
|
|
1304
|
+
$(document).off('.onescroll');
|
|
1305
|
+
this.trigger.off();
|
|
1306
|
+
this.okBtn.off();
|
|
1307
|
+
this.cancelBtn.off();
|
|
1308
|
+
this.optionsContainer.off();
|
|
1309
|
+
|
|
1310
|
+
// Clear horizontal scroll tracking interval
|
|
1311
|
+
if (this._horizontalScrollInterval) {
|
|
1312
|
+
clearInterval(this._horizontalScrollInterval);
|
|
1313
|
+
this._horizontalScrollInterval = null;
|
|
1314
|
+
}
|
|
1315
|
+
|
|
1316
|
+
$('input.cms-hidden-input[data-cms-input="' + this.settings.name + '"]').remove();
|
|
1317
|
+
|
|
1318
|
+
this.wrapper.remove();
|
|
1319
|
+
this.dropdown.remove();
|
|
1320
|
+
this.$element.removeData(pluginName);
|
|
1321
|
+
}
|
|
1322
|
+
};
|
|
1323
|
+
|
|
1324
|
+
/**
|
|
1325
|
+
* Get instance by ID
|
|
1326
|
+
*/
|
|
1327
|
+
OneSelect.getInstance = function (instanceId) {
|
|
1328
|
+
return instances[instanceId] || null;
|
|
1329
|
+
};
|
|
1330
|
+
|
|
1331
|
+
/**
|
|
1332
|
+
* Get all instances
|
|
1333
|
+
*/
|
|
1334
|
+
OneSelect.getAllInstances = function () {
|
|
1335
|
+
return instances;
|
|
1336
|
+
};
|
|
1337
|
+
|
|
1338
|
+
/**
|
|
1339
|
+
* jQuery Plugin Registration
|
|
1340
|
+
*/
|
|
1341
|
+
$.fn[pluginName] = function (options) {
|
|
1342
|
+
var args = arguments;
|
|
1343
|
+
var returnValue = this;
|
|
1344
|
+
|
|
1345
|
+
this.each(function () {
|
|
1346
|
+
var $this = $(this);
|
|
1347
|
+
var instance = $this.data(pluginName);
|
|
1348
|
+
|
|
1349
|
+
// Initialize if not already
|
|
1350
|
+
if (!instance) {
|
|
1351
|
+
// Don't auto-initialize - only init if options are provided
|
|
1352
|
+
if (typeof options === 'object' || !options) {
|
|
1353
|
+
instance = new OneSelect(this, options);
|
|
1354
|
+
$this.data(pluginName, instance);
|
|
1355
|
+
} else {
|
|
1356
|
+
// Method called without initialization
|
|
1357
|
+
return;
|
|
1358
|
+
}
|
|
1359
|
+
}
|
|
1360
|
+
|
|
1361
|
+
// Call method
|
|
1362
|
+
if (typeof options === 'string') {
|
|
1363
|
+
if (options === 'value') {
|
|
1364
|
+
if (args[1] !== undefined) {
|
|
1365
|
+
instance.setValue(args[1]);
|
|
1366
|
+
returnValue = $this;
|
|
1367
|
+
} else {
|
|
1368
|
+
returnValue = instance.getValue();
|
|
1369
|
+
}
|
|
1370
|
+
} else if (options === 'getValues') {
|
|
1371
|
+
returnValue = instance.getSelectedValues();
|
|
1372
|
+
} else if (options === 'getLabels') {
|
|
1373
|
+
returnValue = instance.getSelectedLabels();
|
|
1374
|
+
} else if (options === 'getInstanceId') {
|
|
1375
|
+
returnValue = instance.getInstanceId();
|
|
1376
|
+
} else if (options === 'updateData') {
|
|
1377
|
+
instance.updateData(args[1]);
|
|
1378
|
+
} else if (options === 'loadData') {
|
|
1379
|
+
instance.loadData(args[1], args[2], args[3]);
|
|
1380
|
+
} else if (options === 'reload') {
|
|
1381
|
+
instance.reload();
|
|
1382
|
+
} else if (options === 'select') {
|
|
1383
|
+
instance.select(args[1]);
|
|
1384
|
+
} else if (options === 'unselect') {
|
|
1385
|
+
instance.unselect(args[1]);
|
|
1386
|
+
} else if (options === 'selectAll') {
|
|
1387
|
+
instance.selectAll();
|
|
1388
|
+
} else if (options === 'unselectAll') {
|
|
1389
|
+
instance.unselectAll();
|
|
1390
|
+
} else if (options === 'toggleSelection') {
|
|
1391
|
+
instance.toggleSelection(args[1]);
|
|
1392
|
+
} else if (options === 'open') {
|
|
1393
|
+
instance.open();
|
|
1394
|
+
} else if (options === 'close') {
|
|
1395
|
+
instance.close();
|
|
1396
|
+
} else if (options === 'destroy') {
|
|
1397
|
+
instance.destroy();
|
|
1398
|
+
}
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
|
|
1402
|
+
return returnValue;
|
|
1403
|
+
};
|
|
1404
|
+
|
|
1405
|
+
// Expose constructor
|
|
1406
|
+
$.fn[pluginName].Constructor = OneSelect;
|
|
1407
|
+
|
|
1408
|
+
// Expose static methods
|
|
1409
|
+
$.fn[pluginName].getInstance = OneSelect.getInstance;
|
|
1410
|
+
$.fn[pluginName].getAllInstances = OneSelect.getAllInstances;
|
|
1411
|
+
|
|
1412
|
+
}));
|