web-dev-qa-db-fra.com

jQuery et css: masquer / afficher les options de sélection avec une certaine classe css

Dans le code html j'ai des options de sélection comme celle-ci:

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

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

[~ # ~] modifier [~ # ~]

J'en ai deux choisis. Lorsque je sélectionne une valeur dans la première sélection, la seconde doit être remplie en conséquence (je dois empêcher un appel ajax).

J'ai mis toutes les deuxièmes valeurs de sélection dans une var de session, mais mon problème est de ne sélectionner que celles liées à la première sélection, donc j'essayais à travers les classes 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

Pour moi, la solution de greenish est bonne, mais il y a un problème sur IE que je n'arrive pas à expliquer: lorsque j'utilise le bouton de retour, la valeur sélectionnée par l'utilisateur est "perdue", c'est-à-dire , si je me connecte à la console, la valeur sélectionnée par l'utilisateur, je vois son "index" dans la nouvelle sélection clonée. Dans le code source html, il y a toute la sélection d'origine.

EDIT4

J'ai résolu grâce à ce post

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

18
Sefran2

Donc, lorsque je comprends bien votre question, vous souhaitez rendre les options du deuxième champ de sélection dépendant de la valeur sélectionnée dans le premier champ de sélection.

J'ai essayé rapidement et masquer une option avec css ne semble pas fonctionner sur plusieurs navigateurs, même la dernière version de chrome sur mac ne masquera pas les options.

J'ai donc trouvé ce qui suit:

HTML d'abord: j'ai utilisé des classes pour marquer les dépendances. Cela permet à l'attribut value dans le deuxième champ de sélection d'être utilisé sans restrictions.

De plus, seules les options marquées comme conditional seront modifiées, les autres ne seront pas affectées. Ceci est utile pour quelque chose comme la valeur par défaut dans ce scénario.

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

Et le Javascript: Pour que cela fonctionne, j'ai copié les options du champ secondSelect et les ai enregistrées dans une variable. Cela me permet en fait remove options du champ de sélection pendant que je suis toujours en mesure de récupérer les options de la copie.

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

Et voici un violon qui montre le script en action: http://jsfiddle.net/Kn8Gc/

Remarque: Si vous obtenez des données dans une base de données et que l'utilisateur a déjà sélectionné #firstSelect, utilisez simplement le selected="selected" attribut. #secondSelect affichera automatiquement les valeurs correctes. Essayez simplement le violon ci-dessus et "présélectionnez" par exemple valeur1 au lieu de 0!


Voici également une fonction "générique" qui peut être utilisée facilement pour rendre dépendants l'un de l'autre deux champs de sélection (en utilisant toujours les classes conditional + source value pour faire la relation):

// "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"));

Et le voici en action: http://jsfiddle.net/NUxQ9/

26
greenish

Je ne suis pas sûr de bien comprendre votre question, mais qu'en est-il de quelque chose comme ceci:

$(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/

Alternativement , l'option d'écriture dynamique existe également:

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

Inclure un objet javascript qui a un mappage de sélections

ce type de question revient souvent dans le développement de SPA, et j'ai développé cette approche. Ce que je recommande, c'est de créer un objet javascript avec les différentes listes d'options et des clés d'objet constituées des noms des champs de sélection, ce qui provoquera la fratrie: après la sélection des champs à créer dynamiquement, en se liant à l'événement 'select' de la sélection dépendante et exécuter un script personnalisé pour évaluer l'option sélectionnée, analyser votre carte, puis afficher les options en conséquence.

J'ai pris ce concept et créé un Shell assez astucieux, qui devrait non seulement vous permettre cela entre les deux éléments de sélection que vous mentionnez, mais vous permettant essentiellement d'avoir autant d'éléments de sélection dépendants que vous le souhaitez ... en fonction de la sélection effectuée dans l'élément dépendant. Voici les avantages encore plus cool:

  • le balisage html est extrêmement propre
  • vous pouvez initialiser les dépendances même sur les options de dépendance créées dynamiquement
  • le code javascript est très propre et précis
  • cela peut facilement être rendu modulaire, il pourrait donc être converti en un plugin ou un module avec seulement quelques lignes de code
  • créer facilement de nouvelles options de manière asynchrone et modifier de manière asynchrone les dépendances à l'aide de $.extend() et de l'objet SelectOption fourni
  • le code est construit de telle manière que les différentes listes d'options peuvent être injectées dans l'objet map en appelant des fonctions personnalisées
  • fonctionnera sur TOUT ÉLÉMENT qui peut déclencher l'événement select. Vous permettant d'utiliser des éléments non-formulaire et d'injecter des fonctionnalités de type déroulant tout en affectant d'autres éléments (** fonctionne avec Bootstrap!

J'ai créé un Gist pour démontrer les concepts. J'ai le Shell initial répertorié ici, mais vérifiez le lien pour vous assurer que vous disposez de la version la plus récente et des informations sur ce Gist. (Je peux le transformer en plugin)

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

La seule façon pour que cela fonctionne sur tous les navigateurs était de détacher puis de rattacher les options. J'ai ajouté une classe à chaque option pour casser également la valeur de l'option en dehors de son regroupement. Ces deux choses peuvent être liées, mais je ne suppose pas cela.

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

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

Violon: http://jsfiddle.net/JbVWV/8/

Modifier - J'ai ajouté l'appel à $("#firstselected").trigger("change") au chargement de la page. Donc, si quelque chose est déjà sélectionné dans le premier menu déroulant, le deuxième menu déroulant sera déjà correctement rempli.

2
Andy Jones

Masquer une option n'est pas défini dans tous les navigateurs. Il n'est pas défini dans la spécification W3C.

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

Désactiver l'option basée sur la première valeur sélectionnée

Vous pouvez désactiver la deuxième option qui ne permettra pas à l'utilisateur de sélectionner l'option.

DEMO: http://jsfiddle.net/HrpF2/

Code:

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

Afficher/masquer les options en fonction de la première valeur sélectionnée

Si vous voulez vraiment afficher/masquer les options, vous devez cloner les deuxièmes options et les rajouter en fonction de la première valeur de sélection. Voir ci-dessous,

DEMO: http://jsfiddle.net/HrpF2/1/

Code:

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