Skip to content
This repository was archived by the owner on Oct 15, 2024. It is now read-only.

Commit 2a8638b

Browse files
committed
Add ability to accept and display optgroups
Added ability to parse and create option groups in the select Updated the README to explain the JSON object expected for option groups Added a demo item (example5) to show this functionallity Added call in ajax-mocks that groups the resolutions for the demo
1 parent 9dec4d1 commit 2a8638b

File tree

4 files changed

+242
-19
lines changed

4 files changed

+242
-19
lines changed

README.md

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# jQuery Cascading Dropdown Plugin
22

3-
A simple and lighweight jQuery plugin for creating cascading dropdowns.
3+
A simple and lighweight jQuery plugin for creating cascading dropdowns.
44

55
[View Demo](http://dnasir.com/github/jquery-cascading-dropdown/demo.html)
66

@@ -28,7 +28,7 @@ Tells the plugin to use POST when sending Ajax request.
2828

2929
<sub>Added: 1.1.2</sub>
3030

31-
Tells the plugin to stringify (JSON.stringify) dropdown data for Ajax requests. Requires
31+
Tells the plugin to stringify (JSON.stringify) dropdown data for Ajax requests. Requires
3232
[json2.js](https://github.com/douglascrockford/JSON-js) if you're planning to support older browsers.
3333

3434
#### onReady (eventHandler)
@@ -114,6 +114,36 @@ Example JSON object
114114

115115
It's also possible to include a property named 'selected' in the object to define a selected item.
116116

117+
It is also possible to create option groups in the select by specifying a key (the group name) in the JSON.
118+
119+
Example JSON object with groups
120+
121+
{
122+
'My Group':
123+
[
124+
{
125+
"label": "Item 1",
126+
"value": "1"
127+
},
128+
{
129+
"label": "Item 2",
130+
"value": "2"
131+
}
132+
],
133+
'Another Group':
134+
[
135+
{
136+
"label": "Item 3",
137+
"value": "3"
138+
},
139+
{
140+
"label": "Item 4",
141+
"value": "4"
142+
}
143+
]
144+
}
145+
146+
117147
If the source parameter is not set, the plugin will simply enable the select box when requirements are met.
118148

119149
##### requires (array)
@@ -149,7 +179,7 @@ Required dropdown value parameter name used in Ajax requests. If this value is n
149179

150180
<sub>Added: 1.1.5</sub>
151181

152-
Sets the default dropdown item on initialisation. The value can be a the value of the targeted dropdown item, or its index value.
182+
Sets the default dropdown item on initialisation. The value can be a the value of the targeted dropdown item, or its index value.
153183

154184
##### onChange (eventHandler)
155185

ajax-mocks.js

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,10 +120,34 @@ function getResolutions(screen, storage) {
120120
var phones = getPhones(screen, null, storage);
121121

122122
var resolutions = $.map(phones, function(phone) { return phone.resolution; });
123+
123124
resolutions.sort(asc);
124125
return arrayUnique(resolutions);
125126
}
126127

128+
function getGroupedResolutions(screen, storage) {
129+
var phones = getPhones(screen, null, storage);
130+
131+
// Create SD and HD resolution groups
132+
// SD <= 540
133+
// HD >= 720
134+
var groupedResolutions = {'SD': [], 'HD': []};
135+
$.each(phones, function(index, item) {
136+
if (item.resolution <= 540) {
137+
groupedResolutions.SD.push(item.resolution);
138+
} else {
139+
groupedResolutions.HD.push(item.resolution);
140+
}
141+
});
142+
143+
$.each(groupedResolutions, function(key, value) {
144+
value.sort(asc);
145+
groupedResolutions[key] = arrayUnique(value);
146+
});
147+
148+
return groupedResolutions;
149+
}
150+
127151
function getStorages(screen, resolution) {
128152
var phones = getPhones(screen, resolution, null);
129153

@@ -169,6 +193,15 @@ $.mockjax({
169193
}
170194
});
171195

196+
$.mockjax({
197+
url: '/api/resolutionsGrouped',
198+
contentType: 'application/json; charset=utf-8',
199+
responseTime: 1000,
200+
response: function(settings){
201+
this.responseText = JSON.stringify(getGroupedResolutions(settings.data.screen, settings.data.storage));
202+
}
203+
});
204+
172205
$.mockjax({
173206
url: '/api/storages',
174207
contentType: 'application/json; charset=utf-8',
@@ -185,4 +218,4 @@ $.mockjax({
185218
response: function(settings){
186219
this.responseText = JSON.stringify(getPhones(settings.data.screen, settings.data.resolution, settings.data.storage));
187220
}
188-
});
221+
});

demo.html

Lines changed: 146 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,90 @@ <h6>Code</h6>
273273

274274
<br />
275275

276+
<h4>Option Group</h4>
277+
<p>This example demonstrates the plugin's capability to combine both standard and grouped (option group) dropdowns.</p>
278+
279+
<div id="example5" class="bs-docs-example">
280+
<h4>Phone finder</h4>
281+
282+
<select class="step1" name="screen">
283+
<option value="">Screen size</option>
284+
<option value="4" selected="selected">4.0"</option>
285+
<option value="4.3">4.3"</option>
286+
<option value="4.7">4.7"</option>
287+
<option value="5">5.0"</option>
288+
</select>
289+
<select class="step2" name="resolution">
290+
<option value="">Screen resolution</option>
291+
</select>
292+
<select class="step3" name="storage">
293+
<option value="">Storage size</option>
294+
</select>
295+
296+
<h4>Matches <img src="ajax-loader.gif" data-bind="visible: loading" /></h4>
297+
<ul data-bind="foreach: phones, visible: phones().length > 0">
298+
<li>
299+
<span data-bind="text: maker"></span>
300+
<span data-bind="text: model"></span>
301+
</li>
302+
</ul>
303+
<p data-bind="visible: phones().length == 0">No matches</p>
304+
</div>
305+
306+
<h6>Code</h6>
307+
<div>
308+
<pre class="brush: js">$('#example5').cascadingDropdown({
309+
selectBoxes: [
310+
{
311+
selector: '.step1'
312+
},
313+
{
314+
selector: '.step2',
315+
source: function(request, response) {
316+
$.getJSON('/api/resolutionsGrouped', request, function(data) {
317+
var newData = {};
318+
$.each(data, function(key, value) {
319+
newData[key] = $.map(value, function(item, index) {
320+
return {
321+
label: item + 'p',
322+
value: item
323+
};
324+
});
325+
});
326+
327+
response(newData);
328+
});
329+
}
330+
},
331+
{
332+
selector: '.step3',
333+
requires: ['.step1', '.step2'],
334+
requireAll: true,
335+
source: function(request, response) {
336+
$.getJSON('/api/storages', request, function(data) {
337+
response($.map(data, function(item, index) {
338+
return {
339+
label: item + ' GB',
340+
value: item,
341+
selected: index == 0 // set to true to mark it as the selected item
342+
};
343+
}));
344+
});
345+
}
346+
}
347+
],
348+
onChange: function(event, dropdownData) {
349+
// do stuff
350+
// dropdownData is an object with values from all the dropdowns in this group
351+
},
352+
onReady: function(event, dropdownData) {
353+
// do stuff
354+
}
355+
});</pre>
356+
</div>
357+
358+
<br />
359+
276360
<h4>Multiple select</h4>
277361
<p>You can enable multiple select by including the <code>multiple</code> attribute. The value for the dropdown will then be an array of strings instead of a string. However, you will need to ensure that your backend service supports this type of data.</p>
278362

@@ -321,11 +405,13 @@ <h4>Matches <img src="ajax-loader.gif" data-bind="visible: loading" /></h4>
321405
example2 = new viewmodel(),
322406
example3 = new viewmodel(),
323407
example4 = new viewmodel();
408+
example5 = new viewmodel();
324409

325410
ko.applyBindings(example1, document.getElementById('example1'));
326411
ko.applyBindings(example2, document.getElementById('example2'));
327412
ko.applyBindings(example3, document.getElementById('example3'));
328413
ko.applyBindings(example4, document.getElementById('example4'));
414+
ko.applyBindings(example5, document.getElementById('example5'));
329415

330416
// Example 1
331417
$('#example1').cascadingDropdown({
@@ -356,7 +442,7 @@ <h4>Matches <img src="ajax-loader.gif" data-bind="visible: loading" /></h4>
356442
}
357443
]
358444
});
359-
445+
360446
// Example 2
361447
$('#example2').cascadingDropdown({
362448
selectBoxes: [
@@ -410,7 +496,7 @@ <h4>Matches <img src="ajax-loader.gif" data-bind="visible: loading" /></h4>
410496
}
411497
]
412498
});
413-
499+
414500
// Example 3
415501
$('#example3').cascadingDropdown({
416502
selectBoxes: [
@@ -516,11 +602,68 @@ <h4>Matches <img src="ajax-loader.gif" data-bind="visible: loading" /></h4>
516602
});
517603
}
518604
});
605+
606+
// Example 5
607+
$('#example5').cascadingDropdown({
608+
selectBoxes: [
609+
{
610+
selector: '.step1'
611+
},
612+
{
613+
selector: '.step2',
614+
source: function(request, response) {
615+
$.getJSON('/api/resolutionsGrouped', request, function(data) {
616+
var newData = {};
617+
$.each(data, function(key, value) {
618+
newData[key] = $.map(value, function(item, index) {
619+
return {
620+
label: item + 'p',
621+
value: item
622+
};
623+
});
624+
});
625+
626+
response(newData);
627+
});
628+
}
629+
},
630+
{
631+
selector: '.step3',
632+
requires: ['.step1', '.step2'],
633+
requireAll: true,
634+
source: function(request, response) {
635+
$.getJSON('/api/storages', request, function(data) {
636+
response($.map(data, function(item, index) {
637+
return {
638+
label: item + ' GB',
639+
value: item,
640+
selected: index == 0 // set to true to mark it as the selected item
641+
};
642+
}));
643+
});
644+
}
645+
}
646+
],
647+
onChange: function(event, dropdownData) {
648+
example5.loading(true);
649+
$.getJSON('/api/phones', dropdownData, function(data) {
650+
example5.phones(data);
651+
example5.loading(false);
652+
});
653+
},
654+
onReady: function(event, dropdownData) {
655+
example5.loading(true);
656+
$.getJSON('/api/phones', dropdownData, function(data) {
657+
example5.phones(data);
658+
example5.loading(false);
659+
});
660+
}
661+
});
519662
</script>
520663
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shCore.js"></script>
521664
<script type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/SyntaxHighlighter/3.0.83/scripts/shBrushJScript.js"></script>
522665
<script type="text/javascript">
523666
SyntaxHighlighter.all();
524667
</script>
525668
</body>
526-
</html>
669+
</html>

