2011-12-20 1 views
11

Je suis un peu perdu. Je reçois ce JSON:GroupBy en JavaScript pour grouper les données JSON et remplir sur optgroup

[{ 
    "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" 
}] 

Et je voudrais mettre tout cela dans une sélection avec des options et optgroups. En fait, la optgroup devrait être la catégorie

Je voudrais quelque chose comme ceci:

<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> 

Aujourd'hui, je n'ai fait parce que je me bats trop:

$(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"); 
     }); 
    }); 
}); 

Comme vous ne pouvez pas voir optgroup :) Y at-il un moyen de faire cela? Je peux aussi modifier mon JSON si cela peut le rendre plus facile.

Merci pour toute aide.

Répondre

16

En supposant que les optgroups existent déjà, changer cela ...

.appendTo("optgroup") 

à cette ...

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

http://jsfiddle.net/FG9Lg/


Si elles n'existent pas, vous besoin de les créer, bien que je suggère une restructuration de votre réponse JSON pour avoir chaque élément imbriqué sous le catégorie appropriée.

Comme ça ...

{ 
    "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"} 
    ] 
} 

Alors vous pourriez faire ceci:

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/

+1

nom d'utilisateur épique est tout ce que je dois dire. – donutdan4114

+0

@ donutdan4114 Merci. C'était soit cela ou "REGARDEZ-MOI! REGARDEZ-MOI!". –

+1

Merci beaucoup! J'ai modifié mon JSON et fait comme tu l'as dit! Cela fonctionne parfaitement! – user1108276

16

Si je vous, je voudrais utiliser une petite bibliothèque appelée Underscore pour regrouper les données qui sont retournées dans une représentation plus facile.

Voir le code ci-dessous et vous pouvez également voir ce 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]); 
} 

Si vous hésitez à utiliser la bibliothèque Souligné, vous pouvez envisager cette fonction groupBy:

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; 
} 

USAGES:

var groupData = groupBy(data, function (obj) { 
    return obj.category; 
}); 
0

Si vous souhaitez vous garder le format JSON tel quel, ce qui suit pourrait répondre à votre question:

//Loop through the json, get distinct category names, and append them as optgroup to the select dropdown 
var categories = []; 
$.each(data, function(index, item) { 
    if ($.inArray(item.category, categories) == -1) { 
     categories.push(item.category); 
     var optgroupId = "cat-" + item.category.replace(/\s/g, ""); 
     $('#id_of_select_dropdown').append('<optgroup id ="'+optgroupId+'"label="'+item.category+'">'); 
    } 
}); 
// append the options to their corresponding optgroups 
$.each(data.response, function(index, item) { 
    var optgroupId = "cat-" + item.category.replace(/\s/g, ""); 
    $('#'+optgroupId).append('<option>' + item.name + '</option>'); 
}); 

Hope this helps!

2

Je sais que ce sujet est très ancien, mais j'avais besoin de quelque chose de similaire et je suis arrivé avec ça. Il ajoute automatiquement des optgroups lorsque cela est nécessaire et les remplit avec des options. De plus, cela fonctionne à la fois lorsque vous avez des optgroups et quand vous ne le faites pas.

http://jsfiddle.net/mzj0nuet/

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); 
    }   
}); 
Questions connexes