11<!DOCTYPE html>
2- < html >
3- < head >
4- < meta charset ="utf-8 ">
2+ < html lang =" en " >
3+ < head >
4+ < meta charset ="utf-8 ">
55 < meta name ="viewport " content ="width=device-width,minimum-scale=1 ">
6- < title > Multi Select JS</ title >
6+ < title > Multi Select JS - Demos </ title >
77 <!-- Include the Multi Select stylesheet -->
88 < link href ="MultiSelect.css " rel ="stylesheet " type ="text/css ">
99 < style >
10- * {
11- box-sizing : border-box;
12- font-family : system-ui, "Segoe UI" , Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji" , "Segoe UI Emoji" , "Segoe UI Symbol" ;
13- font-size : 16px ;
14- }
15- body {
16- margin : 0 ;
17- padding : 15px ;
18- background-color : # f3f4f7 ;
19- }
20- form {
21- display : flex;
22- flex-direction : column;
23- margin : 100px auto;
24- padding : 40px 40px 60px ;
25- max-width : 500px ;
26- width : 100% ;
27- background-color : # fff ;
28- border-radius : 5px ;
29- box-shadow : 0 0 10px rgba (0 , 0 , 0 , 0.1 );
30- }
31- form h1 {
32- margin : 10px 0 5px ;
33- font-size : 24px ;
34- font-weight : 500 ;
35- color : # 474b50 ;
36- }
37- form label {
38- margin : 25px 0 10px ;
39- font-weight : 500 ;
40- color : # 474b50 ;
41- }
10+ * {
11+ box-sizing : border-box;
12+ font-family : system-ui, "Segoe UI" , Roboto, Helvetica, Arial, sans-serif;
13+ font-size : 16px ;
14+ }
15+ body {
16+ margin : 0 ;
17+ padding : 20px ;
18+ background-color : # f3f4f7 ;
19+ color : # 212529 ;
20+ }
21+ .container {
22+ display : flex;
23+ flex-direction : column;
24+ margin : 60px auto;
25+ padding : 40px 50px 50px ;
26+ max-width : 600px ;
27+ width : 100% ;
28+ background-color : # fff ;
29+ border-radius : 8px ;
30+ box-shadow : 0 4px 15px rgba (0 , 0 , 0 , 0.05 );
31+ }
32+ h1 {
33+ margin : 0 0 5px ;
34+ font-size : 28px ;
35+ font-weight : 600 ;
36+ color : # 212529 ;
37+ }
38+ p .description {
39+ color : # 65727e ;
40+ margin-top : 0 ;
41+ margin-bottom : 10px ;
42+ font-size : 15px ;
43+ line-height : 1.5 ;
44+ }
45+ label {
46+ display : block;
47+ margin : 20px 0 10px ;
48+ font-weight : 600 ;
49+ color : # 212529 ;
50+ padding-bottom : 8px ;
51+ }
52+ .hint {
53+ display : block;
54+ font-size : 13px ;
55+ color : # 888 ;
56+ margin-top : 5px ;
57+ margin-bottom : 5px ;
58+ font-weight : normal;
59+ }
60+ .btn {
61+ display : inline-block;
62+ margin-top : 30px ;
63+ padding : 14px 20px ;
64+ background : # 40c979 ;
65+ color : # fff ;
66+ font-weight : bold;
67+ font-size : 16px ;
68+ border : none;
69+ border-radius : 5px ;
70+ cursor : pointer;
71+ transition : background 0.2s ;
72+ width : 100% ;
73+ }
74+ .btn : hover { background : # 35b068 ; }
75+ .btn-small {
76+ width : auto;
77+ margin-top : 10px ;
78+ font-size : 14px ;
79+ padding : 8px 15px ;
80+ background : # 6c757d ;
81+ }
82+ .btn-small : hover { background : # 5a6268 ; }
4283 </ style >
43- </ head >
44- < body >
45- < form >
46-
47- < h1 > Multi Select Dropdown</ h1 >
48-
49- < label for ="fruits "> Fruits</ label >
50- < select id ="fruits " name ="fruits " data-placeholder ="Select fruits " multiple data-multi-select >
51- < option value ="Apple "> Apple</ option >
52- < option value ="Banana "> Banana</ option >
53- < option value ="Blackberry "> Blackberry</ option >
54- < option value ="Blueberry "> Blueberry</ option >
55- < option value ="Cherry "> Cherry</ option >
56- < option value ="Cranberry "> Cranberry</ option >
57- < option value ="Grapes "> Grapes</ option >
58- < option value ="Kiwi "> Kiwi</ option >
59- < option value ="Mango "> Mango</ option >
60- < option value ="Orange "> Orange</ option >
61- < option value ="Peach "> Peach</ option >
62- < option value ="Pear "> Pear</ option >
63- < option value ="Pineapple "> Pineapple</ option >
64- < option value ="Raspberry "> Raspberry</ option >
65- < option value ="Strawberry "> Strawberry</ option >
66- < option value ="Watermelon "> Watermelon</ option >
84+ </ head >
85+ < body >
86+
87+ < form class ="container " onsubmit ="event.preventDefault(); alert('Success! Form validation passed and data is ready to be submitted.'); ">
88+
89+ < h1 > Multi Select JS</ h1 >
90+ < p class ="description "> A lightweight, dependency-free, and highly customizable Vanilla JavaScript library. Check out the interactive demos below.</ p >
91+
92+ <!-- DEMO 1: OptGroups -->
93+ < label for ="fruits ">
94+ 1. Standard & OptGroups
95+ < span class ="hint "> Parses standard HTML < code > <optgroup></ code > tags. Click a group header to toggle the entire sublist.</ span >
96+ </ label >
97+ < select id ="fruits " name ="fruits[] " data-placeholder ="Select fruits " multiple data-multi-select >
98+ < optgroup label ="Berries ">
99+ < option value ="Blackberry "> Blackberry</ option >
100+ < option value ="Blueberry "> Blueberry</ option >
101+ < option value ="Raspberry "> Raspberry</ option >
102+ < option value ="Strawberry "> Strawberry</ option >
103+ </ optgroup >
104+ < optgroup label ="Citrus ">
105+ < option value ="Orange "> Orange</ option >
106+ < option value ="Grapefruit "> Grapefruit</ option >
107+ < option value ="Lemon "> Lemon</ option >
108+ </ optgroup >
109+ < optgroup label ="Other ">
110+ < option value ="Apple "> Apple</ option >
111+ < option value ="Banana "> Banana</ option >
112+ < option value ="Mango "> Mango</ option >
113+ < option value ="Watermelon "> Watermelon</ option >
114+ </ optgroup >
67115 </ select >
68116
69- < label for ="cars "> Car Manufacturers</ label >
70- < select id ="cars " name ="cars " data-placeholder ="Select car manufacturers " data-max ="2 " data-search ="false " data-select-all ="false " data-width ="300px " data-height ="50px " multiple data-multi-select >
117+ <!-- DEMO 2: Validation & Limits -->
118+ < label for ="cars ">
119+ 2. Limits & Form Validation
120+ < span class ="hint "> Try to submit the form without selecting a car. Uses < code > required</ code > , < code > data-max="3"</ code > , and hides the "Select All" button.</ span >
121+ </ label >
122+ < select id ="cars " name ="cars[] " data-placeholder ="Select up to 3 cars (Required) " required data-max ="3 " data-select-all ="false " multiple data-multi-select >
71123 < option value ="Audi "> Audi</ option >
72124 < option value ="BMW "> BMW</ option >
73125 < option value ="Chevrolet "> Chevrolet</ option >
126+ < option value ="Dodge "> Dodge</ option >
127+ < option value ="Ford "> Ford</ option >
128+ < option value ="Honda "> Honda</ option >
129+ < option value ="Toyota "> Toyota</ option >
74130 </ select >
75131
76- < label for ="dynamic "> Dynamic Select</ label >
77- < select id ="dynamic " name ="dynamic "> </ select >
132+ <!-- DEMO 3: Dark Mode -->
133+ < label for ="darkmode ">
134+ 3. Dark Mode Theme
135+ < span class ="hint "> Easily toggle themes using < code > data-theme="dark"</ code > (Accepts: auto, light, dark).</ span >
136+ </ label >
137+ < select id ="darkmode " name ="darkmode[] " data-placeholder ="Dark mode active... " data-theme ="dark " multiple data-multi-select >
138+ < option value ="1 "> Dark Option 1</ option >
139+ < option value ="2 "> Dark Option 2</ option >
140+ < option value ="3 "> Dark Option 3</ option >
141+ </ select >
142+
143+ <!-- DEMO 4: Advanced JS Init -->
144+ < label for ="dynamic ">
145+ 4. Advanced JS Initialization
146+ < span class ="hint "> Initialized entirely via JavaScript. Showcases HTML tag injection, custom callbacks, and auto-close on selection.</ span >
147+ </ label >
148+ < select id ="dynamic " name ="dynamic[] " multiple > </ select >
149+
150+ <!-- DEMO 5: Async Fetch -->
151+ < label for ="async ">
152+ 5. Async Data Fetching
153+ < span class ="hint "> Natively fetch JSON arrays from remote endpoints.</ span >
154+ </ label >
155+ < select id ="async " name ="async[] " multiple > </ select >
156+ < button id ="fetch-btn " type ="button " class ="btn btn-small "> Fetch Remote Data</ button >
157+
158+
159+ <!-- Submit Button for Testing Form Validation -->
160+ < button type ="submit " class ="btn "> Test Form Submission</ button >
78161
79162 </ form >
163+
80164 <!-- Include the Multi Select JS class -->
81165 < script src ="MultiSelect.js "> </ script >
166+
167+ <!-- Initialize Custom JS Demos -->
82168 < script >
83- // Initialize the Multi Selects
84- new MultiSelect ( '#dynamic' , {
85- data : [
86- {
87- value : 'opt1' ,
88- text : 'Option 1'
89- } ,
90- {
91- value : 'opt2' ,
92- html : '<strong>Option 2 with HTML!</strong>'
169+ // ==========================================
170+ // DEMO 4: Advanced JS Configuration
171+ // ==========================================
172+ const dynamicSelect = new MultiSelect ( '#dynamic' , {
173+ placeholder : 'Select an option' ,
174+ search : true ,
175+ selectAll : false ,
176+ listAll : false , // Will show "X selected" instead of rendering tags
177+ closeListOnItemSelect : true , // Auto-closes dropdown on click
178+ data :[
179+ { value : 'opt1' , text : 'Standard Option' } ,
180+ { value : 'opt2' , html : '<span style="color: #e44e4e; font-weight: bold;">🔴 Option 2 with Custom HTML!</span>' } ,
181+ { value : 'opt3' , text : 'Pre-Selected Option' , selected : true } ,
182+ { value : 'opt4' , text : 'Option 4' } ,
183+ { value : 'opt5' , text : 'Option 5' }
184+ ] ,
185+ onChange : function ( value , text , element ) {
186+ console . log ( 'Change Event:' , value , text ) ;
93187 } ,
94- {
95- value : 'opt3' ,
96- text : 'Option 3' ,
97- selected : true
188+ onSelect : function ( value , text , element ) {
189+ console . log ( 'Selected Event:' , value ) ;
98190 } ,
99- {
100- value : 'opt4' ,
101- text : 'Option 4'
102- } ,
103- {
104- value : 'opt5' ,
105- text : 'Option 5'
191+ onUnselect : function ( value , text , element ) {
192+ console . log ( 'Unselected Event:' , value ) ;
106193 }
107- ] ,
108- placeholder : 'Select an option' ,
109- search : true ,
110- selectAll : true ,
111- listAll : false ,
112- max : 2 ,
113- onChange : function ( value , text , element ) {
114- console . log ( 'Change:' , value , text , element ) ;
115- } ,
116- onSelect : function ( value , text , element ) {
117- console . log ( 'Selected:' , value , text , element ) ;
118- } ,
119- onUnselect : function ( value , text , element ) {
120- console . log ( 'Unselected:' , value , text , element ) ;
121- }
122- } ) ;
194+ } ) ;
195+
196+ // ==========================================
197+ // DEMO 5: Async Fetch Data API
198+ // ==========================================
199+ const asyncSelect = new MultiSelect ( '#async' , {
200+ placeholder : 'Click fetch button to load...' ,
201+ search : true ,
202+ selectAll : true
203+ } ) ;
204+
205+ document . getElementById ( 'fetch-btn' ) . addEventListener ( 'click' , async ( e ) => {
206+ const btn = e . target ;
207+ btn . textContent = "Loading..." ;
208+ btn . disabled = true ;
209+
210+ // Mock an API Response to keep the demo self-contained
211+ const mockApiData = JSON . stringify ( [
212+ { value : 'remote_1' , text : 'Cloud User 1' , group : 'Fetched Data' } ,
213+ { value : 'remote_2' , text : 'Cloud User 2' , group : 'Fetched Data' } ,
214+ { value : 'remote_3' , text : 'Cloud User 3' , group : 'Fetched Data' } ,
215+ { value : 'remote_4' , text : 'Cloud User 4' , group : 'Fetched Data' }
216+ ] ) ;
217+
218+ // Create a blob URL to simulate fetching from a real remote domain
219+ const blob = new Blob ( [ mockApiData ] , { type : 'application/json' } ) ;
220+ const mockApiUrl = URL . createObjectURL ( blob ) ;
221+
222+ // Trigger the native fetch function inside your library
223+ await asyncSelect . fetch ( mockApiUrl ) ;
224+
225+ btn . textContent = "Data Loaded Successfully!" ;
226+ btn . style . backgroundColor = "#40c979" ;
227+ btn . style . color = "#fff" ;
228+ } ) ;
123229 </ script >
124230
125231 </ body >
126- </ html >
232+ </ html >
0 commit comments