2011-12-20 71 views
11

我有点迷路。 我得到这个JSON:Group通过JavaScript来分组JSON数据并在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" 
}] 

而且我喜欢把所有这一切都在选择的选项和optgroups。其实OPTGROUP应类别

我想是这样的:

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

今天,因为我挣扎了太多我仅仅在此:

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

由于你可以看到没有optgroup :) 有没有办法做到这一点? 我也可以修改我的JSON,如果它可以更容易。

感谢您的任何帮助。

回答

16

假设optgroups已经存在,改变了...

.appendTo("optgroup") 

这个...

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

http://jsfiddle.net/FG9Lg/


如果它们不存在,你需要创建它们,尽管我会建议重构您的JSON响应以将每个项目嵌套在适当的类别。

就像这个...

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

所以,你可以那么做:

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

史诗的用户名是我不得不说。 – donutdan4114 2011-12-20 16:47:20

+0

@ donutdan4114谢谢。这是要么“看着我!看着我!”。 – 2011-12-20 16:48:59

+1

非常感谢!我修改了我的JSON并像你说的那样完成了!它完美的工作! – user1108276 2011-12-21 10:34:00

16

如果我是你,我会用一个小型图书馆称为Underscore将以更简单的表示形式返回的数据分组。

请参见下面的代码,你也可以看到这个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]); 
} 

如果你毫不犹豫地使用下划线库,你可以考虑这个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; 
} 

用法:

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

如果你想保持你的JSON格式,以下会回答你的问题:

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

希望这有助于!

2

我知道这个线程很旧,但我需要类似的东西,我想出了这个。它会在需要时自动添加optgroup并使用选项填充它们。另外,它既适用于有选择群组的情况,也适用于不适用的情况。

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