GroupBy in JavaScript to group JSON data and populate on optgroup
Solution 1
If I were you, I would use a small library called Underscore to group the data which is returned in a easier representation.
See this code below and you may also see this live demo:
var groupData = _.groupBy(data, function (obj) {
return obj.category;
});
var optGroups = [];
for (var key in groupData) {
if (groupData.hasOwnProperty(key)) {
var optGroup = $("<optgroup></optgroup>");
optGroup.attr("label", key);
var currentGroup = groupData[key];
for (var i = 0; i < currentGroup.length; i++) {
$("<option />").attr("value", currentGroup[i].id).html(currentGroup[i].name).appendTo(optGroup);
}
optGroups.push(optGroup);
}
}
for(var i = 0; i < optGroups.length; i++) {
$("#products").append(optGroups[i]);
}
If you hesitate to use Underscore library, you may consider this groupBy
function:
var groupBy = function(array, predicate) {
var grouped = {};
for(var i = 0; i < array.length; i++) {
var groupKey = predicate(array[i]);
if (typeof(grouped[groupKey]) === "undefined")
grouped[groupKey] = [];
grouped[groupKey].push(array[i]);
}
return grouped;
}
USAGE:
var groupData = groupBy(data, function (obj) {
return obj.category;
});
Solution 2
I know this thread is very old, but I was needing something similar and I came up with this. It automatically adds optgroups when needed and populate them with options. Plus, it works both when you have optgroups and when you don't.
var select = $('#product');
$.each(data, function (key, cat) {
var option = "<option value='"+cat.id+"'>"+cat.name+"</option>";
// If we ave a category property, add this item to an optgroup
if (cat.hasOwnProperty("category")) {
var group = cat.category;
// If this optgroup is not already present, add it
if (select.find("optgroup[label='" + group + "']").length === 0) {
select.append("<optgroup label='" + group + "' />");
}
select.find("optgroup[label='" + group + "']").append(option);
// No category, no optgroup. Add this as simple option
} else {
select.append(option);
}
});
user1108276
Updated on July 09, 2022Comments
-
user1108276 almost 2 years
I am a little bit lost. I am getting this JSON:
[{ "id": "210", "name": "Name 1", "category": "Category 1" }, { "id": "187", "name": "Name 2", "category": "Category 1" }, { "id": "186", "name": "Name 3", "category": "Category 1" }, { "id": "185", "name": "Name 4", "category": "Category 1" }, { "id": "184", "name": "Name 5", "category": "Category 1" }, { "id": "183", "name": "Name 6", "category": "Category 1" }, { "id": "182", "name": "Name 7", "category": "Category 1" }, { "id": "181", "name": "Name 8", "category": "Category 2" }, { "id": "180", "name": "Name 9", "category": "Category 3" }, { "id": "178", "name": "Name 10", "category": "Category 2" }]
And I would like to put all of this in a select with options and optgroups. Actually the optgroup should be category
I would like something like this:
<select name="products" class="product" id="product"> <optgroup label="Category 1"> <option value="210">Name 1</option> <option value="187">Name 2</option> <option value="186">Name 3</option> <option value="185">Name 4</option> ... </optgroup> <optgroup label="Category 2"> <option value="181">Name 8</option> <option value="178">Name 10</option> </optgroup> <optgroup label="Category 3"> <option value="180">Name 9</option> </optgroup>
Today I have only made this because I'm struggling too much:
$(document).ready(function () { $.getJSON("5.php", { val: $(this).val() }, function (data) { $.each(data, function (i, item) { $("<option/>").attr("value", item.id).append(item.name).appendTo("optgroup"); }); }); });
As you can see no optgroup :) Is there a way to do this? I can also modify my JSON if it can make it easier.
Thanks for any help.