Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding options to multiple Select elements

I have an HTML page, including a Form with multiple <select> elements. I know how to load the elements into a single <select>; here’s a piece of the code that works as I expect it to:

$(function() {
    google.script.run.withSuccessHandler(buildProjectList)
    .getProjects();
  });

  function buildProjectList(options) {
    var list = $('#projectList');
    list.empty();
    for (var i=0; i<options.length; i++) {
      list.append('<option value="' + options[i] + '">' + options[i] + '</option>');
    }
  }

It correctly gets a list of Projects, and adds the Options to the <select>.

Now what I am trying to do is add a list of options (all the same) to multiple <select> elements.

Here’s the code as I’ve written it:

$(function() {
    google.script.run.withSuccessHandler(buildDropDowns)
    .getDropDowns();
  });

function buildDropDowns(sizes) {
    var selections = document.getElementsByClassName('resourceSize');
    for(var i=0; i<selections.length; i++) {
      console.log(selection);
      for(var j= 0; j<sizes.length; j++) {
        selections[i].options.add(sizes[j], sizes[j]);
      }
    }
  }

function buildDropDowns(sizes) {
    var selections = document.getElementsByClassName('resourceSize');
    for(var i=0; i<selections.length; i++) {
      var selection = selections[i];
      console.log(selection);
      for(var j= 0; j<sizes.length; j++) {
        selection.options.add(sizes[j], sizes[j]);
      }
    }
  }

I’ve also tried it where I create a new variable for each element as it iterates through:

function buildDropDowns(sizes) {
  var selections = document.getElementsByClassName('resourceSize');
  for(var i=0; i<selections.length; i++) {
    var selection = selections[i];
    console.log(selection);
    for(var j= 0; j<sizes.length; j++) {
      selection.options.add(sizes[j], sizes[j]);
    }
  }
}

In either case, this is the error I’m getting in the console:

Uncaught TypeError: Failed to execute 'add' on 'HTMLOptionsCollection':
The provided value is not of type '(HTMLOptionElement or HTMLOptGroupElement)'

I’ve tried a couple different things based on some searching I’ve done, but no matter what I try, I’m getting the same error message. I’m assuming it has something to do with the difference between getElementById and getElementsByClassName. One returns the element itself, the other an array of elements. But I would think that I should be able to iterate through that array, and use the add function.

I can see that the iteration is working; here is what console.log(selection) shows as it cycles through each element:

<select id=​"busMerchPlan" name=​"busMerchPlan" class=​"resourceSize">​</select>
<select id=​"busMerchAlloc" name=​"busMerchAlloc" class=​"resourceSize">​</select>​
<select id=​"busMerchBuy" name=​"busMerchBuy" class=​"resourceSize">​</select>​
<select id=​"busMerchPDD" name=​"busMerchPDD" class=​"resourceSize">​</select>

Is there a way to iterate through the elements, and for each element, add each of the Options? Or do I need to use a getElementId statement for each of the elements I want to modify?

function buildDropDowns(sizes) {
  var list = $('#busMerchPlan');
  list.empty();
  for (var i=0; i<options.length; i++) {
    list.append('<option value="' + options[i] + '">' + options[i] + '</option>');
  }

  var list = $('#busMerchAlloc');
  list.empty();
  for (var i=0; i<options.length; i++) {
    list.append('<option value="' + options[i] + '">' + options[i] + '</option>');
  }

  var list = $('#busMerchBuy');
  list.empty();
  for (var i=0; i<options.length; i++) {
    list.append('<option value="' + options[i] + '">' + options[i] + '</option>');
  }

  var list = $('#busMerchPDD');
  list.empty();
  for (var i=0; i<options.length; i++) {
    list.append('<option value="' + options[i] + '">' + options[i] + '</option>');
  }
}

I can do that, but in the end, I'll have 20+ <select> elements, and there has to be a better way than brute force.

like image 380
Andrew Avatar asked Jun 21 '18 21:06

Andrew


People also ask

How do you allow multiple selections in select elements?

For windows: Hold down the control (ctrl) button to select multiple options. For Mac: Hold down the command button to select multiple options.

How do I append select options?

Method 1: Append the option tag to the select box The option to be added is created like a normal HTML string. The select box is selected with the jQuery selector and this option is added with the append() method. The append() method inserts the specified content as the last child of the jQuery collection.

How do I select multiple options in a dropdown?

To select multiple options in a drop-down list, use the multiple properties. It allows you to select more than one option while pressing CTRL key.

Which element is used to select multiple options?

The <select> element has some unique attributes you can use to control it, such as multiple to specify whether multiple options can be selected, and size to specify how many options should be shown at once.


2 Answers

Uncaught TypeError: Failed to execute 'add' on 'HTMLOptionsCollection': The provided value is not of type '(HTMLOptionElement or HTMLOptGroupElement)'

The error message suggests you add a value that's either a HTMLOptionElement or a HTMLOptGroupElement. So, you can write a function that creates such an element :

function createOption(option, label) {
      var option = document.createElement("option");
      option.setAttribute("value", option);
      option.innerHTML = label;

      return option;
}

And call it in your selections[i].options.add function.

function buildDropDowns(sizes) {
    var selections = document.getElementsByClassName('resourceSize');
    for(var i=0; i<selections.length; i++) {
      //console.log(selection);
      for(var j= 0; j<sizes.length; j++) {
        selections[i].options.add(createOption(sizes[j], sizes[j]));
      }
    }
}

function createOption(option, label) {
  var option = document.createElement("option");
  option.setAttribute("value", option);
  option.innerHTML = label;
  
  return option;
}
  
var sizes = ["XXL", "XL", "L", "M", "S", "XS"];

buildDropDowns(sizes);
<select id="busMerchPlan" name="busMerchPlan" class="resourceSize"></select>
<select id="busMerchAlloc" name="busMerchAlloc" class="resourceSize"></select>
<select id="busMerchBuy" name="busMerchBuy" class="resourceSize"></select>
<select id="busMerchPDD" name="busMerchPDD" class="resourceSize"></select>
like image 127
Guillaume Georges Avatar answered Sep 25 '22 01:09

Guillaume Georges


Or you just use the native code new Option( label [,value] )

A little more minimalistic approach (maybe easier to understand)

var selects = document.getElementsByClassName('resourceSize');
var sizes = ["XXL", "XL", "L", "M", "S", "XS"];

for( var i = 0; i < selects.length; i++ ) {
  for( var id in sizes ) {
    selects[i].options.add( new Option( sizes[id], id ));
  }
}
<select id="busMerchPlan" name="busMerchPlan" class="resourceSize"></select>
<select id="busMerchAlloc" name="busMerchAlloc" class="resourceSize"></select>
<select id="busMerchBuy" name="busMerchBuy" class="resourceSize"></select>
<select id="busMerchPDD" name="busMerchPDD" class="resourceSize"></select>
like image 22
SirPilan Avatar answered Sep 24 '22 01:09

SirPilan