2012-10-24 18 views
11

私は、グループでselectの要素を持っています。 optionをクリックしたときににあるoptionをすべて選択(または選択解除)する必要があります。同時に複数のoptgroupを選択できるようにする必要があります。optgroup内のすべてのオプションを選択してください

私は仕事にそれを望む方法がこれです:何も選択されていない場合は

  • 、私は1つのオプションをクリックして、選択したのと同じOPTGROUPにオプションのすべてを取得したいです。
  • optgroupsがすでに選択されている場合は、別のoptgroupで1つのオプションをクリックし、それらのオプションをすべて選択します。
  • optgroupsがすでに選択されている場合は、選択されていないoptgroupのオプションをCtrlキーを押しながらクリックして、そのoptgroupのすべてのオプションも選択できるようにします。
  • optgroupsがすでに選択されている場合は、選択したoptgroupのオプションをCtrlを押しながらクリックし、そのグループのすべてのオプションを選択解除したいと考えています。

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

    私はここで例を作った:http://jsfiddle.net/mflodin/Ndkct/ を(悲しいことに、私は次のように作成したスタックオーバーフロー上の他の回答を見てみると

jsFiddleはIE8をこれ以上サポートしていないようです。)

これはFirefox(16.0)では期待通りに動作しますが、IE8ではまったく動作しません。他の回答から、IE8がoptgroupまたはoptionというイベントのclickイベントを処理できないことがわかりました。これがselectにバインドしてから$(ev.target)を使用した理由です。しかし、IE8では、$(ev.target)はまだselect全体を指し、クリックしたのはoptionではありません。クリックされたoption(またはoptgroupが含まれています)が選択されているか、選択解除されているかを確認するにはどうすればよいですか?

Chrome(20.0)では、マウスがselectを離れるまで、選択解除は行われません。誰かがこれに対する回避策を知っていますか?

答えて

-1

問題に応じて、すべてのオプションを選択/選択解除してください。 次のコードを試してみると助けになるかもしれません。

コード:

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コード:

 <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

(このフィドルhttp://jsfiddle.net/Ndkct/44/はそれをより使いやすくするために、親のチェックボックスを追加します)今

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

十分に簡単ですこれは私が望むものとは何の関係もありません。私はすべての 'options'を選択する' option'リンクをクリックしません。 – mflodin

-1

、これはこれで問題が解決

$("#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

これは私が望むものではありません。これは全ての 'optgroup'の全ての' option'要素を選択します。クリックされた 'option'と同じ' optgroup'にあるものだけを選択するべきです。 – mflodin

+0

ライブ関数の最後のカッコもありません。 – mflodin

0

を働くことを願っています、あなただけのinitが選ばれた後にこのコードを追加する必要があります。 githubの上でこの修正プログラムを掲載adriengibratへ

$('.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' }) 

ありがとう:
https://github.com/harvesthq/chosen/issues/323

+0

しかし私は選ばれたものを使用していません... – mflodin

1

バージョン10のようにInternet Explorerは、まだ、へのクロスブラウザのソリューションをoptgroupoption上の任意の有用なイベントをサポートしていませんので、この問題は、これらの要素からの直接的なイベントに依存することはできません。

注: MSDNのドキュメントは、optgroupclickイベントをサポートしていることを主張しますが、IE 10のようまだ現実ではないようですその:http://msdn.microsoft.com/en-us/library/ie/ms535876(v=vs.85).aspx

私はクローム27は、Firefox 20、Safariの6に次のようにテストしました、IE 9、およびIE 10(私は現在IE 8にアクセスできません)。

ここにあなたがと遊ぶことができる例を示します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); 
    } 
}; 

それはselect要素に以前に選択したグループとオプションを格納し、optgroupを選択(または選択解除)する必要があるかを決定することによって動作します。

一部の動作は、開発者のニーズに基づいて変更できます。この場合のデフォルトの競合解決は常に最後optgroupを使用することです

multiple options selected spanning multiple optgroups

、しかし:(スクリーンショットに見られるようにクリックして上下にドラッグすることによって)optgroups複数にまたがる複数のoptionsを選択した場合、たとえば、最初のものを常に使用するように変更するか、すでに選択されているオプションの数が最も多いoptgroupに変更することができます。

+0

これは1つのオプトグループを選択するのに最適ですが、複数のオプトグループは選択できません。私は私の質問を更新して、私が必要とするものを明確にします。私が必要とするコードを変更するのは簡単かもしれませんが、残念ながら私は今それを調べる時間がありません。それでも、私はあなたに今までの仕事とIEの互換性に関する情報を+1します。 – 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

ない選択オプションのクロスブラウザーの問題の特定の質問への答えは、私はそれが既に回答されていると思うが、データを選択し、バックサーバにそれを渡すの問題を解決するには、あなたを変えることであろう何かより良いスーツマルチ選択にマークアップ

あなたの代わりにチェックボックスを使用する場合は、リストに入れ、すべてを選択するには、JSをenhanching追加し、選択を解除することができ、すべての

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

JSが

+0

良い代替ソリューション!それはユーザーにとってはもっと明白かもしれません。 – mflodin

+0

ta、私もそうだと思います。リストボックスとその全体の左シフト/コントロールボタンのマルチセレクト機能はユーザーフレンドリーではありません。あなたはここで多くのアイテムを素早く選択するための階層の利点があります。それを見るだけで何が起きているのかが分かります –

関連する問題