Скрыть параметры в списке выбора с помощью jQuery


98

У меня есть объект с парами параметров ключ / значение, которые я хочу скрыть / удалить из списка выбора. Ни один из следующих селекторов опций не работает. Что мне не хватает?

$.each(results['hide'], function(name, title) {                     
  $("#edit-field-service-sub-cat-value option[value=title]").hide();
  $("#edit-field-service-sub-cat-value option[@value=title]").hide();
}); 

12
вы уверены, что принятый ответ работает x-browser;) Я бы не хотел, чтобы кто-нибудь еще нашел эти вопросы и ответы через Google и ушел с неправильным впечатлением!
redsquare

@redsquare - именно поэтому я разместил ссылку на другой вопрос о скрытии элементов option в select, не являющемся кроссбраузерным :)
Russ Cam


Я обнаружил, что вам также необходимо отменить выбор выбранного элемента, если он скрыт после
вызова

Ответы:


127

Как бы то ни было, второй формы (с @) не существует в jQuery 1.3. Первый не работает, потому что вы, очевидно, ожидаете интерполяции переменных. Попробуй это:

$("#edit-field-service-sub-cat-value option[value=" + title + "]").hide();

Обратите внимание, что это, вероятно, будет ломаться различными отвратительными способами, если titleсодержит метасимволы селектора jQuery.


50
Скрытие вариантов является не кросс-браузерный.
mpen

1
Использование одинарных кавычек решит большинство проблем с метасимволами jquery
peterjwest


Эта концепция помогла мне найти другое решение. Спасибо
Аджай Кумар

Утомляет при скрытии <options />, так как часто это не обновляет выбранное значение. Вам нужно будет выбрать новый вариант после его скрытия. Если вы работаете в optgroup, вам будет сложно пройти через DOM.
Solvitieg

80

Вы не можете сделать это x-browser. Если я помню, то есть проблемы. Проще всего сохранить клонированную копию выбранного элемента перед удалением элементов, это позволяет легко удалить, а затем снова добавить отсутствующие элементы.


2
возврат параметров не будет проблемой, поскольку он является частью зависимого раскрывающегося списка с вызовами ajax на сервер для обновления параметров при каждом изменении. Но разве hide () не работает в IE?
hitfactory

Действительно т.е. не буду их скрывать. Не уверен насчет IE8, но определенно один из вариантов
IE

Пример ссылки pastebin также не скрывает эту опцию в Chrome
slolife

5
Вот ответ, который работает в кросс-браузере - с примером здесь - я тестировал в IE6-9, Chrome и FF
Tr1stan

Пожалуйста, посмотрите мой ответ ниже, работая в IE, FF, Chrome и Safari. Это наиболее гибкий вариант (допускающий разные значения из отображаемого текста).
Sablefoste

54

Я нашел способ получше, и он очень простой:

$("option_you_want_to_hide").wrap('<span/>')

Чтобы показать еще раз, просто найдите этот вариант (не диапазон) и $("option_you_want_to_show").unwrap().

Он был протестирован в Chrome и Firefox.


3
Вы абсолютный гений! Кроссбраузерная магия всего в одну строку.
манудеа

Прохладно. Хорошо справляется с проблемой кроссбраузерности.
Субрат Паттнаик 01

1
Я проголосовал за это, но он испортится, если не будет реализован должным образом: например, вы не можете использовать $("select").val("0").trigger("change"). Легче решение это
clod986

2
Вы теряете слишком много контроля, используя упаковку / разворачивание. легко случайно развернуть элементы, которые еще не были обернуты, таким образом, лишив их родительского элемента. Также это может испортить селекторы css. Использование show / hide лучше, хотя вам все равно нужно не забыть отменить выбор любого выбранного элемента с помощью: $ ('selector-for-dropdown'). Val ('');
omarjebari

1
Мне понравился раствор обертывания / распаковки. Просто нужно убедиться, что мы не оборачиваем уже упакованные дважды. Аналогичная идея с развернутыми.
анон

47

Вот мой поворот, вероятно, немного быстрее из-за собственных методов DOM

$.each(results['hide'], function(name, title) {                     
    $(document.getElementById('edit-field-service-sub-cat-value').options).each(function(index, option) {
      if( option.value == title ) {
        option.hidden = true; // not fully compatible. option.style.display = 'none'; would be an alternative or $(option).hide();
      }
    });
});

14

Это работает в Firefox 3.0, но не в MSIE 8 и Opera 9.62:

jQuery('#destinations').children('option[value="1"]').hide();
jQuery('#destinations').children('option[value="1"]').css('display','none');