jquery.cascadingdropdown.js

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/*
1+
/*
22
* jQuery Cascading Dropdown Plugin 1.2.5
33
* https://github.com/dnasir/jquery-cascading-dropdown
44
*
@@ -194,25 +194,42 @@
194194
var self = this;
195195

196196
// Remove all dropdown items and restore to initial state
197-
self.el.children('option').remove();
197+
self.el.find('option, optgroup').remove();
198198
self.el.append(self.originalDropdownItems);
199199

200-
if(!items || !items.length) {
200+
if(!items) {
201201
self._triggerReady();
202202
return;
203203
}
204204

205205
var selected;
206206

207207
// Add all items as dropdown item
208-
$.each(items, function(index, item) {
209-
var selectedAttr = '';
210-
if(item.selected) {
211-
selected = item;
208+
var getOption = function(item) {
209+
var selectedAttr = '';
210+
if(item.selected) {
211+
selected = item;
212+
}
213+
214+
return '<option value="' + item.value + '"' + selectedAttr + '>' + item.label + '</option>';
215+
};
216+
217+
if ($.isArray(items)) {
218+
$.each(items, function(index, item) {
219+
self.el.append(getOption(item));
220+
});
221+
} else {
222+
$.each(items, function(key, value) {
223+
var itemData = [];
224+
itemData.push('<optgroup label="' + key + '">');
225+
for (var i = 0; i < value.length; i++) {
226+
var item = value[i];
227+
itemData.push(getOption(item));
212228
}
213-
214-
self.el.append('<option value="' + item.value + '"' + selectedAttr + '>' + item.label + '</option>');
215-
});
229+
itemData.push('</optgroup>');
230+
self.el.append(itemData.join(''));
231+
});
232+
}
216233

217234
// Enable the dropdown
218235
self.enable();
@@ -280,7 +297,7 @@
280297

281298
// Instance array
282299
self.dropdowns = [];
283-
300+
284301
var dropdowns = $($.map(self.options.selectBoxes, function(item) {
285302
return item.selector;
286303
}).join(','), self.el);
@@ -297,7 +314,7 @@
297314
function changeEventHandler(event) {
298315
self.options.onChange.call(self, event, self.getValues());
299316
}
300-
317+
301318
if(typeof self.options.onReady === 'function') {
302319
dropdowns.bind('ready', readyEventHandler);
303320
}

0 commit comments

Comments
 (0)