JQuery Hide Option doesn't work in IE and Safari
Asked Answered
C

8

17

I'm trying to hide a few options in a dropdown box using .hide(). This works perfectly fine in firefox and chrome, but it doesn't work in IE and Safari. My original code is more complex but I've narrowed it down to this.

I've tried several combinations and nothing has worked.

.hide() works, but not for things within option tags for some reason.

Can someone please help me? This is driving me nuts. Thank you so much for taking the time help!

Here's my jscript:

    <script type="text/javascript" src="js/jquery-1.7.1.min.js"></script>
    <script type="text/javascript">
        $(document).ready(function(){
            $(".wrapper1").hide();
        });
    </script>

Here's the HTML:

                <label for="prodName">Product Name:</label> 
                <input type="text" name="prodName" /><br />

                <label for="candy">Candy:</label> 
                <select name="candy" id="candy">
                        <option value="0" class="blank" selected="selected"></option><!-- PHP and JS validators should not allow "0" here. User should be prompted to select something. -->
                        <option value="1" class="wrapper1">Hide this 1</option>
                        <option value="2" class="wrapper1">Hide this 2</option>
                        <option value="3" class="wrapper2">Show this 1</option>     
                </select><br />
Chesterfieldian answered 4/12, 2011 at 6:27 Comment(0)
U
11

This will work.. change .show to .showOption and .hideOption. However this still kind of sucks in IE because in firefox you can make it hide an option which is selected. So if "Select One" is shown and is hidden. Firefox will still say "select one".

$.fn.showOption = function() {
this.each(function() {
    if( this.tagName == "OPTION" ) {
        var opt = this;
        if( $(this).parent().get(0).tagName == "SPAN" ) {
            var span = $(this).parent().get(0);
            $(span).replaceWith(opt);
            $(span).remove();
        }
        opt.disabled = false;
        $(opt).show();
    }
});
return this;
}
$.fn.hideOption = function() {
this.each(function() {
    if( this.tagName == "OPTION" ) {
        var opt = this;
        if( $(this).parent().get(0).tagName == "SPAN" ) {
            var span = $(this).parent().get(0);
            $(span).hide();
        } else {
            $(opt).wrap("span").hide();
        }
        opt.disabled = true;
    }
});
return this;
}
Unsupportable answered 17/6, 2013 at 23:20 Comment(1)
This is a great answer as far as I can tell - it works and it makes it easy to update code that needs to be fixed! Thankyou.Intelligible
T
8

You're right. Some browsers just won't let you hide option elements. You'll likely need to remove them.

Although perhaps a better (or at least an alternate) possibility would be to disable them.

$(".wrapper1").prop('disbled', true);
Timoteo answered 4/12, 2011 at 6:39 Comment(3)
disable also works bad in ie6 and not sure about ie7 - robust approach is remove options , for instance create a hidden select and put hidden options hereSmokeless
@vittore: Ah, wasn't aware of the IE6 issue. Then yes, removing would be the way to go.Timoteo
Thanks Fred, Vittore, and Jim. You guys are great! I've been trying to figure it out all weekend.Chesterfieldian
C
5

You have to remove the option elements.. hiding them with display:none is not supported in many browsers.

HIDE

var elems = $(".wrapper1").remove();

SHOW

$('#candy').append(elems);
Coralline answered 4/12, 2011 at 6:49 Comment(1)
To put the options back in their original location, you'll want to do $('#canty > option:nth-child(1)').after( elems );.Timoteo
F
4

I tried the solution that uses <span> around options, but found that it didn't work for me in all browsers.

I've made a jQuery Plugin that solves this very nicely. With it, you would do this:

$('#selection1').hideOption('1');
$('#selection1').showOption('1');

You can hide and show them as much as you want, and they will keep their original order and any .data('x') values you've assigned to the option. It works in all browsers. You can see that in this sample: jsFiddle - Toggle Dropdown Options

You can get the Toggle Dropdown Options plug-in. If you don't like plug-ins, just copy the JavaScript code from it to your own project's JavaScript file. See the Read the Docs link on the plug-in for more information!

