web-dev-qa-db-ja.com

jQueryとcss:特定のcssクラスの選択オプションを非表示/表示

HTMLコードでは、次のような選択オプションがあります。

  <option value="1" class="myclass5">Value1</option>

JQueryの場合:

var cod = $(this).val(); // This is the value of another select: when the value 
$("option[class^=myclass]").hide();
$("option[class^=myclass]").each(function () {
    $("option[class^=myclass" + cod + "]").show();
});

[〜#〜]編集[〜#〜]

2つ選択します。最初の選択で値を選択すると、それに応じて2番目の値を入力する必要があります(ajax呼び出しを防ぐ必要があります)。

私は2番目の選択値をすべてセッション変数に入れましたが、私の問題は最初の選択に関連付けられた値のみを選択することなので、cssクラスを試してみました。

EDIT2

<select name="firstselect">
   <option value="0" selected="selected">Choose...</option>
   <option value="1">Value1</option>
   <option value="2">Value2</option>
   <option value="3">Value3</option>
</select>

<select name="secondselect">
   <option value="0" selected="selected">Choose...</option>
   <option value="myclass1">Value11</option>
   <option value="myclass1">Value12</option>
   <option value="myclass1">Value13</option>
   <option value="myclass2">Value21</option>
   <option value="myclass2">Value22</option>
   <option value="myclass2">Value23</option>
   <option value="myclass3">Value31</option>
   <option value="myclass3">Value32</option>
   <option value="myclass3">Value33</option>
</select>

EDIT3

私にとっては緑がかった解決策は良いですが、IEには説明できない問題があります。戻るボタンを使用すると、ユーザーが選択した値が「失われます」、つまり、ユーザーが選択した値をコンソールにログオンすると、新しくクローンされた選択にその「インデックス」が表示されます。htmlソースコードには、元の選択全体が含まれています。

EDIT4

この投稿のおかげで解決しました

https://forum.jquery.com/topic/jquery-select-box-selectedindex-problems-in-internet-Explorer-ie-on-refresh-and-back-buttons

18
Sefran2

したがって、質問を正しく理解したら、2番目の選択フィールドのオプションを、最初の選択フィールドで選択された値に依存させる必要があります。

私はこれをすばやく試しましたが、cssでオプションを非表示にしてもブラウザー間で機能しないようです。Macのchromeの最新バージョンでもオプションは非表示になりません。

それで私は次のことを思いつきました:

最初にHTML:クラスを使用して依存関係をマークしました。これにより、2番目の選択フィールドのvalue属性を制限なしで使用できます。

また、conditionalとマークされたオプションのみが変更され、他のオプションは影響を受けません。これは、このシナリオのデフォルト値などに役立ちます。

<select id="firstSelect">
   <option value="0" selected="selected">Choose...</option>
   <option value="value1">Value1</option>
   <option value="value2">Value2</option>
   <option value="value3">Value3</option>
</select>

<select id="secondSelect">
   <option value="0" selected="selected">Choose...</option>
   <option class="conditional value1" value="subValue1">Value1: Sub1</option>
   <option class="conditional value2" value="subValue2">Value2: Sub1</option>
   <option class="conditional value2" value="subValue3">Value2: Sub2</option>
   <option class="conditional value2" value="subValue4">Value2: Sub3</option>
   <option class="conditional value2" value="subValue5">Value2: Sub4</option>
   <option class="conditional value2" value="subValue6">Value2: Sub5</option>
   <option class="conditional value3" value="subValue7">Value3: Sub1</option>
   <option class="conditional value3" value="subValue8">Value3: Sub2</option>
   <option class="conditional value3" value="subValue9">Value3: Sub3</option>
</select>

そして、Javascript:これを機能させるために、secondSelectフィールドのオプションをコピーして変数に保存しました。これにより、コピーからオプションを取得しながら、実際に選択フィールドからremoveオプションを取得できます。

$(function(){
    var conditionalSelect = $("#secondSelect"),
        // Save possible options
        options = conditionalSelect.children(".conditional").clone();

    $("#firstSelect").change(function(){
        var value = $(this).val();
        // Remove all "conditional" options               
        conditionalSelect.children(".conditional").remove();
        // Attach options that needs to be displayed for the selected value.
        options.clone().filter("."+value).appendTo(conditionalSelect);
    }).trigger("change");
});

そして、これが実際のスクリプトを示すフィドルです: http://jsfiddle.net/Kn8Gc/

注:データベースからデータを取得し、ユーザーが既に#firstSelectを選択している場合は、selected="selected"属性を使用してください。 #secondSelectは自動的に正しい値を表示します。上記のフィドルを試してみて、たとえばvalue1を0ではなく「事前選択」してください!


また、2つの選択フィールドを相互に依存させるために簡単に使用できる「ジェネリック」関数もここにあります(クラスconditional + source valueを使用してリレーションを作成する):

// "Generic" function
$.conditionalize = function(sourceSelect, conditionalSelect){
    var options = conditionalSelect.children(".conditional").clone();

    sourceSelect.change(function(){
        var value = $(this).val();                  
        conditionalSelect.children(".conditional").remove();
        options.clone().filter("."+value).appendTo(conditionalSelect);
    }).trigger("change");
}

// Used like this:
$.conditionalize($("#firstSelect"), $("#secondSelect"));

そしてここでそれは動作しています: http://jsfiddle.net/NUxQ9/

26
greenish

私はあなたの質問を完全に理解しているとは思いませんが、次のようなものはどうですか:

$(document).ready(function(){
    var cod = '';
    $('select[name="firstselect"]').change(function(){
        cod = $(this).val();
        if ( cod > 0 ) {
            $('select[name="secondselect"] option').hide().filter(function(){
               return ( $(this).val().substr(7,1) == cod || $(this).val() == 0 ); 
            }).show();
        }
    });
});

http://jsfiddle.net/wVCcH/1/

あるいは、動的書き込みオプションも存在します:

var dataset = [ 
    { set: 1, data: [
        { val: "value11", label: "Value 1 - 1" },
        { val: "value12", label: "Value 1 - 2" },
        { val: "value13", label: "Value 1 - 3" } ]
    },
    { set: 2, data: [
        { val: "value21", label: "Value 2 - 1" },
        { val: "value22", label: "Value 2 - 2" },
        { val: "value23", label: "Value 2 - 3" } ]
    }];

var chooser = "<option value='0' selected='selected'>Choose...</option>";

$('select[name="firstselect"]').change(function(){
    var n = $(this).val();                            //get value of data set
    if ( n != 0 ) {
       var str = chooser; n--;                        //0-based n
       for (i=0; i<dataset[n].data.length; i++) {     //write options
          str += "<option value='" + dataset[n].data[i].val + "'>" + dataset[n].data[i].label + "</option>"
        }
        $('select[name="secondselect"]').html(str).attr("disabled",false);
    }
});

http://jsfiddle.net/UNy9Z/4/

3
greener

選択のマッピングを持つJavaScriptオブジェクトを含める

この種の質問はSPA開発で頻繁に出てきます。私はこのアプローチを開発しました。私がお勧めするのは、さまざまなオプションリスト、および兄弟を引き起こす選択フィールドの名前で構成されるオブジェクトキーでJavaScriptオブジェクトを作成することです。依存選択の「select」イベントにバインドすることにより、選択フィールドを動的に作成した後要素、およびカスタムスクリプトを実行して選択したオプションを評価し、マップを解析してから、それに応じてオプションをレンダリングします。

私はこの概念を取り入れて、かなり気の利いたシェルを作成しました。これにより、2つのselect要素の間でこれを行うことができるだけでなく、基本的に、必要な数の依存するselect要素を持つことができます。依存要素で行われた選択に基づいてそれらを設定します。さらにクールな利点は次のとおりです。

  • hTMLマークアップは非常にクリーンです
  • 動的に作成された依存先オプションの依存関係も初期化できます
  • javaScriptコードは非常にクリーンで正確です
  • これは簡単にモジュール化できるため、数行のコードでプラグインまたはモジュールに変換できます
  • $.extend()および提供されたSelectOptionオブジェクトを使用して、非同期で新しいオプションを簡単に作成し、依存関係を非同期に変更する
  • コードは、カスタム関数を呼び出すことにより、さまざまなオプションリストをmapオブジェクトに挿入できるように構築されています
  • selectイベントをトリガーできるANY ELEMENTで機能します。非フォーム要素を使用し、ドロップダウンタイプの機能を挿入しても、他の要素に影響を与えることができます(** Bootstrapで動作します!

コンセプトを示すためにGistを作成しました。ここに最初のシェルがリストされていますが、リンクをチェックして、このGistの最新バージョンと情報があることを確認してください。 (私はそれをプラグインに変えるかもしれません)

https://Gist.github.com/LongLiveCHIEF/7880119.js

form.html

<head>
  <script src="jquery.js"></script><!-- use .js for easier DOM manipulation, can be done without, using the native DOM api -->
  <script src="selection-map.js"></script>
</head>

    <body>
     <!-- select name="" values will be used inside the map object to initialize watch -->
     <!-- the custom data-selmap-cascade="" property initializes the dynamic functionality, and the value should be an
     -- string array format, where the values are the names of the select field whose options will depend on this
     -- elements selected option
     -->
     <select data-selmap-cascade="['secondselect','fourthselect']" name="firstselect">
        <option data-selmap-set-cascade="['second-select : set2', 'fourth-select : set1']" value="0" selected="selected">Choose...</option>
      <!-- list other options here, using the data-selmap-showselectfields settings for each dependent select field -->
      </select>
      <select class="selmap" name="secondselect">
        <!-- will be created via selection-map.js -->
       </select>
</body>

selection-map.js

// first we map our dependencies
var map = {
  secondselect: [ //high level keys are the fields that will cause cascades
      'set1' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]} // this is an option list, with gets a name as a key
      'set2' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]},
      'set3' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]},  
    ],

  fourthselect: [
      'set1' : {[new SelectOption('','','')],[new SelectOption('','','')],[new SelectOption('','','')]}
    ]

  };