Но вместо того, чтобы скрыть параметр, его можно просто отключить:

jQuery('#destinations').val('2'); 
jQuery('#destinations').children('option[value="1"]').attr('disabled','disabled');

Первая из двух вышеперечисленных строк предназначена для Firefox и передает фокус второй опции (при условии, что она имеет значение = "2"). Если мы его опустим, параметр будет отключен, но по-прежнему отображается параметр «включен», прежде чем мы его опустим. Следовательно, мы переключаем фокус на другой вариант, чтобы избежать этого.


12

Это МОЖЕТ быть сделано через браузер; это просто требует специального программирования. Пожалуйста, посмотрите мою скрипку на http://jsfiddle.net/sablefoste/YVMzt/6/ . Он был протестирован для работы в Chrome, Firefox, Internet Explorer и Safari.

Короче говоря, у меня есть скрытое поле, в #optionstoreкотором массив хранится последовательно (поскольку в JavaScript не может быть ассоциативных массивов). Затем, когда вы меняете категорию, он анализирует существующие параметры (только в первый раз), записывает их #optionstore, стирает все и возвращает только те, которые связаны с категорией.

ПРИМЕЧАНИЕ: я создал это, чтобы разрешить различные значения параметров из текста, отображаемого пользователю, поэтому он очень гибкий.

HTML:

<p id="choosetype">
    <div>
        Food Category:
    </div>
    <select name="category" id="category" title="OPTIONAL - Choose a Category to Limit Food Types" size="1">
        <option value="">All Food</option>
        <option value="Food1">Fruit</option>
        <option value="Food2">Veggies</option>
        <option value="Food3">Meat</option>
        <option value="Food4">Dairy</option>
        <option value="Food5">Bread</option>
    </select>
    <div>
        Food Selection
    </div>
    <select name="foodType" id="foodType" size="1">
        <option value="Fruit1" class="sub-Food1">Apples</option>
        <option value="Fruit2" class="sub-Food1">Pears</option>
        <option value="Fruit3" class="sub-Food1">Bananas</option>
        <option value="Fruit4" class="sub-Food1">Oranges</option>
        <option value="Veg1" class="sub-Food2">Peas</option>
        <option value="Veg2" class="sub-Food2">Carrots</option>
        <option value="Veg3" class="sub-Food2">Broccoli</option>
        <option value="Veg4" class="sub-Food2">Lettuce</option>
        <option value="Meat1" class="sub-Food3">Steak</option>
        <option value="Meat2" class="sub-Food3">Chicken</option>
        <option value="Meat3" class="sub-Food3">Salmon</option>
        <option value="Meat4" class="sub-Food3">Shrimp</option>
        <option value="Meat5" class="sub-Food3">Tuna</option>
        <option value="Meat6" class="sub-Food3">Pork</option>
        <option value="Dairy1" class="sub-Food4">Milk</option>
        <option value="Dairy2" class="sub-Food4">Cheese</option>
        <option value="Dairy3" class="sub-Food4">Ice Cream</option>
        <option value="Dairy4" class="sub-Food4">Yogurt</option>
        <option value="Bread1" class="sub-Food5">White Bread</option>
        <option value="Bread2" class="sub-Food5">Panini</option>
    </select>
    <span id="optionstore" style="display:none;"></span>
</p>

JavaScript / jQuery:

$(document).ready(function() {
    $('#category').on("change", function() {
        var cattype = $(this).val();
        optionswitch(cattype);
    });
});

function optionswitch(myfilter) {
    //Populate the optionstore if the first time through
    if ($('#optionstore').text() == "") {
        $('option[class^="sub-"]').each(function() {
            var optvalue = $(this).val();
            var optclass = $(this).prop('class');
            var opttext = $(this).text();
            optionlist = $('#optionstore').text() + "@%" + optvalue + "@%" + optclass + "@%" + opttext;
            $('#optionstore').text(optionlist);
        });
    }

    //Delete everything
    $('option[class^="sub-"]').remove();

    // Put the filtered stuff back
    populateoption = rewriteoption(myfilter);
    $('#foodType').html(populateoption);
}

function rewriteoption(myfilter) {
    //Rewrite only the filtered stuff back into the option
    var options = $('#optionstore').text().split('@%');
    var resultgood = false;
    var myfilterclass = "sub-" + myfilter;
    var optionlisting = "";

    myfilterclass = (myfilter != "")?myfilterclass:"all";

    //First variable is always the value, second is always the class, third is always the text
    for (var i = 3; i < options.length; i = i + 3) {
        if (options[i - 1] == myfilterclass || myfilterclass == "all") {
            optionlisting = optionlisting + '<option value="' + options[i - 2] + '" class="' + options[i - 1] + '">' + options[i] + '</option>';
            resultgood = true;
        }
    }
    if (resultgood) {
        return optionlisting;
    }
}

