2014-11-17 16 views
7

Tôi đã sử dụng select2 để chọn nhiều tùy chọn từ trình đơn thả xuống, nhưng có thể chọn select2 để chọn toàn bộ nhóm không? Những gì tôi muốn là khi người dùng chọn nhóm tùy chọn tất cả các tùy chọn con nên được chọn. Và tôi muốn làm điều này bằng cách sử dụng jQuery Select2. Làm thế nào tôi có thể làm điều này?Chọn tham số bằng cách sử dụng select2

+0

Tôi đã cố định vấn đề này và để tham khảo sau này cho người khác tôi đã thêm đầy đủ các mã + select tất cả các tùy chọn http: // vinurip .blogspot.com/2014/11/select2-selectable-group-and-select-all.html –

Trả lời

18

Điều này có thể xảy ra nếu bạn quay trở lại Select2 với phần tử đầu vào bị ẩn - thay vì phần tử chọn.

Để làm cho tùy chọn nhóm có thể chọn, bạn phải đặt "id", nhưng có vẻ như nó có thể là một chuỗi rỗng. Sau đó, bạn có thể sử dụng sự kiện "select2-select" để ngăn tùy chọn nhóm được chọn và thay vào đó có các tùy chọn con của nó được chọn.

Ngoài ra, có thể cung cấp chức năng query để ngăn tùy chọn nhóm xuất hiện trong danh sách sau khi tất cả các tùy chọn con của nó đã được chọn.

Nếu bạn có các tùy chọn định nghĩa như thế này:

var FRUIT_GROUPS = [ 
    { 
     id: '', 
     text: 'Citrus', 
     children: [ 
      { id: 'c1', text: 'Grapefruit' }, 
      { id: 'c2', text: 'Orange' }, 
      { id: 'c3', text: 'Lemon' }, 
      { id: 'c4', text: 'Lime' } 
     ] 
    }, 
    { 
     id: '', 
     text: 'Other', 
     children: [ 
      { id: 'o1', text: 'Apple' }, 
      { id: 'o2', text: 'Mango' }, 
      { id: 'o3', text: 'Banana' } 
     ] 
    } 
]; 

Bạn có thể cụ Select2 của bạn như thế này:

$('#fruitSelect').select2({ 
    multiple: true, 
    placeholder: "Select fruits...", 
    data: FRUIT_GROUPS, 
    query: function(options) { 
     var selectedIds = options.element.select2('val'); 
     var selectableGroups = $.map(this.data, function(group) { 
      var areChildrenAllSelected = true; 
      $.each(group.children, function(i, child) { 
       if (selectedIds.indexOf(child.id) < 0) { 
        areChildrenAllSelected = false; 
        return false; // Short-circuit $.each() 
       } 
      }); 
      return !areChildrenAllSelected ? group : null; 
     }); 
     options.callback({ results: selectableGroups }); 
    } 
}).on('select2-selecting', function(e) { 
    var $select = $(this); 
    if (e.val == '') { // Assume only groups have an empty id 
     e.preventDefault(); 
     $select.select2('data', $select.select2('data').concat(e.choice.children)); 
     $select.select2('close'); 
    } 
}); 

jsfiddle

Đây là một jsfiddle mà không query chức năng, nơi tùy chọn nhóm vẫn xuất hiện khi tất cả các tùy chọn con của họ được chọn.

+0

hi, cảm ơn câu trả lời nhưng những gì liều lượng dòng này làm gì? $ select.select2 ('val', $ select.select2 ('val'). concat (childIds)); những gì tôi có là một danh sách tùy chọn html với optgroups tôi muốn nó để kết hợp tôi nhưng không thể có được dòng này –

+0

là nó có thể khi tất cả các tùy chọn được lựa chọn theo tên nhóm chọn nó nói "tất cả các tùy chọn được chọn" ??? –

+0

@ user1269524 - Dòng '$ select.select2 ('val', $ select.select2 ('val'). Concat (childIds));' đặt các tùy chọn đã chọn. Nó thêm tất cả các tùy chọn con của tùy chọn cha mẹ đã chọn cho tất cả các tùy chọn đã chọn trước đó, và sau đó cung cấp danh sách đó cho điều khiển Select2. –

2

Tôi đã sử dụng mã của John, nhưng vấn đề của tôi là tôi cần khả năng lọc, vì vậy tôi đã thêm nó. Bạn có thể xem mã hoạt động trên jsfiddle.

