user1246800
user1246800

Reputation: 287

<option> with display:none; does not work on IE

I have some style='display:none' in the option element, it work well on Chrome and I realise it does not work on IE.

<select>
 <option style="display:none;">One</option>
 <option>Two</option>
 <option style="display:none;">Three</option>
 <option>Four</option>
</select>

Using jQuery, how to loop through the option to find display:none and remove the elements <option>?

Upvotes: 7

Views: 13256

Answers (5)

Namrata S Jain
Namrata S Jain

Reputation: 1

Display: none will not work for IE11. I had same issue for search in select option. What I did is disabled the unmatched options and then hide them. After this I have sorted the options to show only enabled options on top. The code I have written is pasted below - please try to understand the logic I hope it will work.

To disable the options use:

$("#addselect option")attr('disabled', 'disabled').hide

And to again enable it use:

$("#addselect option").removeAttr('disabled').show();

Sort by disabled options:

$("#addselect option").each(function (i, val) {
    if ($(this)[i].disabled) {
        moveDown("selectId");
    }
    else {
        moveUp("selectId");
    }
 }

function moveUp(selectId) {
    var selectList = document.getElementById(selectId);
    var selectOptions = selectList.getElementsByTagName('option');
    for (var i = 1; i < selectOptions.length; i++) {
        var opt = selectOptions[i];
        if (!opt.disabled) {
            selectList.removeChild(opt);
            selectList.insertBefore(opt, selectOptions[i - 1]);
        }
    }
}

function moveDown(selectId) {
    var selectList = document.getElementById(selectId);
    var selectOptions = selectList.getElementsByTagName('option');
    for (var i = selectOptions.length - 2; i >= 0; i--) {
        var opt = selectOptions[i];
        if (opt.disabled) {
            var nextOpt = selectOptions[i + 1];
            opt = selectList.removeChild(opt);
            nextOpt = selectList.replaceChild(opt, nextOpt);
            selectList.insertBefore(nextOpt, opt);
        }
    }
}

Upvotes: 0

David Gausmann
David Gausmann

Reputation: 1718

Today I had the same problem. Without removing the unwanted options you won't get your expected result. But the problem is that you need to memorize those options if you want to display them later.

My solution is very simple and works in all major browsers:

function filterList(oList, rxSearch)
{
  // Create backup of the old option list (only once)
  if(typeof(oList.tagOptions) === "undefined")
  {
    // Save current options
    oList.tagOptions = [ ];  // Generate a dynamic property for this DOM object
    for(var i = 0; i < oList.options.length; ++i)
      oList.tagOptions.push(oList.options[i]);
  }

  // Clear the current option list
  while(oList.options.length)
    oList.options.remove(0);

  // Add only those options which match the regular expression
  for(var i = 0; i < oList.tagOptions.length; ++i)
  {
    if(rxSearch.test(oList.tagOptions[i].text))
      oList.options.add(oList.tagOptions[i]);
  }
}

The trick is that the option elements will be copied into the dynamically created tagOptions property on the first run. Since there will be still references (in tagOptions) to these removed option DOM elements they will not be released. Furthermore you need no global variables for that. Later the visible options (oList.options) will be cleared and only those options added, which match the search term.

Using the following HTML code:

<select id="myList" size="10">
<option>apple</option>
<option>advocado</option>
<option>banana</option>
<option>coconut</option>
</select>

You would call it like this:

filterList(document.getElementById("myList"), /^a/i);  // Display only those elements, which start with an a
alert("Display all with a");
filterList(document.getElementById("myList"), /^b/i);  // Display only those elements, which start with an b
alert("Display all with b");
filterList(document.getElementById("myList"), /^/i);   // Display only those elements, which start with an c
alert("Display all");

I've tested this with Firefox, Internet Explorer 11, Chrome and Opera. It works fine for my purposes.

function filterList(oList, rxSearch)
{
  // Create backup of the old option list (only once)
  if(typeof(oList.tagOptions) === "undefined")
  {
    // Save current options
    oList.tagOptions = [ ];  // Generate a dynamic property for this DOM object
    for(var i = 0; i < oList.options.length; ++i)
      oList.tagOptions.push(oList.options[i]);
  }

  // Clear the current option list
  while(oList.options.length)
    oList.options.remove(0);

  // Add only those options which match the regular expression
  for(var i = 0; i < oList.tagOptions.length; ++i)
  {
    if(rxSearch.test(oList.tagOptions[i].text))
      oList.options.add(oList.tagOptions[i]);
  }
}

filterList(document.getElementById("myList"), /^a/i);  // Display only those elements, which start with an a
alert("Display all with a");
filterList(document.getElementById("myList"), /^b/i);  // Display only those elements, which start with an b
alert("Display all with b");
filterList(document.getElementById("myList"), /^/i);   // Display only those elements, which start with an c
alert("Display all");
<select id="myList" size="10">
<option>apple</option>
<option>advocado</option>
<option>banana</option>
<option>coconut</option>
</select>

Upvotes: 0

Luke
Luke

Reputation: 19961

John Boker's solution is the right one for this question. But it does have the downside that you won't be able to ever retrieve those options once you've removed them.

One solution is to save the full HTML of the <select> before you remove any <option> tags.

var $s = $('select');
$s.data("originalHTML", $s.html());

Now you can easily restore by reversing this: $s.html($s.data("originalHTML"));

Full details are on this solution: https://stackoverflow.com/a/24439289/1766230

Also an example: http://jsfiddle.net/luken/9CYjy/

Upvotes: 1

sakhunzai
sakhunzai

Reputation: 14470

I had the same issue but bit complex , and yes we need to remove the option to hide in IE/Chrome/Safari.

But in some cases we want to just HIDE group of options based on criteria /filter and remove() just removes completely. I have following solution to this problem. It removes the options but keeps removed option in a data attribute on same select element and when desired we just re-populate in given sorting order ( value or label).

Let say:

<select id='sorty' multiple=true>
    <option value="1">Group A</option>
    <option value="2">Group B</option>
    <option value="3">Group c</option>
    <option value="4">Group D</option>
    <option value="5">Group D</option>
</select>

<button onclick="HideG('A')">Hide Group A</button>
<button onclick='HideG("B")'>Hide Group B</button>
<button onclick='HideG("C")'>Hide Group C</button>
<button onclick='HideG("D")'>Hide Group D</button>
<button onclick='ShowAll()'>Show ALL</button>

(require Jquery):

function selectOptionFilter(src,filter,sortBy)
{
   if(!$(src).data('hiddenOpts'))
      $(src).data('hiddenOpts',[]);

   //re-insert while keeping sort order by value or label 
   $($(src).data('hiddenOpts')).each(function(){
      var hiddenOpt=this;
      var positioned=false;
      $(src).find('option').each(function(i){
        if((sortBy=='value' && $(this).attr('value')*1 > $(hiddenOpt).attr('value'))
           ||
           (sortBy=='label' && $(this).text() > $(hiddenOpt).text())
          ){
          $(this).before(hiddenOpt);
          positioned=true;  
          //break
          return false;
        }
      }); 
      //else append       
      if(!positioned){
        $(src).append(hiddenOpt);
      }
   });

   //clean the hidden list
   $(src).data('hiddenOpts',[]);

   //apply the filter and remove options
    if( typeof filter=='function'){
        $(src).find('option').filter(filter).each(function(){
            $(src).data('hiddenOpts').push($(this).remove());
      });
   }
}

function HideG(xname){ 
  selectOptionFilter($('#sorty'),function(){
   return ( $(this).text().indexOf(xname) > -1);
   },'value');  
}

function ShowAll(){
  selectOptionFilter($('#sorty'),function(){ return false;},'value');
}

You can pass a more complex filter function to remove the desired options.

Working Demo

Upvotes: 0

John Boker
John Boker

Reputation: 83699

this seems to work for me:

http://jsfiddle.net/PP4AP/1/

$('select option').each(function(){

    if(this.style.display == 'none')
    {
        $(this).remove();
    }

});

Upvotes: 6

Related Questions