1

I have an HTML <select> element that contains some <optgroup> elements containing some <option> elements, like this:

<select>
  <optgroup label="label1">Label 1
    <option>opt1.1</option>
    <option>opt1.2</option>
    <option>opt1.3</option>
  </optgroup>
  <optgroup label="label2">Label 2
    <option>opt2.1</option>
    <option>opt2.2</option>
  </optgroup>
  ...
</select>

I would like to hide all <option>s except the ones in a specific <optgroup>, and then later show them again if the user wants to (that is: I don't want to use innerHTML = '';, because I want to be able to restore my <option>s back later). So I wrote this:

var groups = document.getElementsByTagName('optgroup');
for (var i = 0; i < groups.length; i++) {
    if (groups[i].label != str) {
        var options = groups[i].childNodes;
        for (var j = 0; j < options.length; j++)
            options[j].style.display = 'none';
    }
}

and it doesn't work (on Firefox and Safari). Even if I try something like options[j].style.color = 'red'; nothing happens. But options[j].disabled = true; works, although I would like to hide those <options>s completely.

... why on Earth?

P.S. I can only use vanilla JavaScript :)

Giorgio
  • 2,137
  • 3
  • 20
  • 40
  • 1
    Many browsers prevent hiding select option elements. There are some different solutions [here](http://stackoverflow.com/questions/4398966/how-can-i-hide-select-options-with-javascript-cross-browser). – shipshape Jan 18 '17 at 20:19
  • You're right, that might be the problem. So Safari apparently prevents hiding option elements. – Giorgio Jan 18 '17 at 21:05

2 Answers2

1

From what I can see, this is working in FF, IE and Chrome. I disable by hiding the entire optgroup. Hope this helps!

var selectEl = document.getElementsByTagName("select")[0];
var optGroup = document.getElementsByTagName("optgroup")[0];
var toggleButton = document.getElementsByTagName("button")[0];
optGroup.style.display = "inline";
toggleGroup = function(){
console.log(optGroup.style.display);
  if (optGroup.style.display === "inline") {
    optGroup.style.display = "none";
    toggleButton.innerHTML = "Show group 1";  
    selectEl.selectedIndex = 3;
  } else {
    optGroup.style.display = "inline";
    toggleButton.innerHTML = "Hide group 1";  
    selectEl.selectedIndex = 0;
  }
    
}
<button onclick="toggleGroup()">
Hide group 1
</button>
<select>
  <optgroup label="label1">Label 1
    <option>opt1.1</option>
    <option>opt1.2</option>
    <option>opt1.3</option>
  </optgroup>
  <optgroup label="label2">Label 2
    <option>opt2.1</option>
    <option>opt2.2</option>
  </optgroup>
</select>
Snowmonkey
  • 3,716
  • 1
  • 16
  • 16
  • Thank you for your answer. Apparently, Safari prevents option elements from being hid, so the only way to solve this problem would be in the link provided in the comment by @shipshape. – Giorgio Jan 18 '17 at 21:09
0

Try using the hidden attribute. One thing you'll need to keep in mind is that even if the option is hidden, the selected value won't necessarily change to reflect that (e.g. if you hide opt1.1, the select will still show opt1.1), so you'll need some sort of fallback if you hide a currently selected value.

furkle
  • 5,019
  • 1
  • 15
  • 24