Не могли бы вы объяснить использование переменной resultgood? Мы удалили его использование, потому что, когда у пользователя есть отфильтрованный список, и пользователь вводит символ, который означает, что нет элементов для отображения, пустой список фактически не отображается - код продолжает перечислять элементы, которые соответствуют поисковому запросу, без лишний персонаж. Наш вариант использования немного отличается от примера - мы используем поле ввода, чтобы принять ввод поискового запроса.
B5A7

Это resultgoodпросто проверка, не было ли optionlistingдобавлено. если это так, <option>возвращается список s. В противном случае ничего не возвращается, чего бы вы хотели, если бы вы случайно включили класс, которого на самом деле не было (в этом примере, скажем, sub-Food6). Чтобы вернуть пробел в раскрывающемся списке, измените строку объявления в начале функции на var optionlisting="<option value=''></option>";.
Sablefoste

Между прочим, если бы я написал это сегодня, я бы, вероятно, не использовал класс в качестве носителя информации, а скорее dataатрибут; это более семантически правильно.
Sablefoste

Да. Мы сделали то же самое.
B5A7

5

Лучше всего установить disabled = true для элементов параметров, которые вы хотите отключить, а затем установить CSS

option:disabled {
    display: none;
}

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


4

Взгляните на этот вопрос и ответы -

Отключить параметры выбора ...

Глядя на ваш код, вам может потребоваться указать значение атрибута

$("#edit-field-service-sub-cat-value option[value='title']").hide();

из селекторов атрибутов jQuery

Кавычки в большинстве случаев необязательны, но их следует использовать во избежание конфликтов, если значение содержит такие символы, как "]"

РЕДАКТИРОВАТЬ:

Только что понял, что вы получаете заголовок из параметра функции, и в этом случае синтаксис должен быть

$("#edit-field-service-sub-cat-value option[value='" + title + "']").hide();

4

Что касается предложения redsquare, в итоге я сделал следующее:

var selectItems = $("#edit-field-service-sub-cat-value option[value=" + title + "]").detach();

а затем отменить это:

$("#edit-field-service-sub-cat-value").append(selectItems);

3

Проблема в том, что Internet Explorer, похоже, не поддерживает методы скрытия и отображения для выбора параметров. Я хотел скрыть все параметры моего выбора ddlReasonCode, у которых не было текущего выбранного типа в качестве значения атрибута "attType".

В то время как прекрасный Chrome был вполне доволен:

//Hiding all options
            $("#ddlReasonCode").children().hide();
            //Showing only the relevant options
            $("#ddlReasonCode").children("option[atttype=\"" + CurrentType + "\"]").show();

Это то, что требовалось IE (дети, не пробуйте это в CHROME :-)):

//Hiding all options
            $("#ddlReasonCode option").each(function (index, val) {
                if ($(this).is('option') && (!$(this).parent().is('span')) && ($(this).atttype != CurrentType))
                    $(this).wrap('<span>').hide();
            });
            //Showing only the relevant options
            $("#ddlReasonCode option").each(function (index, val) {
                if (this.nodeName.toUpperCase() === 'OPTION') {
                    var span = $(this).parent();
                    var opt = this;
                    if ($(this).parent().is('span') && ((this).atttype == CurrentType)) {
                        $(opt).show();
                        $(span).replaceWith(opt);
                    }
                }
            });

Я нашел эту идею упаковки на http://ajax911.com/hide-options-selecbox-jquery/


3

После тестирования решения, опубликованные выше различными, включая хаос, для скрытия элементов теперь работают в последних версиях Firefox (66.0.4), Chrome (74.0.3729.169) и Edge (42.17134.1.0).

$("#edit-field-service-sub-cat-value option[value=" + title + "]").hide();
$("#edit-field-service-sub-cat-value option[value=" + title + "]").show();

Для IE это не работает, однако вы можете отключить опцию

$("#edit-field-service-sub-cat-value option[value=" + title + "]").attr("disabled", "disabled");
$("#edit-field-service-sub-cat-value option[value=" + title + "]").removeAttr("disabled");

а затем принудительно выбрать другое значение.

$("#edit-field-service-sub-cat-value").val("0");

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


2

