How to hide a selectize option programmatically?
Asked Answered
J

2

3

I currently have a selectize drop-down that is suppose to have some options in it disabled and hidden depending on a list of strings that I have. Here is the non-selectize javascript function that I tried:

<!DOCTYPE html>
<html>

<body>

  <select onchange="ToggleSelectizeOptions(this.value)">
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
    <option value="opel">Opel</option>
    <option value="audi">Audi</option>
    <option value="ford">Ford</option>
    <option value="hyundai">Hyundai</option>
    <option value="honda">Honda</option>
    <option value="porsche">Porsche</option>
  </select>

  <select id="selectize">
    <option value="">All Vehicles</option>
    <option value="volvo">Volvo</option>
    <option value="saab">Saab</option>
    <option value="opel">Opel</option>
    <option value="audi">Audi</option>
    <option value="ford">Ford</option>
    <option value="hyundai">Hyundai</option>
    <option value="honda">Honda</option>
    <option value="porsche">Porsche</option>
  </select>

  <script>
    function ToggleSelectizeOptions(ids) {
      var selectizeOptions = document.getElementById("selectize").options;
      var selectizeSingleOption;

      //We always start at 1 because index 0 always have "" as the value.
      for (var idx = 1; idx < selectizeOptions.length; idx++) {
        selectizeSingleOption = selectizeOptions[idx];
        if (ids) {
          if (ids.includes(selectizeSingleOption.value)) {
            selectizeSingleOption.style.display = "";
          } else {
            selectizeSingleOption.style.display = "none";
          }
        } else {
          selectizeSingleOption.style.display = "";
        }
      }
    }
  </script>

</body>

</html>

This works with dropdowns that are not selectize controls but I'm looking for a solution that would use selectize.js to do the same thing.

I saw this question that is similar to what I want, except the answer disables the option while I want to hide the option.

Joslin answered 9/10, 2018 at 16:39 Comment(2)
Create a minimal reproducible example.Convulsant
@RokoC.Buljan I added code snippet to show that the code works.Joslin
V
5

I am not aware of a way to "hide" selectize options (with display css or otherwise) other than simply removing them from the options array that is created when you initialize a selectize control. If that is all that you need to do, then you can remove a selectize option by using the selectize removeOption(value) method (see the working snippet below for an example).

Based on your code example, it looks like your ultimate goal is to create cascading dropdowns. If so, see the 2nd snippet below for an example.

const sel1 = $('#select1').selectize();
sel1[0].selectize.removeOption('ford');
sel1[0].selectize.refreshOptions();
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Selectize</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/css/selectize.default.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/js/standalone/selectize.js"></script>
  </head>
  <body>
    <select id="select1">
      <option value="ford">Ford</option>
      <option value="honda">Honda</option>
    </select>
  </body>
</html>

If your ultimate goal is to create cascading dropdowns where the value selected in the first select element determines which options are available in a second select element. The snippet below initializes the options in the javascript rather than the html.

const models = [{text: 'Models', value: ''}];
const makes = [
  {text: 'Makes', value: ''},
  {text: 'Ford', value: 'ford'},
  {text: 'Honda', value: 'honda'}
];

const modelsByMake = {
  ford: [
    {text: 'Explorer', value: 'explorer'},
    {text: 'Expedition', value: 'expedition'}
  ],
  honda: [
    {text: 'Civic', value: 'civic'},
    {text: 'Accord', value: 'accord'}
  ]
};

const sel2 = $('#select2').selectize({
  options: models,
  items: [''],
  valueField: 'value',
  labelField: 'text',
  sortField: 'value',
  searchField: ['text'],
  load: (query, callback) => {
    let options = [];
    $.each(modelsByMake, (i, v) => {
      options = options.concat(v);
    });
    
    callback(options);
  },
  preload: true
});

const sel1 = $('#select1').selectize({
  options: makes,
  items: [''],
  valueField: 'value',
  labelField: 'text',
  sortField: 'value',
  searchField: ['text'],
  onChange: (value) => {
    let options = models;
    if (value) {
      // get models for selected make
      options = options.concat(modelsByMake[value]);
    } else {
      // get all models
      $.each(modelsByMake, (i, v) => {
         options = options.concat(v);
      });
    }
    
    sel2[0].selectize.clear(); // clear sel2 selected items
    sel2[0].selectize.clearOptions(); // clear sel2 options
    
    // load options corresponding to sel1 value in sel2
    sel2[0].selectize.load((callback) => {
      callback(options);
    });
    
    // refresh sel2 options list
    sel2[0].selectize.refreshOptions();
  }
});
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Selectize</title>
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/css/selectize.default.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/selectize.js/0.12.6/js/standalone/selectize.js"></script>
  </head>
  <body>
    <select id="select1"></select>
    <select id="select2"></select>
  </body>
</html>
Villatoro answered 11/10, 2018 at 14:19 Comment(4)
Your cascading dropdown solution is more like what I wanted. I just hoped I didn't need to keep track of the original list of options. An example that I had in mind was that the first drop down could have an option called "All Makes" which would show all available models in the second drop down. If I pick "Ford" as my make then it should show only Ford models but if I switch back to "All Makes" it would show all available models again.Joslin
I'm going to accept this answer, but I was wondering if there is a way to grab the current list of options so that way I could revert the 2nd dropdown back to the original list whenever I need to?Joslin
@JohnOdom - I see... edited answer to include functions that display all models when no make is selected (includes change to enable users to select "Makes" or "Models" in order to reset the dropdown - rather than using placeholders). You can use something similar to the approaches in the load and onChange functions if you need to reset the list of models based on some other action.Villatoro
Thanks! This is very helpful to me!Joslin
T
1

I had the same task - hide or remove some selectized options. The @benvc solution works for me, but it displays a dropdown, as if it was pressed.

Improved version:

const sel1 = $('#select1').selectize();
sel1[0].selectize.removeOption('ford');
sel1[0].selectize.refreshOptions(false);

Explanation:

As the documentation says it has a boolean parameter triggerDropdown:

refreshOptions(triggerDropdown)

...

triggerDropdown boolean

https://selectize.dev/docs/API/selectize#refreshoptionstriggerdropdown

Setting it to false prevents a dropdown from appearing. It worked even without refreshOptions() call. But I decided to keep it.

Titanism answered 13/3, 2023 at 10:21 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.