Đây là mã truy vấn:

  query: function (options) { 
      var selectedIds = options.element.select2('val'); 
      var data = jQuery.extend(true, {}, FRUIT_GROUPS); 
      var selectableGroups = $.map(data, function (group) { 
       var areAllChildrenSelected = true, 
        parentMatchTerm = false, 
        anyChildMatchTerm = false; 
       if (group.text.toLowerCase().indexOf(options.term.toLowerCase()) >= 0) { 
        parentMatchTerm = true; 
       } 
       var i = group.children.length 
       while (i--) { 
        var child = group.children[i]; 

        if (selectedIds.indexOf(child.id) < 0) { 
         areAllChildrenSelected = false; 
        }; 

        if (options.term == '' || (child.text.toLowerCase().indexOf(options.term.toLowerCase()) >= 0)) { 
         anyChildMatchTerm = true; 
        } 
        else if (!parentMatchTerm) { 
         var index = group.children.indexOf(child); 
         if (index > -1) { 
          group.children.splice(index, 1); 
         }; 
        }; 
       }; 

       return (!areAllChildrenSelected && (parentMatchTerm || anyChildMatchTerm)) ? group : null; 
      }); 

      options.callback({ results: selectableGroups }); 
     } 
0

Trong Select2 v4, tôi phát hiện ra rằng câu trả lời John S sẽ không hoạt động (see here). Tôi đang tải dữ liệu của tôi như là một mảng sử dụng AJAX và tạo ra một cách giải quyết:

$(document).on("click", ".select2-results__group", function(){ 
    var input = $(this); 
    var location = input.html(); 
    // Find the items with this location 
    var options = $('#select2 option'); 
    $.each(options, function(key, value){ 
     var name = $(value).html(); 
     // The option contains the location, so mark it as selected 
     if(name.indexOf(location) >= 0){ 
      $(value).prop("selected","selected"); 
     } 
    }); 
    $("#select2").trigger("change"); 
}); 

Tôi nhóm mặt hàng tôi theo địa điểm, và mỗi tùy chọn chứa tên vị trí ở đâu đó trong nó là html. Bất cứ lúc nào một tiêu đề optgroup được nhấp vào, tôi nhận được vị trí của nó (tên được hiển thị trong danh sách thả xuống). Sau đó, tôi xem xét tất cả các tùy chọn trong bảng # select2 và tìm những tùy chọn nào chứa vị trí đó trong html của nó.

Tôi biết đây là một cách giải quyết hacky, nhưng hy vọng nó giúp/điểm đi đúng hướng.

0

John S, ví dụ được cung cấp hoạt động thực sự tốt (đối với V3) cho hầu hết các trường hợp. Tuy nhiên, nó có một lỗi:

Giả sử danh sách lựa chọn đủ dài để cuộn. Khi bạn chọn bất kỳ mục nào trong bất kỳ nhóm nào chỉ khả dụng sau khi bạn cuộn xuống - bạn không thể chọn mục tiếp theo sau mục bạn đã chọn từ nhóm này nữa. Đó là bởi vì EnsureHighlightChế độ có thể chọn của select2 bắt đầu hoạt động sai vì các bộ chọn mà nó đang sử dụng được thực hiện bằng cách sử dụng các giả định rằng nhóm luôn luôn là 'không thể chọn'. Vì vậy, cuộn sẽ nhảy mỗi khi bạn cố gắng chọn mục.

Vì vậy, thật không may, mặc dù giải pháp này trông thật sự tốt - Anh đã đánh rơi nó và tái thực hiện nó mà không sử dụng id nhóm:

$selectEl..on("select2-open", function(event) { 
      $(event.target).data("select2").dropdown.on("click", "li.select2-result-unselectable", selectGroup); 
      $(event.target).data("select2").dropdown.on("mousemove-filtered", "li.select2-result-unselectable", highlight); 
     }).on("select2-close", function(event) { 
      $(event.target).data("select2").dropdown.off("click", "li.select2-result-unselectable", selectGroup); 
      $(event.target).data("select2").dropdown.off("mousemove-filtered", "li.select2-result-unselectable", highlight); 
     }); 

// selection of the group. 
    function selectGroup(e) { 
    var $li = $(this); 
    e.preventDefault(); 
    $select.select2('data', $select.select2('data').concat($li.data("select2Data").children)); 
    $select.select2('close'); 
    _this.$field.trigger('change'); 
    } 

    // highlight of the group. 
    function highlight(e) { 
    if ($(e.target).hasClass("select2-result-unselectable") || $(e.target.parentNode).hasClass('select2-result-unselectable')) { 
     e.preventDefault(); 
     e.stopPropagation(); 
     $select.data("select2").dropdown.find(".select2-highlighted").removeClass("select2-highlighted"); 
     $(this).addClass("select2-highlighted"); 
    } 
    } 