Похоже, вам тоже нужно обновить атрибут "selected". В противном случае текущий выбранный параметр может продолжать отображаться - хотя он, вероятно, исчезнет, ​​когда вы действительно перейдете к выбору параметра (это то, что он сделал для меня): Попробуйте сделать это:

$('#mySelector').children('option').hide();
$('#mySelector').children('option').removeAttr("selected"); //this may be overkill.
$('#mySelector').children('option[value="'+SelVal+'"]').show();  
$('#mySelector').children(':visible').attr('selected','selected'); //assuming that something is still on the list.

2

Я пытался скрыть параметры из одного списка выбора на основе выбранного варианта из другого списка выбора. Он работал в Firefox3, но не в Internet Explorer 6. У меня здесь есть несколько идей и решение, поэтому я хотел бы поделиться:

Код JavaScript

function change_fruit(seldd) {
    var look_for_id=''; var opt_id='';
    $('#obj_id').html("");
    $("#obj_id").append("<option value='0'>-Select Fruit-</option>");
    if(seldd.value=='0') {
        look_for_id='N';
    }
    if(seldd.value=='1'){
        look_for_id='Y';
        opt_id='a';
    }
    if(seldd.value=='2') {
        look_for_id='Y';
        opt_id='b';
    }
    if(seldd.value=='3') {
        look_for_id='Y';
        opt_id='c';
    }

    if(look_for_id=='Y') {
        $("#obj_id_all option[id='"+opt_id+"']").each(function() {
          $("#obj_id").append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
        });
    }
    else {
        $("#obj_id_all option").each(function() {
          $("#obj_id").append("<option value='"+$(this).val()+"'>"+$(this).text()+"</option>");
        });
    }
}

HTML

<select name="obj_id" id="obj_id">
    <option value="0">-Select Fruit-</option>
    <option value="1" id="a">apple1</option>
    <option value="2" id="a">apple2</option>
    <option value="3" id="a">apple3</option>
    <option value="4" id="b">banana1</option>
    <option value="5" id="b">banana2</option>
    <option value="6" id="b">banana3</option>
    <option value="7" id="c">Clove1</option>
    <option value="8" id="c">Clove2</option>
    <option value="9" id="c">Clove3</option>
</select>

<select name="fruit_type" id="srv_type" onchange="change_fruit(this)">
    <option value="0">All</option>
    <option value="1">Starts with A</option>
    <option value="2">Starts with B</option>
    <option value="3">Starts with C</option>
</select>

<select name="obj_id_all" id="obj_id_all" style="display:none;">
    <option value="1" id="a">apple1</option>
    <option value="2" id="a">apple2</option>
    <option value="3" id="a">apple3</option>
    <option value="4" id="b">banana1</option>
    <option value="5" id="b">banana2</option>
    <option value="6" id="b">banana3</option>
    <option value="7" id="c">Clove1</option>
    <option value="8" id="c">Clove2</option>
    <option value="9" id="c">Clove3</option>
</select>

Проверено, что он работает в Firefox 3 и Internet Explorer 6.


5
Согласно W3Cid , атрибут должен быть уникальным: ID = Этот атрибут присваивает имя элемента. Это имя должно быть уникальным в документе.
Джаспер

1

Чтобы избежать конкатенации строк, вы можете использовать jQuery.grep

$($.grep($("#edit-field-service-sub-cat-value option"),
         function(n,i){
           return n.value==title;
         })
 ).hide()

1

Наверное, не такой элегантный или многоразовый, как плагин jquery. но другой подход - просто сохранить элементы опций и при необходимости поменять их местами:

var SelectFilter = function ()
        {
            this.allOptions = $("#someSelect option");

            this.fooBarOptions= $("#someSelect option[value='foo']");
            this.fooBarOptions= this.fooBarOptions.add($("#someSelect option[value='bar']"));


            this.showFooBarOptions = function()
            {
                $("#someSelect option").remove();
                $("#someSelect").append(this.fooBarOptions);
            };
            this.showAllOptions = function()
            {
                $("#someSelect option").remove();
                $("#someSelect").append(this.allOptions);
            };



        };

сделайте это, чтобы использовать объект:

var filterObject = new SelectFilter();
filterObject.showFooBarOptions (); 

1
$("option_you_want_to_hide").addClass('hidden')

Затем в вашем CSS убедитесь, что у вас есть

.hidden{
    display:none;
}

1

Я реализовал решение, используя функцию, которая фильтрует combobox ( <select>) на основе настраиваемых атрибутов данных. Это решение поддерживает:

  • Наличие, <option>чтобы показать, когда фильтр оставит выбор пустым.
  • Уважает существующие выбранные атрибуты.
  • <option> элементы без атрибута data-filter остаются нетронутыми.