Fernanda answered 21/1, 2014 at 23:21 Comment(4)
how would I return the select to it's original state? Basically looking for something like this: $('#select').resetOptions();Alina
You can add this inside the code after other $.fn functions: $.fn.showOptions = function () { return this.filter('option').each(function () { var opt = $(this); opt.showOption(); }); };Fernanda
It looks like showOption() requires a value in order to work correctly, or am I missing something?Alina
Your jsFiddle example doesnt work on IE11 - I checked.Call
R
1

I found one workaround for this, Just wrap with Jquery wrap()) to option you want to hide,it will hidden automatically and unwrap span with unwrap() to show it again.

Rossuck answered 11/5, 2016 at 11:8 Comment(0)
J
0

I tried in many different ways but this solution seems reasonable and I have used in my code. No plugins required simple register function with jquery object

Solution at glance:

(function ($) {


$('#showOne').click(function () {
    $('#ddlNumbers').showHideDropdownOptions('3', true);
});

$('#hideOne').click(function () {
    $('#ddlNumbers').showHideDropdownOptions('3', false);
});

 $.fn.showHideDropdownOptions = function(value, canShowOption) { 

         $(this).find('option[value="' + value + '"]').map(function () {
            return $(this).parent('span').length === 0 ? this : null;
        }).wrap('<span>').hide();

        if (canShowOption) 
            $(this).find('option[value="' + value + '"]').unwrap().show();
        else 
            $(this).find('option[value="' + value + '"]').hide();

}



})(jQuery);

Here is the complete implementation http://jsfiddle.net/8uxD7/3/

Junior answered 9/4, 2014 at 11:43 Comment(0)
H
0

Safari renders things differently and uses a UI overlay for dropdowns. You can't just hide them, but you can refresh the options match from array each time. Here I use jQuery to clear a select options each time and create new options:

myFunction();

function myFunction() {

  //alert("dins");

    var select = document.getElementById("selectArticles");
  var options = ["NouCreus", "Pic de l'Àliga", "Puigmal", "Finestrelles", "NouFonts", "Núria Estació"];
  
    var i, L = select.options.length - 1;
  for(i = L; i >= 0; i--) {
     select.remove(i);
  }

    var input, filter, ul, li, a, i, txtValue;
    input = document.getElementById("inputPatro");
    filter = input.value.toUpperCase();
  
  var el = document.createElement("option");
      el.textContent = "Vall de Núria";
      el.value = "-1";
      select.appendChild(el);

  for(var i = 0; i < options.length; i++) {
    var opt = options[i];
    if (opt.toUpperCase().indexOf(filter) > -1) {
      var el = document.createElement("option");
      el.textContent = opt;
      el.value = opt;
      select.appendChild(el);
    }
  }
}
<input type="text" id="inputPatro" onchange="myFunction()" placeholder="Filtre per nom.." title="Escriu un patró per filtrar les opcionw del desplegable">
<select id="selectArticles">
</select>
Hemiplegia answered 10/10, 2020 at 7:14 Comment(0)
L
0

try this way:

$(function(){
  var $primary = $('#primary');
  $primary.change(function(){
    refreshSecondary($(this).val());
  });
  $primary.trigger('change');
})

function refreshSecondary(primary) {
  var $secondary = $('#secondary')
  if (!$secondary.data('init')) {
    // 将所有 option 缓存至 data 中,然后仅渲染只符合条件的 options (safari 不支持 option 隐藏)
    var options = [];
    $secondary.find('option').each(function(){
      var $option = $(this);
      options.push($option[0].outerHTML);
    });
    $secondary.data({init: true, options: options});
  }
  $secondary.empty();
  $.each($secondary.data('options'), function(index, option){
    var $option = $(option);
    if ($option.data('primary') === primary) {
      $secondary.append($option);
    }
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

<select id="primary">
  <option value="swe">Swedish Cars</option>
  <option value="ger">German Cars</option>
  <option value="ita">Italian</option>
</select>
<select id="secondary">
  <option value="volvo" data-primary="swe">Volvo</option>
  <option value="saab" data-primary="swe">Saab</option>
  <option value="mercedes" data-primary="ger">Mercedes</option>
  <option value="audi" data-primary="ger">Audi</option>
  <option value="bmw" data-primary="ger">BMW</option>
  <option value="ferrari" data-primary="ita">Ferrari</option>
  <option value="lamborghini" data-primary="ita">Lamborghini</option>
</select>

https://codepen.io/pen?template=dyjoyvr

Lila answered 22/12, 2022 at 8:38 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.