@kamranbaylarov/one-select 1.1.1 → 1.2.1
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 +1011 -892
- package/css/one-select.min.css +41 -37
- package/js/one-select.js +1424 -1196
- package/js/one-select.min.js +1 -7
- package/package.json +41 -41
package/README.md
CHANGED
|
@@ -1,892 +1,1011 @@
|
|
|
1
|
-
# 🎯 OneSelect - jQuery Multi-Select Dropdown Component
|
|
2
|
-
|
|
3
|
-
**Version:** 1.
|
|
4
|
-
|
|
5
|
-
A powerful, flexible, and feature-rich multi-select dropdown component for jQuery.
|
|
6
|
-
|
|
7
|
-
## 📋 Table of Contents
|
|
8
|
-
|
|
9
|
-
1. [Overview](#overview)
|
|
10
|
-
2. [Features](#features)
|
|
11
|
-
3. [Installation](#installation)
|
|
12
|
-
4. [All Parameters](#all-parameters)
|
|
13
|
-
5. [Data Attributes](#data-attributes)
|
|
14
|
-
6. [Methods](#methods)
|
|
15
|
-
7. [Callbacks](#callbacks)
|
|
16
|
-
8. [Examples](#examples)
|
|
17
|
-
9. [AJAX Integration](#ajax-integration)
|
|
18
|
-
10. [Form Submission](#form-submission)
|
|
19
|
-
11. [Badge System](#badge-system)
|
|
20
|
-
12. [CSS Styling](#css-styling)
|
|
21
|
-
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
## 🎯 Overview
|
|
25
|
-
|
|
26
|
-
OneSelect is a powerful **jQuery-based** plugin that provides multi-select functionality with comprehensive customization options.
|
|
27
|
-
|
|
28
|
-
### 🚀 Key Features
|
|
29
|
-
|
|
30
|
-
- ✅ **Multiple Selection** - Select multiple items with checkboxes
|
|
31
|
-
- 🎯 **Select All** - Select all items with one click
|
|
32
|
-
- 🏷️️ **Badge System** - Display selected items as badges
|
|
33
|
-
- 📤 **External Badges** - Display badges in external elements
|
|
34
|
-
- 🔄 **AJAX Support** - Load data dynamically
|
|
35
|
-
- 🔍 **Search Feature** - Local filtering or AJAX search with debounce
|
|
36
|
-
- 📝 **Form Submission** - Submit data via hidden inputs
|
|
37
|
-
- 🎨 **Fully Customizable** - Complete control with 27+ parameters
|
|
38
|
-
- 📱 **Responsive** - Works on all devices
|
|
39
|
-
- 🌐 **Data Attributes** - Configure via HTML attributes
|
|
40
|
-
-
|
|
41
|
-
-
|
|
42
|
-
-
|
|
43
|
-
-
|
|
44
|
-
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
| **
|
|
56
|
-
| **
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
├──
|
|
68
|
-
├──
|
|
69
|
-
├──
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
├──
|
|
75
|
-
├──
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
```
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
|
141
|
-
|
|
142
|
-
| `
|
|
143
|
-
| `
|
|
144
|
-
| `
|
|
145
|
-
| `
|
|
146
|
-
| `
|
|
147
|
-
| `
|
|
148
|
-
| `
|
|
149
|
-
| `
|
|
150
|
-
| `
|
|
151
|
-
| `
|
|
152
|
-
| `
|
|
153
|
-
| `
|
|
154
|
-
| `
|
|
155
|
-
| `
|
|
156
|
-
| `
|
|
157
|
-
| `
|
|
158
|
-
| `
|
|
159
|
-
| `
|
|
160
|
-
| `
|
|
161
|
-
| `
|
|
162
|
-
| `
|
|
163
|
-
| `
|
|
164
|
-
| `
|
|
165
|
-
| `
|
|
166
|
-
| `
|
|
167
|
-
| `
|
|
168
|
-
| `
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
|
179
|
-
|
|
180
|
-
| `data-ones-
|
|
181
|
-
| `data-ones-
|
|
182
|
-
| `data-ones-
|
|
183
|
-
| `data-ones-
|
|
184
|
-
| `data-ones-
|
|
185
|
-
| `data-ones-
|
|
186
|
-
| `data-ones-
|
|
187
|
-
| `data-ones-
|
|
188
|
-
| `data-ones-show-
|
|
189
|
-
| `data-ones-show-
|
|
190
|
-
| `data-ones-
|
|
191
|
-
| `data-ones-search
|
|
192
|
-
| `data-ones-search-
|
|
193
|
-
| `data-ones-
|
|
194
|
-
| `data-ones-
|
|
195
|
-
| `data-ones-
|
|
196
|
-
| `data-ones-
|
|
197
|
-
| `data-ones-form
|
|
198
|
-
| `data-ones-
|
|
199
|
-
| `data-ones-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
data-ones-
|
|
208
|
-
data-ones-
|
|
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
|
-
|
|
241
|
-
$('#mySelect').oneSelect('
|
|
242
|
-
$('#mySelect').oneSelect('
|
|
243
|
-
$('#mySelect').oneSelect('
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
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
|
-
|
|
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
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
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
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
data: ['
|
|
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
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
$('#mySelect').oneSelect({
|
|
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
|
-
|
|
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
|
-
|
|
799
|
-
|
|
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
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
861
|
-
```
|
|
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
|
-
|
|
1
|
+
# 🎯 OneSelect - jQuery Multi-Select Dropdown Component
|
|
2
|
+
|
|
3
|
+
**Version:** 1.2.1 | **Author:** Kamran Baylarov
|
|
4
|
+
|
|
5
|
+
A powerful, flexible, and feature-rich multi-select dropdown component for jQuery.
|
|
6
|
+
|
|
7
|
+
## 📋 Table of Contents
|
|
8
|
+
|
|
9
|
+
1. [Overview](#overview)
|
|
10
|
+
2. [Features](#features)
|
|
11
|
+
3. [Installation](#installation)
|
|
12
|
+
4. [All Parameters](#all-parameters)
|
|
13
|
+
5. [Data Attributes](#data-attributes)
|
|
14
|
+
6. [Methods](#methods)
|
|
15
|
+
7. [Callbacks](#callbacks)
|
|
16
|
+
8. [Examples](#examples)
|
|
17
|
+
9. [AJAX Integration](#ajax-integration)
|
|
18
|
+
10. [Form Submission](#form-submission)
|
|
19
|
+
11. [Badge System](#badge-system)
|
|
20
|
+
12. [CSS Styling](#css-styling)
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 🎯 Overview
|
|
25
|
+
|
|
26
|
+
OneSelect is a powerful **jQuery-based** plugin that provides multi-select functionality with comprehensive customization options.
|
|
27
|
+
|
|
28
|
+
### 🚀 Key Features
|
|
29
|
+
|
|
30
|
+
- ✅ **Multiple Selection** - Select multiple items with checkboxes
|
|
31
|
+
- 🎯 **Select All** - Select all items with one click
|
|
32
|
+
- 🏷️️ **Badge System** - Display selected items as badges
|
|
33
|
+
- 📤 **External Badges** - Display badges in external elements
|
|
34
|
+
- 🔄 **AJAX Support** - Load data dynamically
|
|
35
|
+
- 🔍 **Search Feature** - Local filtering or AJAX search with debounce
|
|
36
|
+
- 📝 **Form Submission** - Submit data via hidden inputs
|
|
37
|
+
- 🎨 **Fully Customizable** - Complete control with 27+ parameters
|
|
38
|
+
- 📱 **Responsive** - Works on all devices
|
|
39
|
+
- 🌐 **Data Attributes** - Configure via HTML attributes
|
|
40
|
+
- 🔄 **Real-time Sync** - `data-ones-value` attribute updates automatically
|
|
41
|
+
- 🔗 **Label-Checkbox Binding** - Native HTML label-for-id connection for proper accessibility
|
|
42
|
+
- 🎪 **Multiple Instances** - Independent selects on same page
|
|
43
|
+
- 🌪 **Click Outside** - Close dropdown when clicking outside (default: true)
|
|
44
|
+
- 📍 **Smart Positioning** - Dropdown positioned with `position: fixed` using viewport coordinates
|
|
45
|
+
- 🔀 **Horizontal Scroll Detection** - Automatically closes on any horizontal scroll to prevent misalignment
|
|
46
|
+
|
|
47
|
+
---
|
|
48
|
+
|
|
49
|
+
## 💡 Features
|
|
50
|
+
|
|
51
|
+
### 📊 Technical Stack
|
|
52
|
+
|
|
53
|
+
| Component | Technology |
|
|
54
|
+
|-----------|------------|
|
|
55
|
+
| **Library** | jQuery (required dependency) |
|
|
56
|
+
| **Plugin Type** | jQuery Plugin |
|
|
57
|
+
| **Files** | `one-select.js`, `one-select.min.css` |
|
|
58
|
+
|
|
59
|
+
### 🎯 Functionality
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
📦 Data Structures:
|
|
63
|
+
├── String Array: ['Apple', 'Banana', 'Cherry']
|
|
64
|
+
└── Object Array: [{id: 1, name: 'Apple'}, ...]
|
|
65
|
+
|
|
66
|
+
🎮 Interactions:
|
|
67
|
+
├── Click to select (checkbox)
|
|
68
|
+
├── "Select All" option
|
|
69
|
+
├── OK button (confirm)
|
|
70
|
+
├── Cancel button (clears selection and closes)
|
|
71
|
+
└── × button (remove from badges)
|
|
72
|
+
|
|
73
|
+
📤 Data Flow:
|
|
74
|
+
├── onChange(values, labels) - When selection changes
|
|
75
|
+
├── onOk(values, labels) - When OK clicked
|
|
76
|
+
├── onCancel() - When Cancel clicked
|
|
77
|
+
├── data-ones-value sync - Real-time attribute updates
|
|
78
|
+
└── AJAX callbacks (beforeLoad, afterLoad, onLoadError)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
---
|
|
82
|
+
|
|
83
|
+
## 📦 Installation
|
|
84
|
+
|
|
85
|
+
### Via NPM (Recommended)
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
npm install @kamranbaylarov/one-select
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Manual Download
|
|
92
|
+
|
|
93
|
+
Download from [GitHub Releases](https://github.com/KamranBeylarov/one-select/releases)
|
|
94
|
+
|
|
95
|
+
### Dependencies
|
|
96
|
+
|
|
97
|
+
```html
|
|
98
|
+
<!-- jQuery must be included first -->
|
|
99
|
+
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### Include Files
|
|
103
|
+
|
|
104
|
+
**NPM:**
|
|
105
|
+
```html
|
|
106
|
+
<!-- CSS -->
|
|
107
|
+
<link rel="stylesheet" href="/node_modules/@kamranbaylarov/one-select/css/one-select.min.css">
|
|
108
|
+
|
|
109
|
+
<!-- JavaScript -->
|
|
110
|
+
<script src="/node_modules/@kamranbaylarov/one-select/js/one-select.min.js"></script>
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Manual:**
|
|
114
|
+
```html
|
|
115
|
+
<!-- CSS -->
|
|
116
|
+
<link rel="stylesheet" href="/path/to/one-select.min.css">
|
|
117
|
+
|
|
118
|
+
<!-- JavaScript -->
|
|
119
|
+
<script src="/path/to/one-select.js"></script>
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Create HTML Element
|
|
123
|
+
|
|
124
|
+
```html
|
|
125
|
+
<div id="mySelect"></div>
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Initialize
|
|
129
|
+
|
|
130
|
+
```javascript
|
|
131
|
+
$('#mySelect').oneSelect({
|
|
132
|
+
data: ['Apple', 'Banana', 'Cherry']
|
|
133
|
+
});
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
---
|
|
137
|
+
|
|
138
|
+
## ⚙️ All Parameters
|
|
139
|
+
|
|
140
|
+
| Parameter | Type | Default | Description |
|
|
141
|
+
|---------|-----|---------|-------------|
|
|
142
|
+
| `placeholder` | String | `'Select options...'` | Placeholder text when nothing selected |
|
|
143
|
+
| `selectAllText` | String | `'Select All'` | "Select All" button text |
|
|
144
|
+
| `okText` | String | `'OK'` | OK button text |
|
|
145
|
+
| `cancelText` | String | `'Cancel'` | Cancel button text |
|
|
146
|
+
| `data` | Array/Object | `[]` | Options list (string array or key-value object) |
|
|
147
|
+
| `value` | Number/Array/String/null | `null` | Single index, key, or array to pre-select |
|
|
148
|
+
| `showCheckbox` | Boolean | `true` | Show/hide checkboxes |
|
|
149
|
+
| `showBadges` | Boolean | `false` | Show badges in trigger |
|
|
150
|
+
| `showBadgesExternal` | String/null | `null` | External element ID (for badges) |
|
|
151
|
+
| `showSearch` | Boolean | `false` | Show search input in dropdown |
|
|
152
|
+
| `searchPlaceholder` | String | `'Search...'` | Search input placeholder text |
|
|
153
|
+
| `searchUrl` | String/null | `null` | URL for AJAX search (GET request with `q` parameter) |
|
|
154
|
+
| `searchDebounceDelay` | Number | `300` | Delay in milliseconds for search debounce |
|
|
155
|
+
| `closeOnScroll` | Boolean | `false` | Close dropdown on page scroll |
|
|
156
|
+
| `closeOnOutside` | Boolean | `true` | Close dropdown when clicking outside |
|
|
157
|
+
| `submitForm` | Boolean | `false` | Submit form on OK click |
|
|
158
|
+
| `submitOnOutside` | Boolean | `false` | Submit form on outside click |
|
|
159
|
+
| `formId` | String/null | `null` | Specific form ID (null: parent form) |
|
|
160
|
+
| `name` | String/null | `null` | Hidden input name attribute |
|
|
161
|
+
| `multiple` | Boolean | `true` | Submit as array (name[]) |
|
|
162
|
+
| `ajax` | Object/null | `null` | AJAX configuration object |
|
|
163
|
+
| `autoLoad` | Boolean | `true` | Auto load data via AJAX |
|
|
164
|
+
| `beforeLoad` | Function/null | `null` | Called before AJAX |
|
|
165
|
+
| `afterLoad` | Function/null | `null` | Called after AJAX success |
|
|
166
|
+
| `onLoadError` | Function/null | `null` | Called on AJAX error |
|
|
167
|
+
| `onChange` | Function/null | `null` | Called when selection changes |
|
|
168
|
+
| `onSelect` | Function/null | `null` | Previous version of onChange |
|
|
169
|
+
| `onOk` | Function/null | `null` | Called when OK clicked |
|
|
170
|
+
| `onCancel` | Function/null | `null` | Called when Cancel clicked |
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## 🏷️ Data Attributes
|
|
175
|
+
|
|
176
|
+
All parameters can be set via HTML data attributes. Data attributes **override JS parameters**.
|
|
177
|
+
|
|
178
|
+
| Data Attribute | Parameter | Type | Example |
|
|
179
|
+
|----------------|----------|-----|---------|
|
|
180
|
+
| `data-ones-placeholder` | `placeholder` | String | `data-ones-placeholder="Select..."` |
|
|
181
|
+
| `data-ones-select-all-text` | `selectAllText` | String | `data-ones-select-all-text="Select All"` |
|
|
182
|
+
| `data-ones-ok-text` | `okText` | String | `data-ones-ok-text="Confirm"` |
|
|
183
|
+
| `data-ones-cancel-text` | `cancelText` | String | `data-ones-cancel-text="Cancel"` |
|
|
184
|
+
| `data-ones-data` | `data` | Array | `data-ones-data='["A","B","C"]'` |
|
|
185
|
+
| `data-ones-value` | `value` | Number/Array | `data-ones-value='"0"'` or `data-ones-value='["0","2"]'` (Real-time sync, removed when empty) |
|
|
186
|
+
| `data-ones-name` | `name` | String | `data-ones-name="items"` |
|
|
187
|
+
| `data-ones-multiple` | `multiple` | Boolean | `data-ones-multiple="true"` |
|
|
188
|
+
| `data-ones-show-checkbox` | `showCheckbox` | Boolean | `data-ones-show-checkbox="false"` |
|
|
189
|
+
| `data-ones-show-badges` | `showBadges` | Boolean | `data-ones-show-badges="true"` |
|
|
190
|
+
| `data-ones-show-badges-external` | `showBadgesExternal` | String | `data-ones-show-badges-external="badgesDiv"` |
|
|
191
|
+
| `data-ones-show-search` | `showSearch` | Boolean | `data-ones-show-search="true"` |
|
|
192
|
+
| `data-ones-search-placeholder` | `searchPlaceholder` | String | `data-ones-search-placeholder="Search items..."` |
|
|
193
|
+
| `data-ones-search-url` | `searchUrl` | String | `data-ones-search-url="/api/search"` |
|
|
194
|
+
| `data-ones-search-debounce-delay` | `searchDebounceDelay` | Number | `data-ones-search-debounce-delay="500"` |
|
|
195
|
+
| `data-ones-close-on-scroll` | `closeOnScroll` | Boolean | `data-ones-close-on-scroll="true"` |
|
|
196
|
+
| `data-ones-close-on-outside` | `closeOnOutside` | Boolean | `data-ones-close-on-outside="true"` |
|
|
197
|
+
| `data-ones-submit-form` | `submitForm` | Boolean | `data-ones-submit-form="true"` |
|
|
198
|
+
| `data-ones-submit-on-outside` | `submitOnOutside` | Boolean | `data-ones-submit-on-outside="true"` |
|
|
199
|
+
| `data-ones-form-id` | `formId` | String | `data-ones-form-id="myForm"` |
|
|
200
|
+
| `data-ones-auto-load` | `autoLoad` | Boolean | `data-ones-auto-load="false"` |
|
|
201
|
+
| `data-ones-ajax` | `ajax` | String/Object | `data-ones-ajax="/api/items"` or `data-ones-ajax='{"url": "/api/items","method":"POST"}'` |
|
|
202
|
+
|
|
203
|
+
### Example:
|
|
204
|
+
|
|
205
|
+
```html
|
|
206
|
+
<div id="mySelect"
|
|
207
|
+
data-ones-placeholder="Select products..."
|
|
208
|
+
data-ones-data='["Apple", "Banana", "Cherry"]'
|
|
209
|
+
data-ones-show-badges="true"
|
|
210
|
+
data-ones-name="fruits"
|
|
211
|
+
></div>
|
|
212
|
+
|
|
213
|
+
<script>
|
|
214
|
+
$('#mySelect').oneSelect({
|
|
215
|
+
// JS options (data attributes override these)
|
|
216
|
+
});
|
|
217
|
+
</script>
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
## 🔧 Methods
|
|
223
|
+
|
|
224
|
+
Call via jQuery plugin method:
|
|
225
|
+
|
|
226
|
+
```javascript
|
|
227
|
+
// Get selected values
|
|
228
|
+
var values = $('#mySelect').oneSelect('getValues');
|
|
229
|
+
var labels = $('#mySelect').oneSelect('getLabels');
|
|
230
|
+
|
|
231
|
+
// Set selection
|
|
232
|
+
$('#mySelect').oneSelect('value', ['Apple', 'Banana']);
|
|
233
|
+
|
|
234
|
+
// Update data
|
|
235
|
+
$('#mySelect').oneSelect('updateData', ['New', 'Data']);
|
|
236
|
+
|
|
237
|
+
// Load data via AJAX
|
|
238
|
+
$('#mySelect').oneSelect('loadData');
|
|
239
|
+
|
|
240
|
+
// Selection control
|
|
241
|
+
$('#mySelect').oneSelect('selectAll');
|
|
242
|
+
$('#mySelect').oneSelect('unselectAll');
|
|
243
|
+
$('#mySelect').oneSelect('select', 'Apple');
|
|
244
|
+
$('#mySelect').oneSelect('unselect', 'Banana');
|
|
245
|
+
$('#mySelect').oneSelect('toggleSelection', 'Cherry');
|
|
246
|
+
|
|
247
|
+
// Dropdown control
|
|
248
|
+
$('#mySelect').oneSelect('open');
|
|
249
|
+
$('#mySelect').oneSelect('close');
|
|
250
|
+
|
|
251
|
+
// Get instance ID
|
|
252
|
+
var instanceId = $('#mySelect').oneSelect('getInstanceId');
|
|
253
|
+
|
|
254
|
+
// Get instance object
|
|
255
|
+
var instance = OneSelect.getInstance(instanceId);
|
|
256
|
+
|
|
257
|
+
// Get all instances
|
|
258
|
+
var allInstances = OneSelect.getAllInstances();
|
|
259
|
+
|
|
260
|
+
// Destroy
|
|
261
|
+
$('#mySelect').oneSelect('destroy');
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 🎯 Callbacks
|
|
267
|
+
|
|
268
|
+
### onChange(values, labels)
|
|
269
|
+
|
|
270
|
+
Called every time selection changes. Most important callback.
|
|
271
|
+
|
|
272
|
+
```javascript
|
|
273
|
+
$('#mySelect').oneSelect({
|
|
274
|
+
data: ['A', 'B', 'C'],
|
|
275
|
+
onChange: function(values, labels) {
|
|
276
|
+
console.log('Values:', values);
|
|
277
|
+
console.log('Labels:', labels);
|
|
278
|
+
// values: ['A', 'C']
|
|
279
|
+
// labels: ['A', 'C']
|
|
280
|
+
}
|
|
281
|
+
});
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
### onOk(values, labels)
|
|
285
|
+
|
|
286
|
+
Called when OK button is clicked.
|
|
287
|
+
|
|
288
|
+
```javascript
|
|
289
|
+
$('#mySelect').oneSelect({
|
|
290
|
+
onOk: function(values, labels) {
|
|
291
|
+
alert('Selected: ' + labels.join(', '));
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### onCancel()
|
|
297
|
+
|
|
298
|
+
Called when Cancel button is clicked and clears all selections.
|
|
299
|
+
|
|
300
|
+
```javascript
|
|
301
|
+
$('#mySelect').oneSelect({
|
|
302
|
+
onCancel: function() {
|
|
303
|
+
console.log('Selection cancelled');
|
|
304
|
+
}
|
|
305
|
+
});
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
### AJAX Callbacks
|
|
309
|
+
|
|
310
|
+
```javascript
|
|
311
|
+
$('#mySelect').oneSelect({
|
|
312
|
+
ajax: {
|
|
313
|
+
url: '/api/items',
|
|
314
|
+
method: 'GET'
|
|
315
|
+
},
|
|
316
|
+
beforeLoad: function() {
|
|
317
|
+
$('#loading').show();
|
|
318
|
+
},
|
|
319
|
+
afterLoad: function(response) {
|
|
320
|
+
$('#loading').hide();
|
|
321
|
+
console.log('Data loaded:', response);
|
|
322
|
+
},
|
|
323
|
+
onLoadError: function(error) {
|
|
324
|
+
$('#error').text('Error: ' + error);
|
|
325
|
+
}
|
|
326
|
+
});
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
---
|
|
330
|
+
|
|
331
|
+
## 📚 Examples
|
|
332
|
+
|
|
333
|
+
### 1. Basic Usage
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
$('#mySelect').oneSelect({
|
|
337
|
+
placeholder: 'Select fruits...',
|
|
338
|
+
data: ['Apple', 'Banana', 'Cherry', 'Mango']
|
|
339
|
+
});
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### 2. How It Works
|
|
343
|
+
|
|
344
|
+
**Data Format:** Now supports both String Array and Key-Value Object
|
|
345
|
+
|
|
346
|
+
#### Option 1: String Array (original)
|
|
347
|
+
```javascript
|
|
348
|
+
data: ['Apple', 'Banana', 'Cherry']
|
|
349
|
+
```
|
|
350
|
+
**Result:**
|
|
351
|
+
- **value** (what gets submitted): `0, 1, 2` (array indices)
|
|
352
|
+
- **label** (what user sees): `'Apple', 'Banana', 'Cherry'`
|
|
353
|
+
|
|
354
|
+
#### Option 2: Key-Value Object (NEW!)
|
|
355
|
+
```javascript
|
|
356
|
+
data: {
|
|
357
|
+
'fruit_1': 'Apple',
|
|
358
|
+
'fruit_2': 'Banana',
|
|
359
|
+
'fruit_3': 'Cherry'
|
|
360
|
+
}
|
|
361
|
+
```
|
|
362
|
+
**Result:**
|
|
363
|
+
- **value** (what gets submitted): `'fruit_1', 'fruit_2', 'fruit_3'` (keys)
|
|
364
|
+
- **label** (what user sees): `'Apple', 'Banana', 'Cherry'` (values)
|
|
365
|
+
|
|
366
|
+
**Perfect for:**
|
|
367
|
+
- Database IDs as keys
|
|
368
|
+
- Backend-generated key-value pairs
|
|
369
|
+
- Real-world data structures
|
|
370
|
+
|
|
371
|
+
**Example with PHP data:**
|
|
372
|
+
```php
|
|
373
|
+
// PHP
|
|
374
|
+
$items = [
|
|
375
|
+
5 => "M.Hadi_9_6/1",
|
|
376
|
+
6 => "Sarayevo_20_4/2/1",
|
|
377
|
+
7 => "Sarayevo_13B_3/2/1"
|
|
378
|
+
];
|
|
379
|
+
echo json_encode($items);
|
|
380
|
+
// Output: {"5":"M.Hadi_9_6/1","6":"Sarayevo_20_4/2/1","7":"Sarayevo_13B_3/2/1"}
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
```javascript
|
|
384
|
+
// JavaScript
|
|
385
|
+
$('#mySelect').oneSelect({
|
|
386
|
+
data: {"5":"M.Hadi_9_6/1", "6":"Sarayevo_20_4/2/1", "7":"Sarayevo_13B_3/2/1"}
|
|
387
|
+
});
|
|
388
|
+
// value: "5", "6", "7" (keys - submitted to form)
|
|
389
|
+
// label: "M.Hadi_9_6/1", "Sarayevo_20_4/2/1", "Sarayevo_13B_3/2/1" (values - displayed to user)
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### 2.1. AJAX with Simple URL (NEW!)
|
|
393
|
+
|
|
394
|
+
**Easy AJAX setup with just URL:**
|
|
395
|
+
|
|
396
|
+
```javascript
|
|
397
|
+
// Method 1: JavaScript configuration
|
|
398
|
+
$('#mySelect').oneSelect({
|
|
399
|
+
ajax: {
|
|
400
|
+
url: '/api/fruits',
|
|
401
|
+
method: 'GET' // Default is GET
|
|
402
|
+
},
|
|
403
|
+
autoLoad: true
|
|
404
|
+
});
|
|
405
|
+
```
|
|
406
|
+
|
|
407
|
+
```html
|
|
408
|
+
<!-- Method 2: HTML data attribute (easiest!) -->
|
|
409
|
+
<div id="mySelect" data-ones-ajax="/api/fruits"></div>
|
|
410
|
+
|
|
411
|
+
<script>
|
|
412
|
+
$('#mySelect').oneSelect();
|
|
413
|
+
</script>
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
**Advanced AJAX configuration:**
|
|
417
|
+
```html
|
|
418
|
+
<div id="mySelect"
|
|
419
|
+
data-ones-ajax='{"url":"/api/fruits","method":"POST","data":{"category":"fresh"}}'>
|
|
420
|
+
</div>
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
### 3. Value Parameter (Pre-selected Items)
|
|
424
|
+
|
|
425
|
+
```javascript
|
|
426
|
+
// Single value (by index)
|
|
427
|
+
$('#mySelect').oneSelect({
|
|
428
|
+
data: ['Apple', 'Banana', 'Cherry', 'Mango'],
|
|
429
|
+
value: 0 // Index 0 ('Apple') will be selected
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
// Array with multiple selection
|
|
433
|
+
$('#mySelect').oneSelect({
|
|
434
|
+
data: ['Apple', 'Banana', 'Cherry', 'Mango'],
|
|
435
|
+
value: [0, 2], // Indices 0 ('Apple') and 2 ('Cherry') will be selected
|
|
436
|
+
showBadges: true
|
|
437
|
+
});
|
|
438
|
+
|
|
439
|
+
// HTML data attribute
|
|
440
|
+
<div class="one-select"
|
|
441
|
+
data-ones-data='["Apple", "Banana", "Cherry"]'
|
|
442
|
+
data-ones-value='"0"'> <!-- Single index -->
|
|
443
|
+
</div>
|
|
444
|
+
|
|
445
|
+
<!-- OR -->
|
|
446
|
+
<div class="one-select"
|
|
447
|
+
data-ones-data='["Apple", "Banana", "Cherry"]'
|
|
448
|
+
data-ones-value='["0", "2"]'> <!-- Multiple indices -->
|
|
449
|
+
</div>
|
|
450
|
+
```
|
|
451
|
+
|
|
452
|
+
### 4. Badge System
|
|
453
|
+
|
|
454
|
+
```javascript
|
|
455
|
+
// Trigger badges
|
|
456
|
+
$('#mySelect').oneSelect({
|
|
457
|
+
data: ['A', 'B', 'C'],
|
|
458
|
+
showBadges: true
|
|
459
|
+
});
|
|
460
|
+
|
|
461
|
+
// External badges
|
|
462
|
+
<div id="badgesContainer"></div>
|
|
463
|
+
|
|
464
|
+
$('#mySelect').oneSelect({
|
|
465
|
+
data: ['A', 'B', 'C'],
|
|
466
|
+
showBadgesExternal: 'badgesContainer'
|
|
467
|
+
});
|
|
468
|
+
```
|
|
469
|
+
|
|
470
|
+
### 5. Form Submission
|
|
471
|
+
|
|
472
|
+
```javascript
|
|
473
|
+
$('#mySelect').oneSelect({
|
|
474
|
+
data: ['Item 1', 'Item 2'],
|
|
475
|
+
name: 'items',
|
|
476
|
+
multiple: true,
|
|
477
|
+
submitForm: true,
|
|
478
|
+
formId: 'myForm'
|
|
479
|
+
});
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
Backend example:
|
|
483
|
+
```javascript
|
|
484
|
+
// Receive items array: [0, 1] (indices of selected items)
|
|
485
|
+
// Use indices to get original values from your data array
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
### 6. AJAX Data Loading
|
|
489
|
+
|
|
490
|
+
```javascript
|
|
491
|
+
$('#mySelect').oneSelect({
|
|
492
|
+
ajax: {
|
|
493
|
+
url: '/api/categories',
|
|
494
|
+
method: 'GET'
|
|
495
|
+
},
|
|
496
|
+
beforeLoad: function() {
|
|
497
|
+
console.log('Loading...');
|
|
498
|
+
},
|
|
499
|
+
afterLoad: function(response) {
|
|
500
|
+
console.log('Loaded:', response);
|
|
501
|
+
}
|
|
502
|
+
});
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
### 7. Multiple Instances
|
|
506
|
+
|
|
507
|
+
```javascript
|
|
508
|
+
// Each has independent ID
|
|
509
|
+
var fruits = $('#fruits').oneSelect({
|
|
510
|
+
data: ['Apple', 'Banana', 'Cherry']
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
var colors = $('#colors').oneSelect({
|
|
514
|
+
data: ['Red', 'Blue', 'Green']
|
|
515
|
+
});
|
|
516
|
+
|
|
517
|
+
// External control over instances
|
|
518
|
+
var fruitsInstance = OneSelect.getInstance(
|
|
519
|
+
$('#fruits').oneSelect('getInstanceId')
|
|
520
|
+
);
|
|
521
|
+
fruitsInstance.selectAll();
|
|
522
|
+
```
|
|
523
|
+
|
|
524
|
+
### 8. Search Feature
|
|
525
|
+
|
|
526
|
+
```javascript
|
|
527
|
+
// Enable local search (filters existing data)
|
|
528
|
+
$('#mySelect').oneSelect({
|
|
529
|
+
data: ['Apple', 'Banana', 'Cherry', 'Mango', 'Orange', 'Grape'],
|
|
530
|
+
showSearch: true,
|
|
531
|
+
searchPlaceholder: 'Type to search...'
|
|
532
|
+
});
|
|
533
|
+
|
|
534
|
+
// Enable AJAX search (with debounce)
|
|
535
|
+
$('#mySelect').oneSelect({
|
|
536
|
+
showSearch: true,
|
|
537
|
+
searchUrl: '/api/search',
|
|
538
|
+
searchDebounceDelay: 500,
|
|
539
|
+
searchPlaceholder: 'Search items...'
|
|
540
|
+
});
|
|
541
|
+
|
|
542
|
+
// HTML data attribute example (local search)
|
|
543
|
+
<div class="one-select"
|
|
544
|
+
data-ones-data='["Apple", "Banana", "Cherry", "Mango"]'
|
|
545
|
+
data-ones-show-search="true"
|
|
546
|
+
data-ones-search-placeholder="Find a fruit...">
|
|
547
|
+
</div>
|
|
548
|
+
|
|
549
|
+
// HTML data attribute example (AJAX search)
|
|
550
|
+
<div class="one-select"
|
|
551
|
+
data-ones-show-search="true"
|
|
552
|
+
data-ones-search-url="/api/customers/search"
|
|
553
|
+
data-ones-search-debounce-delay="300"
|
|
554
|
+
data-ones-search-placeholder="Search customers...">
|
|
555
|
+
</div>
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
**AJAX Search Server Response Format:**
|
|
559
|
+
|
|
560
|
+
The server should respond with JSON in one of these formats:
|
|
561
|
+
|
|
562
|
+
```json
|
|
563
|
+
// Direct array
|
|
564
|
+
["Apple", "Banana", "Cherry"]
|
|
565
|
+
|
|
566
|
+
// Wrapped with 'data'
|
|
567
|
+
{
|
|
568
|
+
"data": [{"value": 1, "label": "Apple"}, {"value": 2, "label": "Banana"}]
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
// Wrapped with 'results'
|
|
572
|
+
{
|
|
573
|
+
"results": ["Apple", "Banana"]
|
|
574
|
+
}
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
The request will be sent as `GET /api/search?q=searchterm`
|
|
578
|
+
|
|
579
|
+
---
|
|
580
|
+
|
|
581
|
+
## 📦 Horizontal Scroll Behavior
|
|
582
|
+
|
|
583
|
+
**Automatic dropdown closing on horizontal scroll:**
|
|
584
|
+
|
|
585
|
+
The dropdown automatically closes when the user performs any horizontal scrolling action while the dropdown is open. This prevents the dropdown from appearing in the wrong position when:
|
|
586
|
+
|
|
587
|
+
- Tables with `overflow-x: auto` are scrolled horizontally
|
|
588
|
+
- Any scrollable container is scrolled horizontally
|
|
589
|
+
- Touchpad/trackpad horizontal gestures are used
|
|
590
|
+
- Mouse wheel horizontal scrolling is performed
|
|
591
|
+
|
|
592
|
+
### How It Works
|
|
593
|
+
|
|
594
|
+
The plugin uses two methods to detect horizontal scroll:
|
|
595
|
+
|
|
596
|
+
1. **Wheel Event Detection**: Detects horizontal mouse/touchpad scrolling in real-time
|
|
597
|
+
2. **Periodic Scroll Checking**: Every 50ms, checks if any scrollable element's `scrollLeft` position has changed
|
|
598
|
+
|
|
599
|
+
When horizontal scroll is detected, the dropdown immediately closes.
|
|
600
|
+
|
|
601
|
+
### Example
|
|
602
|
+
|
|
603
|
+
```html
|
|
604
|
+
<div style="overflow-x: auto; width: 100%;">
|
|
605
|
+
<table style="width: 2000px;">
|
|
606
|
+
<tr>
|
|
607
|
+
<td>
|
|
608
|
+
<div id="mySelect"></div>
|
|
609
|
+
</td>
|
|
610
|
+
<td>Other columns...</td>
|
|
611
|
+
</tr>
|
|
612
|
+
</table>
|
|
613
|
+
</div>
|
|
614
|
+
|
|
615
|
+
<script>
|
|
616
|
+
$('#mySelect').oneSelect({
|
|
617
|
+
data: ['Apple', 'Banana', 'Cherry']
|
|
618
|
+
});
|
|
619
|
+
</script>
|
|
620
|
+
```
|
|
621
|
+
|
|
622
|
+
**Behavior:**
|
|
623
|
+
- User opens dropdown ✅
|
|
624
|
+
- User scrolls table horizontally → **Dropdown closes automatically** ✅
|
|
625
|
+
|
|
626
|
+
---
|
|
627
|
+
|
|
628
|
+
## 🔄 AJAX Integration
|
|
629
|
+
|
|
630
|
+
### AJAX Configuration
|
|
631
|
+
|
|
632
|
+
```javascript
|
|
633
|
+
$('#mySelect').oneSelect({
|
|
634
|
+
ajax: {
|
|
635
|
+
url: '/api/items',
|
|
636
|
+
method: 'GET',
|
|
637
|
+
data: { category: 'fruits', active: true }
|
|
638
|
+
},
|
|
639
|
+
autoLoad: false
|
|
640
|
+
});
|
|
641
|
+
|
|
642
|
+
// Manual load
|
|
643
|
+
$('#loadBtn').on('click', function() {
|
|
644
|
+
$('#mySelect').oneSelect('loadData', {
|
|
645
|
+
url: '/api/different-items',
|
|
646
|
+
data: { filter: 'active' }
|
|
647
|
+
});
|
|
648
|
+
});
|
|
649
|
+
```
|
|
650
|
+
|
|
651
|
+
### Supported Response Formats
|
|
652
|
+
|
|
653
|
+
**1. Direct array:**
|
|
654
|
+
```json
|
|
655
|
+
["Apple", "Banana", "Cherry"]
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
**2. Wrapped with 'data':**
|
|
659
|
+
```json
|
|
660
|
+
{
|
|
661
|
+
"data": ["Apple", "Banana"]
|
|
662
|
+
}
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
**3. Wrapped with 'results':**
|
|
666
|
+
```json
|
|
667
|
+
{
|
|
668
|
+
"results": ["Apple", "Banana"]
|
|
669
|
+
}
|
|
670
|
+
```
|
|
671
|
+
|
|
672
|
+
**4. Object array:**
|
|
673
|
+
```json
|
|
674
|
+
[
|
|
675
|
+
{"value": 1, "label": "Apple"},
|
|
676
|
+
{"value": 2, "label": "Banana"}
|
|
677
|
+
]
|
|
678
|
+
```
|
|
679
|
+
|
|
680
|
+
---
|
|
681
|
+
|
|
682
|
+
## 📝 Form Submission
|
|
683
|
+
|
|
684
|
+
### Hidden Inputs
|
|
685
|
+
|
|
686
|
+
Component automatically creates `<input type="hidden">` elements:
|
|
687
|
+
|
|
688
|
+
```javascript
|
|
689
|
+
$('#mySelect').oneSelect({
|
|
690
|
+
name: 'items',
|
|
691
|
+
multiple: true,
|
|
692
|
+
data: ['A', 'B', 'C']
|
|
693
|
+
});
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
HTML result:
|
|
697
|
+
```html
|
|
698
|
+
<input type="hidden" name="items[]" value="A">
|
|
699
|
+
<input type="hidden" name="items[]" value="B">
|
|
700
|
+
<input type="hidden" name="items[]" value="C">
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
### data-ones-value Attribute Synchronization
|
|
704
|
+
|
|
705
|
+
The `data-ones-value` attribute automatically synchronizes with the current selection state:
|
|
706
|
+
|
|
707
|
+
**Real-time Updates:**
|
|
708
|
+
- Attribute updates immediately when items are selected/deselected
|
|
709
|
+
- Contains JSON array of selected values: `data-ones-value='["A","C"]'`
|
|
710
|
+
- Removed completely when no items are selected (not set to `[]` or `null`)
|
|
711
|
+
|
|
712
|
+
**Cancel Button Behavior:**
|
|
713
|
+
- Pressing Cancel clears all selections
|
|
714
|
+
- The `data-ones-value` attribute is **removed completely** from the DOM
|
|
715
|
+
- This ensures proper state management on page reload
|
|
716
|
+
|
|
717
|
+
**Server Integration:**
|
|
718
|
+
```php
|
|
719
|
+
// PHP: Set initial value from POST data
|
|
720
|
+
$selected = isset($_POST['items']) ? json_encode($_POST['items']) : '[]';
|
|
721
|
+
echo '<div id="mySelect" data-ones-value=\'' . $selected . '\'></div>';
|
|
722
|
+
```
|
|
723
|
+
|
|
724
|
+
**JavaScript Observation:**
|
|
725
|
+
```javascript
|
|
726
|
+
// Watch for attribute changes (useful for debugging)
|
|
727
|
+
$('#mySelect').on('DOMSubtreeModified', function() {
|
|
728
|
+
console.log($(this).data('ones-value')); // Current value as array
|
|
729
|
+
});
|
|
730
|
+
```
|
|
731
|
+
|
|
732
|
+
---
|
|
733
|
+
|
|
734
|
+
## 🏷️ Badge System
|
|
735
|
+
|
|
736
|
+
### Trigger Badges
|
|
737
|
+
|
|
738
|
+
```javascript
|
|
739
|
+
$('#mySelect').oneSelect({
|
|
740
|
+
showBadges: true
|
|
741
|
+
});
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
Result: `[Apple ×] [Banana ×] [Cherry ×]`
|
|
745
|
+
|
|
746
|
+
### External Badges
|
|
747
|
+
|
|
748
|
+
```javascript
|
|
749
|
+
<div id="myBadges"></div>
|
|
750
|
+
|
|
751
|
+
$('#mySelect').oneSelect({
|
|
752
|
+
showBadgesExternal: 'myBadges'
|
|
753
|
+
});
|
|
754
|
+
```
|
|
755
|
+
|
|
756
|
+
### Badge Properties
|
|
757
|
+
|
|
758
|
+
- **Background:** `#3b82f6` (light blue)
|
|
759
|
+
- **Text color:** `#fff` (white)
|
|
760
|
+
- **Remove button (×):** `#fff` (white)
|
|
761
|
+
- **Hover:** Light gray background
|
|
762
|
+
- **Remove:** Clicking × button unselects item
|
|
763
|
+
|
|
764
|
+
### Both Together
|
|
765
|
+
|
|
766
|
+
```javascript
|
|
767
|
+
$('#mySelect').oneSelect({
|
|
768
|
+
showBadges: true, // Badge in trigger
|
|
769
|
+
showBadgesExternal: 'myBadges' // Badge outside as well
|
|
770
|
+
});
|
|
771
|
+
```
|
|
772
|
+
|
|
773
|
+
---
|
|
774
|
+
|
|
775
|
+
## 🎨 CSS Styling
|
|
776
|
+
|
|
777
|
+
Main CSS classes with `cms-` prefix:
|
|
778
|
+
|
|
779
|
+
```css
|
|
780
|
+
.one-select /* Main container (relative positioned) */
|
|
781
|
+
.cms-wrapper /* Wrapper (relative positioned) */
|
|
782
|
+
.cms-trigger /* Button that opens dropdown */
|
|
783
|
+
.cms-selected-text /* Selected text */
|
|
784
|
+
.cms-dropdown /* Dropdown menu (absolute positioned) */
|
|
785
|
+
.cms-search-wrapper /* Search input wrapper */
|
|
786
|
+
.cms-search-input /* Search input field */
|
|
787
|
+
.cms-options-container /* Options container */
|
|
788
|
+
.cms-options-container.cms-loading /* Loading state for AJAX search */
|
|
789
|
+
.cms-option /* Single option */
|
|
790
|
+
.cms-option.selected /* Selected option */
|
|
791
|
+
.cms-option.select-all /* "Select All" option */
|
|
792
|
+
.cms-badge /* Badge */
|
|
793
|
+
.cms-badge-remove /* Badge × button */
|
|
794
|
+
.cms-btn /* OK/Cancel buttons */
|
|
795
|
+
```
|
|
796
|
+
|
|
797
|
+
### DOM Structure
|
|
798
|
+
|
|
799
|
+
```html
|
|
800
|
+
<!-- Wrapper element (your container) -->
|
|
801
|
+
<div class="one-select">
|
|
802
|
+
<div class="cms-wrapper">
|
|
803
|
+
<div class="cms-trigger">
|
|
804
|
+
<span class="cms-selected-text">Select...</span>
|
|
805
|
+
</div>
|
|
806
|
+
</div>
|
|
807
|
+
</div>
|
|
808
|
+
|
|
809
|
+
<!-- Dropdown is appended to body with dynamic positioning -->
|
|
810
|
+
<div class="cms-dropdown" style="position: fixed; top: ...; left: ...; width: ...;">
|
|
811
|
+
<!-- Search input (when showSearch is true) -->
|
|
812
|
+
<div class="cms-search-wrapper">
|
|
813
|
+
<input type="text" class="cms-search-input" placeholder="Search...">
|
|
814
|
+
</div>
|
|
815
|
+
<div class="cms-options-container">
|
|
816
|
+
<div class="cms-option select-all">...</div>
|
|
817
|
+
<div class="cms-option">
|
|
818
|
+
<input type="checkbox" id="cms-checkbox-ones-abc123-value-xy7z9q2" value="Apple">
|
|
819
|
+
<label for="cms-checkbox-ones-abc123-value-xy7z9q2">Apple</label>
|
|
820
|
+
</div>
|
|
821
|
+
</div>
|
|
822
|
+
<div class="cms-buttons">
|
|
823
|
+
<button class="cms-btn cms-btn-ok">OK</button>
|
|
824
|
+
<button class="cms-btn cms-btn-cancel">Cancel</button>
|
|
825
|
+
</div>
|
|
826
|
+
</div>
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
**Note:** The dropdown is positioned using `position: fixed` with viewport coordinates (`getBoundingClientRect()`). This ensures it stays correctly positioned even when parent elements scroll.
|
|
830
|
+
|
|
831
|
+
### Accessibility & Label-Checkbox Binding
|
|
832
|
+
|
|
833
|
+
**Native HTML Label-Checkbox Connection:**
|
|
834
|
+
|
|
835
|
+
Each checkbox is automatically assigned a unique ID, and the label is linked to it using the native HTML `for` attribute:
|
|
836
|
+
|
|
837
|
+
```html
|
|
838
|
+
<div class="cms-option">
|
|
839
|
+
<input type="checkbox" id="cms-checkbox-ones-abc123-value-xy7z9q2" value="Apple">
|
|
840
|
+
<label for="cms-checkbox-ones-abc123-value-xy7z9q2">Apple</label>
|
|
841
|
+
</div>
|
|
842
|
+
```
|
|
843
|
+
|
|
844
|
+
**Benefits:**
|
|
845
|
+
- ✅ **Proper Accessibility**: Screen readers correctly announce checkbox-label pairs
|
|
846
|
+
- ✅ **Native Browser Behavior**: Clicking the label toggles the checkbox automatically
|
|
847
|
+
- ✅ **No ID Conflicts**: Each checkbox gets a unique ID using instance ID + value + random suffix
|
|
848
|
+
- ✅ **Change Events**: Native `change` event fires when label is clicked
|
|
849
|
+
- ✅ **Multiple Instances**: Different OneSelect instances don't conflict with each other
|
|
850
|
+
|
|
851
|
+
**ID Format:**
|
|
852
|
+
```
|
|
853
|
+
cms-checkbox-{instanceId}-{sanitizedValue}-{random}
|
|
854
|
+
```
|
|
855
|
+
|
|
856
|
+
Example: `cms-checkbox-ones-abc123-apple-xy7z9q2`
|
|
857
|
+
|
|
858
|
+
|
|
859
|
+
### Custom CSS Example
|
|
860
|
+
|
|
861
|
+
```css
|
|
862
|
+
/* Selected option styling */
|
|
863
|
+
.cms-option.selected label {
|
|
864
|
+
font-weight: 600;
|
|
865
|
+
color: #007bff;
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
/* Badge styling */
|
|
869
|
+
.cms-badge {
|
|
870
|
+
background: #3b82f6;
|
|
871
|
+
color: #fff;
|
|
872
|
+
border-radius: 12px;
|
|
873
|
+
padding: 3px 8px;
|
|
874
|
+
}
|
|
875
|
+
|
|
876
|
+
/* Search input styling */
|
|
877
|
+
.cms-search-input {
|
|
878
|
+
background: #f8f9fa;
|
|
879
|
+
border-color: #dee2e6;
|
|
880
|
+
}
|
|
881
|
+
.cms-search-input:focus {
|
|
882
|
+
border-color: #3b82f6;
|
|
883
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
884
|
+
}
|
|
885
|
+
|
|
886
|
+
/* Custom dropdown width */
|
|
887
|
+
.one-select {
|
|
888
|
+
width: 400px;
|
|
889
|
+
}
|
|
890
|
+
```
|
|
891
|
+
|
|
892
|
+
---
|
|
893
|
+
|
|
894
|
+
## 🚀 Quick Usage Examples
|
|
895
|
+
|
|
896
|
+
```javascript
|
|
897
|
+
// 1. Simple
|
|
898
|
+
$('#select1').oneSelect({
|
|
899
|
+
data: ['A', 'B', 'C']
|
|
900
|
+
});
|
|
901
|
+
|
|
902
|
+
// 2. Pre-selected items (by index)
|
|
903
|
+
$('#select2').oneSelect({
|
|
904
|
+
data: ['Apple', 'Banana', 'Cherry'],
|
|
905
|
+
value: [0, 2] // Selects indices 0 and 2
|
|
906
|
+
});
|
|
907
|
+
|
|
908
|
+
// 3. Key-Value Object (NEW!)
|
|
909
|
+
$('#select3').oneSelect({
|
|
910
|
+
data: {
|
|
911
|
+
'id_1': 'Apple',
|
|
912
|
+
'id_2': 'Banana',
|
|
913
|
+
'id_3': 'Cherry'
|
|
914
|
+
},
|
|
915
|
+
value: ['id_1', 'id_3'], // Selects by keys
|
|
916
|
+
name: 'fruits'
|
|
917
|
+
});
|
|
918
|
+
|
|
919
|
+
// 4. Badges
|
|
920
|
+
$('#select4').oneSelect({
|
|
921
|
+
data: ['X', 'Y', 'Z'],
|
|
922
|
+
showBadges: true
|
|
923
|
+
});
|
|
924
|
+
|
|
925
|
+
// 5. Form submission
|
|
926
|
+
$('#select5').oneSelect({
|
|
927
|
+
data: ['P1', 'P2'],
|
|
928
|
+
name: 'products',
|
|
929
|
+
multiple: true,
|
|
930
|
+
submitForm: true,
|
|
931
|
+
formId: 'myForm'
|
|
932
|
+
});
|
|
933
|
+
|
|
934
|
+
// 6. AJAX with simple URL (NEW!)
|
|
935
|
+
$('#select6').oneSelect({
|
|
936
|
+
ajax: {url: '/api/items'},
|
|
937
|
+
autoLoad: true
|
|
938
|
+
});
|
|
939
|
+
|
|
940
|
+
// OR using data attribute (easiest):
|
|
941
|
+
// <div id="select6" data-ones-ajax="/api/items"></div>
|
|
942
|
+
|
|
943
|
+
// 7. Click outside behavior
|
|
944
|
+
$('#select7').oneSelect({
|
|
945
|
+
closeOnOutside: true // Close when clicking outside (default)
|
|
946
|
+
});
|
|
947
|
+
|
|
948
|
+
// 8. Search feature (local filtering)
|
|
949
|
+
$('#select8').oneSelect({
|
|
950
|
+
data: ['Apple', 'Banana', 'Cherry', 'Mango', 'Orange'],
|
|
951
|
+
showSearch: true,
|
|
952
|
+
searchPlaceholder: 'Search fruits...'
|
|
953
|
+
});
|
|
954
|
+
|
|
955
|
+
// 9. AJAX search with debounce
|
|
956
|
+
$('#select9').oneSelect({
|
|
957
|
+
showSearch: true,
|
|
958
|
+
searchUrl: '/api/search',
|
|
959
|
+
searchDebounceDelay: 500
|
|
960
|
+
});
|
|
961
|
+
```
|
|
962
|
+
|
|
963
|
+
---
|
|
964
|
+
|
|
965
|
+
## 📞 Support
|
|
966
|
+
|
|
967
|
+
### Links
|
|
968
|
+
|
|
969
|
+
- **NPM Package:** [@kamranbaylarov/one-select](https://www.npmjs.com/package/@kamranbaylarov/one-select)
|
|
970
|
+
- **GitHub:** [KamranBeylarov/one-select](https://github.com/KamranBeylarov/one-select)
|
|
971
|
+
- **Issues:** [Report issues](https://github.com/KamranBeylarov/one-select/issues)
|
|
972
|
+
|
|
973
|
+
### Installation
|
|
974
|
+
|
|
975
|
+
```bash
|
|
976
|
+
# NPM
|
|
977
|
+
npm install @kamranbaylarov/one-select
|
|
978
|
+
|
|
979
|
+
# CDN (coming soon)
|
|
980
|
+
```
|
|
981
|
+
|
|
982
|
+
### Project Structure
|
|
983
|
+
|
|
984
|
+
```
|
|
985
|
+
one-select/
|
|
986
|
+
├── css/
|
|
987
|
+
│ └── one-select.min.css
|
|
988
|
+
├── js/
|
|
989
|
+
│ ├── one-select.js
|
|
990
|
+
│ └── one-select.min.js
|
|
991
|
+
├── package.json
|
|
992
|
+
└── README.md
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
### License
|
|
996
|
+
|
|
997
|
+
MIT License - Feel free to use in your projects!
|
|
998
|
+
|
|
999
|
+
---
|
|
1000
|
+
|
|
1001
|
+
## 🎯 Browser Support
|
|
1002
|
+
|
|
1003
|
+
- Chrome (latest)
|
|
1004
|
+
- Firefox (latest)
|
|
1005
|
+
- Safari (latest)
|
|
1006
|
+
- Edge (latest)
|
|
1007
|
+
- Opera (latest)
|
|
1008
|
+
|
|
1009
|
+
---
|
|
1010
|
+
|
|
1011
|
+
**OneSelect** makes multi-select dropdowns simple and powerful! 🚀
|