// now we make it easy to inject select options at any point  
var SelectOption = function(text, value, dependenSelectFields){
  return {}; //retun object with properties corresponding to the attributes and values of a specific option
}

//and now we kick off processing

var $primaryElements = $.data('selmap-cascade'); // create a collection consisting of any and all elements with selmap-cascade data option

//here we act when any designated dependent field has a selection change
$primaryelements.select(function(){
  var mapkey = $(this + ':selected').data('selmap-set-cascade'); // get the data that will allow us to grab the proper select options for the dependent elements

  //and now we render the correct option into the correct place in the DOM

});
2

これをブラウザー間で機能させる唯一の方法は、オプションを切り離してから再接続することでした。各オプションにクラスを追加し、グループ化とは別にオプションの値も分割しました。これら二つは関連しているかもしれませんが、私はそれを仮定しません。

_<select name="firstselect" id="firstselect">
   <option value="0" selected="selected">Choose...</option>
   <option value="1">Value1</option>
   <option value="2" selected>Value2</option>
   <option value="3">Value3</option>
</select>

<select name="secondselect" id="secondselect">
   <option value="0">Choose...</option>
   <option value="myclass1" class="group1">Value11</option>
   <option value="myclass1" class="group1">Value12</option>
   <option value="myclass1" class="group1">Value13</option>
   <option value="myclass2" class="group2">Value21</option>
   <option value="myclass2" class="group2">Value22</option>
   <option value="myclass2" class="group2">Value23</option>
   <option value="myclass3" class="group3">Value31</option>
   <option value="myclass3" class="group3">Value32</option>
   <option value="myclass3" class="group3">Value33</option>
