Search code examples
jqueryjsonoptgroup

GroupBy in JavaScript to group JSON data and populate on optgroup


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.


Solution

  • Assuming the optgroups already exist, change this...

    .appendTo("optgroup")
    

    to this...

    .appendTo("optgroup[label='" + item.category + "']");
    

    http://jsfiddle.net/FG9Lg/


    If they don't exist, you need to create them, though I'd suggest a restructuring of your JSON response to have each item nested under the proper category.

    Like this...

    {
        "Category 1":[
            {"id": "210","name": "Name 1"},
            {"id": "187","name": "Name 2"},
            {"id": "186","name": "Name 3"},
            {"id": "185","name": "Name 4"},
            {"id": "184","name": "Name 5"},
            {"id": "183","name": "Name 6"},
            {"id": "182","name": "Name 7"}
        ],
        "Category 2":[
            {"id": "181","name": "Name 8"},
            {"id": "178","name": "Name 10"}
        ],
        "Category 3": [
            {"id": "180","name": "Name 9"}
        ]
    }
    

    So you could then do this:

    var product = $('#product');
    
    $.each(data, function (key, cat) {
        var group = $('<optgroup>',{label:key});
    
        $.each(cat,function(i,item) {
            $("<option/>",{value:item.id,text:item.name})
                .appendTo(group);
        });
    
        group.appendTo( product );
    });
    

    http://jsfiddle.net/FG9Lg/1/