2011-12-20 34 views
11

Tôi bị mất một chút. Tôi nhận JSON này:GroupBy trong JavaScript để nhóm dữ liệu JSON và điền vào 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" 
}] 

Và tôi muốn đặt tất cả những điều này trong một lựa chọn với các tùy chọn và optgroups. Trên thực tế các optgroup nên loại

Tôi muốn một cái gì đó như thế này:

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

Hôm nay tôi đã chỉ làm điều này vì tôi đang gặp khó khăn quá nhiều:

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

Như bạn có thể thấy không có optgroup :) Có cách nào để làm điều này? Tôi cũng có thể sửa đổi JSON của mình nếu nó có thể làm cho nó dễ dàng hơn.

Cảm ơn bạn đã được trợ giúp.

Trả lời

16

Giả sử optgroups đã tồn tại, thay đổi điều này ...

.appendTo("optgroup") 

này ...

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

http://jsfiddle.net/FG9Lg/


Nếu họ không tồn tại, bạn cần phải tạo chúng, mặc dù tôi muốn đề xuất tái cơ cấu phản hồi JSON của bạn để có từng mục được lồng trong danh mục phù hợp.

Như thế này ...

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

Vì vậy, sau đó bạn có thể làm điều này:

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

Tên truy nhập sử thi là tất cả tôi có thể nói. – donutdan4114

+0

@ donutdan4114 Cảm ơn. Đó là hoặc là "LOOK AT ME! LOOK AT ME!". –

+1

Cảm ơn rất nhiều !! Tôi đã sửa đổi JSON của mình và thực hiện như bạn đã nói! Nó hoạt động hoàn hảo! – user1108276

16

Nếu tôi là bạn, tôi sẽ sử dụng một thư viện nhỏ gọi Underscore nhóm các dữ liệu được trả về trong một đại diện dễ dàng hơn.

Xem mã này dưới đây và bạn cũng có thể thấy điều này 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]); 
} 

Nếu bạn ngần ngại sử dụng thư viện gạch dưới, bạn có thể xem xét groupBy chức năng này:

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

SỬ DỤNG:

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

Trong trường hợp bạn muốn giữ nguyên định dạng JSON, câu trả lời sau đây sẽ trả lời câu hỏi của bạn:

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

Hy vọng điều này sẽ hữu ích!

2

Tôi biết chủ đề này là rất cũ, nhưng tôi đã cần một cái gì đó tương tự và tôi đã đưa ra điều này. Nó tự động thêm optgroups khi cần thiết và cư trú chúng với các tùy chọn. Thêm vào đó, nó hoạt động cả khi bạn có optgroups và khi bạn không.

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); 
    }   
}); 
Các vấn đề liên quan