2012-10-24 42 views
11

Tôi có một phần tử select với nhóm option s. Tôi cần phải chọn (hoặc bỏ chọn) tất cả option s trong một số optgroup khi nhấp chuột option. Tôi cũng cần có thể có nhiều lần chọn optgroup giây.Chọn tất cả các tùy chọn trong optgroup

Con đường tôi muốn nó làm việc là thế này:

  • Nếu không có gì được chọn, tôi muốn nhấn một lựa chọn và nhận được tất cả các tùy chọn trong optgroup cùng chọn.
  • Nếu một hoặc nhiều nhóm chọn đã được chọn, tôi muốn nhấp vào một tùy chọn trong một nhóm chọn khác và thay vào đó hãy chọn tất cả các tùy chọn đó.
  • Nếu một hoặc nhiều nhóm chọn đã được chọn, tôi muốn có thể nhấn Ctrl vào một tùy chọn trong nhóm chọn không được chọn và có tất cả các tùy chọn trong nhóm chọn đó cũng được chọn.
  • Nếu một hoặc nhiều nhóm chọn đã được chọn, tôi muốn có thể bấm Ctrl vào một tùy chọn trong nhóm chọn lọc đã chọn và có tất cả các tùy chọn trong nhóm đó đã bỏ chọn.

Nhìn vào câu trả lời khác trên Stack Overflow tôi đã tạo điều sau đây:

HTML:

<select multiple="multiple" size="10"> 
    <optgroup label="Queen"> 
     <option value="Mercury">Freddie</option> 
     <option value="May">Brian</option> 
     <option value="Taylor">Roger</option> 
     <option value="Deacon">John</option> 
    </optgroup> 
    <optgroup label="Pink Floyd"> 
     <option value="Waters">Roger</option> 
     <option value="Gilmour">David</option>  
     <option value="Mason">Nick</option>     
     <option value="Wright">Richard</option> 
    </optgroup> 
</select> 

jQuery:

$('select').click(selectSiblings); 
function selectSiblings(ev) { 
    var clickedOption = $(ev.target); 
    var siblings = clickedOption.siblings(); 
    if (clickedOption.is(":selected")) { 
     siblings.attr("selected", "selected"); 
    } else { 
     siblings.removeAttr("selected"); 
    } 
}​ 

tôi đã thực hiện một ví dụ ở đây: http://jsfiddle.net/mflodin/Ndkct/ (Đáng buồn jsFiddle dường như không hỗ trợ IE8 nữa.)

Điều này hoạt động như mong đợi trong Firefox (16.0), nhưng trong IE8 nó không hoạt động chút nào. Từ các câu trả lời khác, tôi đã phát hiện ra rằng IE8 không thể xử lý sự kiện click trên optgroup hoặc option, đó là lý do tôi liên kết nó với select và sau đó sử dụng $(ev.target). Nhưng trong IE8, $(ev.target) vẫn trỏ đến toàn bộ số select và không cho số option được nhấp. Làm thế nào tôi có thể tìm ra số option (hoặc có chứa optgroup) đã được nhấp và liệu nó đã được chọn hay không được chọn?

Một hành vi không mong muốn khác, nhưng nhỏ hơn khi so sánh, đó là trong Chrome (20.0) việc bỏ chọn không xảy ra cho đến khi chuột rời khỏi select. Có ai biết một giải pháp cho việc này?

Trả lời

-1

Theo sự cố của bạn, hãy chọn/bỏ chọn tất cả tùy chọn. bạn có thể thử mã sau, có thể giúp bạn.

mã:

mã javascript:

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js"> 

 $(function(){ 

       $('#allcheck').click(function(){ 
       var chk=$('#select_option >optgroup > option'); 
       chk.each(function(){ 
        $(this).attr('selected','selected'); 
      }); 
    }); 
$('#alluncheck').click(function(){ 

       var chk=$('#select_option >optgroup > option'); 
       chk.each(function(){ 
       $(this).removeAttr('selected'); 
      }); 
    });}); 

HTML code:

 <select multiple="multiple" size="10" id="select_option" name="option_value[]"> 
      <optgroup label="Queen"> 
      <option value="Mercury">Freddie</option> 
      <option value="May">Brian</option> 
      <option value="Taylor">Roger</option> 
      <option value="Deacon">John</option> 
     </optgroup> 
     <optgroup label="Pink Floyd"> 
      <option value="Waters">Roger</option> 
      <option value="Gilmour">David</option>  
      <option value="Mason">Nick</option>     
      <option value="Wright">Richard</option> 
     </optgroup> 
</select> 
<br> 
     <strong>Select&nbsp;&nbsp;<a style="cursor:pointer;" id="allcheck">All</a> 
    &nbsp;|&nbsp;<a style="cursor:pointer;" id="alluncheck">None</a></strong> 
+0

này không có gì để làm với những gì tôi muốn. Tôi muốn nhấp vào một 'tùy chọn' không phải là một liên kết để chọn tất cả' tùy chọn' – mflodin

-1