</select>
_

そしてJavascript ...

_var groups = false;

function update_selected() {
  // reset the secondselect
  $("#secondselect").val(0);
  $("#secondselect").find("option[value!=0]").detach();

  // re-attach the correct options
  $("#secondselect").append(groups.filter(".group" + $(this).val()));
}

$(function() {
  // initialize by detaching all the options (except for the "Choose..." option)
  groups = $("#secondselect").find("option[value!=0]");
  groups.detach();

  // add the onchange event handler
  $("#firstselect").change(update_selected);

  // immediately call update_selected to update on page load
  $("#firstselect").trigger("change");
});
_

フィドル: http://jsfiddle.net/JbVWV/8/

編集-ページの読み込み時に$("#firstselected").trigger("change")への呼び出しを追加しました。したがって、最初のドロップダウンですでに何かが選択されている場合、2番目のドロップダウンはすでに正しく入力されています。

2
Andy Jones

オプションの非表示は、すべてのブラウザーで定義されているわけではありません。 W3C仕様では定義されていません。

http://www.w3.org/TR/html401/interact/forms.html#h-17.6

最初の選択値に基づいてオプションを無効にする

ユーザーがオプションを選択できない2番目のオプションを無効にすることができます。

デモ:http://jsfiddle.net/HrpF2/

コード:

$(function () {
    var $secondOptions = $('select[name=secondselect] option');
    $("select[name=firstselect]").change(function () {
        var value = $(this).val();

        $secondOptions.prop('disabled', true).filter(function () {
            return this.value == 'myclass' + value;
        }).prop('disabled', false);
    }).trigger("change");
});

最初の選択値に基づいてオプションを表示/非表示

本当にオプションを表示/非表示にする場合は、2番目のオプションを複製し、最初の選択値に基づいてそれらを追加し直す必要があります。下記参照、

デモ:http://jsfiddle.net/HrpF2/1/

コード:

$(function () {
    var $secondOptions = $('select[name=secondselect]');
    var $cloneOptions = $secondOptions.find('option').clone();
    $("select[name=firstselect]").change(function () {
        var value = $(this).val();

        $secondOptions.empty().append($cloneOptions.filter(function () {
            return this.value == 'myclass' + value;
        }));
    }).trigger("change");
});
2