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

Commit c3312d4

Browse files
committed
Manual merge for PR #38
2 parents c7d870a + 2a8638b commit c3312d4

File tree

4 files changed

+241
-18
lines changed

4 files changed

+241
-18
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

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

3333
<sub>Added: 1.1.2</sub>
3434

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

3838
#### onReady (eventHandler)
@@ -118,6 +118,36 @@ Example JSON object
118118

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

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

123153
##### requires (array)
@@ -153,7 +183,7 @@ Required dropdown value parameter name used in Ajax requests. If this value is n
153183

154184
<sub>Added: 1.1.5</sub>
155185

156-
Sets the default dropdown item on initialisation. The value can be a the value of the targeted dropdown item, or its index value.
186+
Sets the default dropdown item on initialisation. The value can be a the value of the targeted dropdown item, or its index value.
157187

158188
##### onChange (eventHandler)
159189

dist/jquery.cascadingdropdown.js

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -207,25 +207,42 @@
207207
var self = this;
208208

209209
// Remove all dropdown items and restore to initial state
210-
self.el.children('option').remove();
210+
self.el.find('option, optgroup').remove();
211211
self.el.append(self.originalDropdownItems);
212212

213-
if(!items || !items.length) {
213+
if(!items) {
214214
self._triggerReady();
215215
return;
216216
}
217217

218218
var selected;
219219

220220
// Add all items as dropdown item
221-
$.each(items, function(index, item) {
222-
var selectedAttr = '';
223-
if(item.selected) {
224-
selected = item;
221+
var getOption = function(item) {
222+
var selectedAttr = '';
223+
if(item.selected) {
224+
selected = item;
225+
}
226+
227+
return '<option value="' + item.value + '"' + selectedAttr + '>' + item.label + '</option>';
228+
};
229+
230+
if ($.isArray(items)) {
231+
$.each(items, function(index, item) {
232+
self.el.append(getOption(item));
233+
});
234+
} else {
235+
$.each(items, function(key, value) {
236+
var itemData = [];
237+
itemData.push('<optgroup label="' + key + '">');
238+
for (var i = 0; i < value.length; i++) {
239+
var item = value[i];
240+
itemData.push(getOption(item));
225241
}
226-
227-
self.el.append('<option value="' + item.value + '"' + selectedAttr + '>' + item.label + '</option>');
228-
});
242+
itemData.push('</optgroup>');
243+
self.el.append(itemData.join(''));
244+
});
245+
}
229246

230247
// Enable the dropdown
231248
self.enable();
@@ -293,7 +310,7 @@
293310

294311
// Instance array
295312
self.dropdowns = [];
296-
313+
297314
var dropdowns = $($.map(self.options.selectBoxes, function(item) {
298315
return item.selector;
299316
}).join(','), self.el);
@@ -310,7 +327,7 @@
310327
function changeEventHandler(event) {
311328
self.options.onChange.call(self, event, self.getValues());
312329
}
313-
330+
314331
if(typeof self.options.onReady === 'function') {
315332
dropdowns.bind('ready', readyEventHandler);
316333
}

index.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="res/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="res/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="res/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="res/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>

res/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+
});

0 commit comments

Comments
 (0)