Hy vọng điều này sẽ làm việc

$("#SelectID").live("click",function() { 
var elements = this.options; //or document.getElementById("SelectID").options; 
for(var i = 0; i < elements.length; i++){ 
    if(!elements[i].selected) 
    elements[i].selected = true; 
} 
} 
+0

Đây không phải là những gì tôi muốn. Điều này chọn tất cả các phần tử 'option' trong tất cả' optgroup's. Nó chỉ nên chọn những người đang trong cùng một 'optgroup' như là nhấp vào' tùy chọn'. – mflodin

+0

Bạn cũng đang thiếu dấu ngoặc đơn cuối cho hàm trực tiếp. – mflodin

0

này có khắc phục được vấn đề, bạn chỉ cần thêm đoạn mã này sau khi init chọn.

$('.chzn-results .group-result').each(function() { 
    var self  = $(this) 
     , options = $('~li', self) 
     , next = options.filter('.group-result').get(0) 
    ; 
    self.data('chzn-options', options.slice(0, options.index(next))); 
}) 
.click(function() { 
    $(this).data('chzn-options').mouseup() 
}) 
.hover(function() { 
    $(this).data('chzn-options').addClass('highlighted'); 
}, function() { 
    $(this).data('chzn-options').removeClass('highlighted'); 
}) 
.css({ cursor: 'pointer' }) 

Nhờ adriengibrat đã đăng sửa chữa này trên github:
https://github.com/harvesthq/chosen/issues/323

+0

Nhưng tôi không sử dụng lựa chọn ... – mflodin

1

Kể từ khi Internet Explorer như các phiên bản 10 vẫn không hỗ trợ bất kỳ sự kiện hữu ích về optgroup hay option, bất kỳ qua trình duyệt giải pháp cho vấn đề này không thể phụ thuộc vào sự kiện trực tiếp từ những yếu tố đó.

Lưu ý: tài liệu MSDN tuyên bố rằng optgroup hỗ trợ click sự kiện, nhưng như của IE 10 mà vẫn dường như không thể trở thành hiện thực: http://msdn.microsoft.com/en-us/library/ie/ms535876(v=vs.85).aspx

Tôi đã thử nghiệm sau đây trong Chrome 27, Firefox 20, Safari 6 , IE 9 và IE 10 (hiện tại tôi không có quyền truy cập vào IE 8).

Dưới đây là một ví dụ bạn có thể chơi với: http://jsfiddle.net/potatosalad/Ndkct/38/

// Detect toggle key (toggle selection) 
$('select') 
    .on('mousedown', function(event) { 
     // toggleKey = Command for Mac OS X; Control for others 
     var toggleKey = (!event.metaKey && event.ctrlKey && !(/Mac OS/.test(navigator.userAgent))) ? event.ctrlKey : event.metaKey; 
     if (toggleKey === true) { 
      $(this).data('toggleKey', true); 
     } 
     $(this).data('_mousedown', true); 
    }) 
    .on('mouseup', function() { 
     $(this).data('_mousedown', null); 
    }); 
// Chrome fix for mouseup outside select 
$(document).on('mouseup', ':not(select)', function() { 
    var $select = $('select'); 
    if ($select.data('_mousedown') === true) { 
     $select.data('_mousedown', null); 
     $select.trigger('change'); 
    } 
}); 

$('select') 
    .on('focus', storeState) 
    .on('change', changeState); 

function storeState() { 
    $(this).data('previousGroup', $('option:selected', this).closest('optgroup')); 
    $(this).data('previousVal', $(this).val()); 
}; 

function changeState() { 
    var select = this, 
     args = Array.prototype.slice.call(arguments); 

    var previousGroup = $(select).data('previousGroup'), 
     previousVal = $(select).data('previousVal'); 
    var currentGroup = null, 
     currentVal = $(select).val(); 

    var selected = $('option:selected', select), 
     groups = selected.closest('optgroup'); 

    console.log("[change] %o -> %o", previousVal, currentVal); 

    if ((previousVal === currentVal) && (groups && groups.length == 1)) { 
     // selected options have not changed 
     // AND 
     // only 1 optgroup is selected 
     // -> do nothing 
    } else if (currentVal === null || currentVal.length === 0) { 
     // zero options selected 
     // -> store state and do nothing 
     storeState.apply(select, args); 
    } else { // a select/deselect change has occurred 
     if ($(select).data('toggleKey') === true 
      && (previousVal !== null && previousGroup !== null && groups !== null) 
      && (previousVal.length > currentVal.length) 
      && (previousGroup.length === groups.length) 
      && (previousGroup.get(0) === groups.get(0))) { 
      // options within the same optgroup have been deselected 
      // -> deselect all and store state 
      $(select).val(null); 
      storeState.apply(select, args); 
     } else if (currentVal.length === 1) { 
      // single option selected 
      // -> use groups 
      currentGroup = groups; 
     } else if (groups.length === 1) { 
      // multiple options selected within same optgroup 
      // -> use groups 
      currentGroup = groups; 
     } else { 
      // multiple options selected spanning multiple optgroups 
      // -> use last optgroup 
      currentGroup = groups.last(); 
     } 
    } 

    $(select).data('toggleKey', null); 

    if (currentGroup !== null) { 
     $('optgroup', select).not(currentGroup).children(':selected').attr('selected', false); 
     $(currentGroup).children(':not(:selected)').attr('selected', true); 
     storeState.apply(select, args); 
    } 
}; 

Nó hoạt động bằng cách lưu trữ các nhóm đã chọn trước đó và các tùy chọn trên các yếu tố select và xác định những optgroup nên được lựa chọn (hoặc bỏ chọn).

Một số hành vi có thể được thay đổi dựa trên nhu cầu của nhà phát triển. Ví dụ trong trường hợp chọn nhiều options mà span nhiều optgroups (bằng cách nhấp và kéo xuống như đã thấy trong ảnh chụp màn hình):

multiple options selected spanning multiple optgroups

Nghị quyết xung đột mặc định cho trường hợp này là luôn luôn sử dụng cuối cùng optgroup, nhưng có thể được thay đổi để luôn sử dụng số đầu tiên hoặc optgroup với số lượng tùy chọn đã được chọn nhiều nhất.

+0

Điều này làm việc tuyệt vời để chọn một nhóm duy nhất, nhưng không phải nhiều nhóm. Tôi sẽ cập nhật câu hỏi của mình để làm rõ hơn những gì tôi cần. Nó có thể đơn giản để sửa đổi mã của bạn cho những gì tôi cần, nhưng tiếc là tôi không có thời gian để nhìn vào nó ngay bây giờ. Tuy nhiên, tôi sẽ trao cho bạn một +1 cho công việc cho đến nay và cho thông tin liên quan đến khả năng tương thích của IE. – mflodin

0
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script> 


$(document).ready(function() { 
    $('select').click(function(tar) { 
     var justClickValue = tar.target.value; 

     var selectedGroup = $('option[value="'+justClickValue+'"]').parent(); 

     if (selectedGroup.hasClass("allSelected")) { 
      selectedGroup.removeClass("allSelected"); 
      $("option").each(function() { 
       $(this).removeAttr("selected"); 
      }); 
     } else { 
      $(".allSelected").removeClass("allSelected"); 
      selectedGroup.addClass("allSelected"); 
      $(".allSelected option").each(function() { 
       $(this).attr("selected", "selected"); 
      }); 
     } 
    }); 
}); 
3

không phải là một câu trả lời cho các câu hỏi cụ thể về các vấn đề trình duyệt chéo chọn tùy chọn, tôi nghĩ rằng đó là được trả lời đã có, nhưng một giải pháp cho vấn đề lựa chọn dữ liệu và đi qua nó lại cho máy chủ sẽ được thay đổi của bạn đánh dấu lên đến một cái gì đó phù hợp tốt hơn nhiều lựa chọn

nếu bạn sử dụng hộp kiểm thay vào đó, bạn có thể đặt chúng trong một danh sách và thêm enhanching js để chọn tất cả và bỏ chọn tất cả

http://jsfiddle.net/Ndkct/43/

<dl> 
<dt>Queen</dt> 
<dd> 
    <ul> 
     <li> 
      <input id="Mercury" name="bandmembers" value="Mercury" type="checkbox" /> 
      <label for="Mercury">Freddie</label> 
     </li>  
     <li> 
      <input id="May" name="bandmembers" value="May" type="checkbox" /> 
      <label for="May">Brian</label> 
     </li>  
     <li> 
      <input id="Taylor" name="bandmembers" value="Taylor" type="checkbox" /> 
      <label for="Taylor">Roger</label> 
     </li>  
     <li> 
      <input id="Deacon" name="bandmembers" value="Deacon" type="checkbox" /> 
      <label for="Deacon">John</label> 
     </li>  
    </ul> 
</dd> 
<dt>Pink Floyd</dt> ... 

Các js tại là đủ đơn giản

$("dt") 
    .css("cursor","pointer") 
    .click(function(){ 
     var $el = $(this).next(); 
     var $checks = $el.find(":checkbox"); 
     if($checks.is(":not(:checked)")){ 
      $checks.attr("checked",true); 
     }else{ 
      $checks.attr("checked",false); 
     } 
    }); 

(fiddle này http://jsfiddle.net/Ndkct/44/ thêm một hộp kiểm cha mẹ để làm cho nó có thể sử dụng nhiều hơn)

+0

Giải pháp thay thế tuyệt vời! Nó thậm chí có thể rõ ràng hơn cho người dùng. – mflodin

+0

ta, tôi cũng nghĩ thế. Các hộp danh sách và toàn bộ phím shift/nút điều khiển bên trái đa lựa chọn cũng không thân thiện với người dùng. Bạn có lợi thế về một hệ thống phân cấp để chọn nhiều mục nhanh chóng ở đây và chỉ nhìn vào nó cho bạn biết điều gì đang xảy ra –

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