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

ИЗМЕНИТЬ

У меня есть два выбора. Когда я выбираю значение в первом выборе, второй должен быть заполнен соответствующим образом (я должен предотвратить вызов ajax).

Я помещаю все значения второго выбора в сеанс var, но моя проблема заключается в выборе только тех, которые привязаны к первому select, поэтому я пытался использовать классы 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

Ответы

Ответ 1

Поэтому, когда я правильно понимаю ваш вопрос, вы хотите сделать параметры второго поля выбора зависимыми от выбранного значения в первом поле выбора.

Я пробовал это быстро и скрываю параметр css, похоже, не работает с перекрестным браузером, даже последняя версия chrome на mac не будет скрывать параметры.

Итак, я придумал следующее:

Сначала HTML: Я использовал классы для обозначения зависимостей. Это позволяет использовать атрибут 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");
});

И вот скрипка, показывающая действие script в действии: http://jsfiddle.net/Kn8Gc/

Примечание. Если вы получаете данные из базы данных, а пользователь уже выбрал #firstSelect, просто используйте атрибут selected="selected". #secondSelect автоматически отобразит правильные значения. Просто попробуйте скрипку выше и "предварительно выберите", например, значение1 вместо 0!


Также здесь "общая" функция, которую можно легко использовать, чтобы сделать любые два поля выбора зависимыми от eachother (все еще используя классы 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/

Ответ 2

Я не уверен, что полностью понимаю ваш вопрос, но как насчет этого:

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

Единственный способ, которым я получил это для работы в браузерах, - это отсоединить, а затем снова подключить параметры. Я добавил класс к каждой опции, чтобы также разбить значение параметра, кроме его группировки. Эти две вещи могут быть связаны, но я не буду этого допускать.

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

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

Изменить - я добавил вызов $("#firstselected").trigger("change") при загрузке страницы. Итак, если в первом выпадающем списке есть что-то, выбранное, второе выпадающее меню уже будет заполнено правильно.

Ответ 4

Скрытие опции не задано во всех браузерах. Он не определен в спецификации W3C.

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

Отключение опции на основе первого значения выбора

Вы можете отключить второй вариант, который не позволит пользователю выбрать эту опцию.

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

Показать/скрыть параметры, основанные на первом значении выбора

Если вы действительно хотите показать/скрыть параметры, вам нужно клонировать второй вариант и добавлять их обратно на основе первого значения выбора. См. Ниже,

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

Ответ 5

Включить объект javascript, который имеет сопоставление выбора

этот тип вопроса часто возникает в SPA-разработке, и я разработал этот подход. Я рекомендую создать объект javascript с различными списками опций и объектными ключами, состоящими из имен полей выбора, которые вызовут родственные отношения: после того, как поля выбора будут динамически созданы, привязка к событию "select" зависимого выбора элемент и запустить пользовательский script, чтобы оценить выбранный параметр, проанализировать вашу карту и затем соответствующим образом отобразить параметры.

Я принял эту концепцию и создал довольно красивую оболочку, которая должна не только позволить вам это между двумя выбранными вами элементами, которые вы упоминаете, но по существу позволяете вам иметь как можно больше зависимых элементов выбора... заполняя все их на основе выбора, сделанного в зависимом элементе. Вот еще более холодные преимущества:

  • Разметка html чрезвычайно чиста.
  • вы можете инициализировать зависимости даже от динамически созданных параметров зависимостей
  • код javascript очень чистый и точный
  • это легко сделать модульным, поэтому его можно преобразовать в плагин или модуль с несколькими строками кода
  • легко асинхронно создавать новые параметры и асинхронно изменять зависимости с помощью $.extend() и предоставленного объекта SelectOption
  • построена таким образом, что различные опции могут быть введены в объект map путем вызова пользовательских функций
  • будет работать над ЛЮБОЙ ЭЛЕМЕНТ, который может вызвать событие select. Позволяя вам использовать неформатные элементы и вводить функциональность выпадающего типа и по-прежнему влиять на другие элементы (** работает с Bootstrap!

Я создал суть, чтобы продемонстрировать концепции. У меня есть исходная оболочка, указанная здесь, но проверьте ссылку, чтобы убедиться, что у вас есть самая обновленная версия и информация об этом значении. (Я могу превратить его в плагин)

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>

Выбор-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

});