1

đầu tiên cung cấp cho id để chọn của bạn ví dụ

<select style="width: 95%" id="selectgroup">

và sau đó thêm lớp để optgroup của bạn như

<optgroup value="ATZ" label="Alaskan/Hawaiian Time Zone" class="select2-result-selectable"> 

và sau đó thêm này

$('#selectgroup').select2({ 

    }).on('select2-selecting', function (e) { 
     debugger; 
     var $select = $(this); 
     if (e.val == undefined) { 
      e.preventDefault(); 
      var childIds = $.map(e.choice.children, function (child) { 
       return child.id; 
      }); 
      $select.select2('val', $select.select2('val').concat(childIds)); 
      $select.select2('close'); 
     } 
    }); 

Nếu bạn bấm vào optgroup Sau đó nó sẽ chọn tất cả các tùy chọn dưới optgroup.

0

Vâng, tôi đã gặp vấn đề này và tôi thấy rằng mỗi khi select2 (Select2 4.0.5) mở nó sẽ thêm phần tử span trước phần tử body đóng. Ngoài ra, bên trong phần tử span thêm một ul với id: select2-X-results, trong đó X là id select2. Vì vậy, tôi tìm thấy cách giải quyết sau (jsfiddle):

var countries = [{ 
 
    "id": 1, 
 
    "text": "Greece", 
 
    "children": [{ 
 
    "id": "Athens", 
 
    "text": "Athens" 
 
    }, { 
 
    "id": "Thessalonica", 
 
    "text": "Thessalonica" 
 
    }] 
 
}, { 
 
    "id": 2, 
 
    "text": "Italy", 
 
    "children": [{ 
 
    "id": "Milan", 
 
    "text": "Milan" 
 
    }, { 
 
    "id": "Rome", 
 
    "text": "Rome" 
 
    }] 
 
}]; 
 

 
$('#selectcountry').select2({ 
 
    placeholder: "Please select cities", 
 
    allowClear: true, 
 
    width: '100%', 
 
    data: countries 
 
}); 
 

 
$('#selectcountry').on('select2:open', function(e) { 
 

 
    $('#select2-selectcountry-results').on('click', function(event) { 
 

 
    event.stopPropagation(); 
 
    var data = $(event.target).html(); 
 
    var selectedOptionGroup = data.toString().trim(); 
 

 
    var groupchildren = []; 
 

 
    for (var i = 0; i < countries.length; i++) { 
 

 

 
     if (selectedOptionGroup.toString() === countries[i].text.toString()) { 
 

 
     for (var j = 0; j < countries[i].children.length; j++) { 
 

 
      groupchildren.push(countries[i].children[j].id); 
 

 
     } 
 

 
     } 
 

 

 
    } 
 

 

 
    var options = []; 
 

 
    options = $('#selectcountry').val(); 
 

 
    if (options === null || options === '') { 
 

 
     options = []; 
 

 
    } 
 

 
    for (var i = 0; i < groupchildren.length; i++) { 
 

 
     var count = 0; 
 

 
     for (var j = 0; j < options.length; j++) { 
 

 
     if (options[j].toString() === groupchildren[i].toString()) { 
 

 
      count++; 
 
      break; 
 

 
     } 
 

 
     } 
 

 
     if (count === 0) { 
 
     options.push(groupchildren[i].toString()); 
 
     } 
 
    } 
 

 
    $('#selectcountry').val(options); 
 
    $('#selectcountry').trigger('change'); // Notify any JS components that the value changed 
 
    $('#selectcountry').select2('close');  
 

 
    }); 
 
});
li.select2-results__option strong.select2-results__group:hover { 
 
    background-color: #ddd; 
 
    cursor: pointer; 
 
}
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/> 
 
<link href="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/css/select2.min.css" rel="stylesheet"/> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script> 
 
<script src="https://cdnjs.cloudflare.com/ajax/libs/select2/4.0.5/js/select2.full.min.js"></script> 
 

 

 
<h1>Selectable optgroup using select2</h1> 
 
<select id="selectcountry" name="country[]" class="form-control" multiple style="width: 100%"></select>

Các vấn đề liên quan