Протестировано с jQuery 2.1.4 и Firefox, Chrome, Safari и IE 10+.

Это пример HTML:

<select id="myCombobox">
  <option data-filter="1" value="AAA">Option 1</option>
  <option data-filter="1" value="BBB">Option 2</option>
  <option data-filter="2" value="CCC">Option 3</option>
  <option data-filter="2" value="DDD">Option 4</option>
  <option data-filter="3" value="EEE">Option 5</option>
  <option data-filter="3" value="FFF">Option 6</option>
  <option data-filter-emptyvalue disabled>No Options</option>
</select>

Код jQuery для фильтрации:

function filterCombobox(selectObject, filterValue, autoSelect) {

  var fullData = selectObject.data("filterdata-values");
  var emptyValue = selectObject.data("filterdata-emptyvalue");

  // Initialize if first time.
  if (!fullData) {
    fullData = selectObject.find("option[data-filter]").detach();
    selectObject.data("filterdata-values", fullData);
    emptyValue = selectObject.find("option[data-filter-emptyvalue]").detach();
    selectObject.data("filterdata-emptyvalue", emptyValue);
    selectObject.addClass("filtered");
  }
  else {
    // Remove elements from DOM
    selectObject.find("option[data-filter]").remove();
    selectObject.find("option[data-filter-emptyvalue]").remove();
  }

  // Get filtered elements.
  var toEnable = fullData.filter("option[data-filter][data-filter='" + filterValue + "']");

  // Attach elements to DOM
  selectObject.append(toEnable);

  // If toEnable is empty, show empty option.
  if (toEnable.length == 0) {
    selectObject.append(emptyValue);
  }

  // Select First Occurrence
  if (autoSelect) {
    var obj = selectObject.find("option[selected]");
    selectObject.val(obj.length == 0 ? toEnable.val() : obj.val());
  }
}

Чтобы использовать его, вы просто вызываете функцию со значением, которое хотите сохранить.

filterCombobox($("#myCombobox"), 2, true);

Тогда результирующий выбор будет:

<select id="myCombobox">
  <option data-filter="2" value="CCC">Option 3</option>
  <option data-filter="2" value="DDD">Option 4</option>
</select>

Исходные элементы сохраняются функцией data (), поэтому последующие вызовы будут добавлять и удалять правильные элементы.


Это отличное решение многократного использования, единственное, что я нашел, работающее в Safari. Спасибо!
Эчилон

0

Ответ указывает, что @это недопустимо для новых итераций jQuery. Хотя это правильно, некоторые старые IE по-прежнему не скрывают элементы параметров. Для тех, кому приходится иметь дело с скрытыми элементами опций в затронутых версиях, я опубликовал обходной путь здесь:

http://work.arounds.org/issue/96/option-elements-do-not-hide-in-IE/

В основном просто оберните его промежутком и замените на выставке.


0

Любой, кто сталкивается с этим вопросом, может также рассмотреть возможность использования Chosen , который значительно расширяет возможности select.


0

Я знаю, что на этот вопрос есть ответ. Но мое требование было немного другим. Вместо значения я хотел фильтровать по тексту. Итак, я изменил ответ @William Herry следующим образом.

var array = ['Administration', 'Finance', 'HR', 'IT', 'Marketing', 'Materials', 'Reception', 'Support'];
if (somecondition) {
   $(array).each(function () {
       $("div#deprtmnts option:contains(" + this + ")").unwrap();
   });
}
else{
   $(array).each(function () {
       $("div#deprtmnts option:contains(" + this + ")").wrap('<span/>');
   });
}

Таким образом, вы также можете использовать значение, заменив содержит, как это

 $("div#ovrcateg option[value=" + this + "]").wrap('<span/>');

0

Для опции скрытия при выборе используйте:

option_node.hidden = true; # For hide selcet item
option_node.hidden = false; # For show selcet item

Где option_node - HTMLOptionElement

PS: Я не использую JQuery, но предполагаю, что он будет работать:

$('.my_select option[value="my_cool_value"]').hidden = true

IE не поддерживает скрытие при выборе параметров
RitchieD

stackoverflow.com/questions/2031740/… PS: IE не является браузером. IE - программа для скачивания браузера! :)
DAVIDhaker

0

Я решил, что лучше всего полностью удалить DOM.

$(".form-group #selectId option[value='39']").remove();

Кроссбраузерная совместимость. Работает и с IE11


0
 $('#id').val($('#id option:eq(0)').hide());

option: eq (0) - скрыть параметр с индексом «0» в поле выбора.



Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.