How to populate the options of a select element in javascript
Asked Answered
U

7

47

The code:

var newSelect=document.createElement('select');
index=0;
var optn = document.createElement("option");

//langArray is an array that contains different items..the size
//is not fixed for this array.

for(element in langArray)
{
   //Now i want to assign each item in langArray to each option tag
   //will it be sumthng like "optn.options[index]=new Option("Sports", "sportsvalue", true,  false);
   //optn.accept(langArray[0]);
   index++;
}

I'm trying to get options populated by this way but its not coming all right as I don't know how to populate the options from an array in JS. Do I even have to use the loop or can I just assign the langArray to some property of select element and every thing will be up and running?

Universalism answered 6/7, 2011 at 18:13 Comment(1)
for(element in langArray) creates a global and is wide open for a bug, better to scope element to the block with const element. Top answer repeats this mistake.Shien
P
60

You can create the option inside the loop;

for(element in langArray)
{
   var opt = document.createElement("option");
   opt.value= index;
   opt.innerHTML = element; // whatever property it has

   // then append it to the select element
   newSelect.appendChild(opt);
   index++;
}

// then append the select to an element in the dom

2023 Update:

To make sure we avoid creating globals and remain in the correct scope, we can use map() and let.

let selectTag = document.createElement('select');
langArray.map( (lang, i) => {
    let opt = document.createElement("option");
    opt.value = i; // the index
    opt.innerHTML = lang;
    selectTag.append(opt);
});
Pantie answered 6/7, 2011 at 18:21 Comment(2)
Doing opt.innerHTML did not work for me, but doing something like option.appendChild(document.createTextNode(langArray[i].text)); like in James Long's answer did.Ecumenicalism
i also think that @James Long's answer is more explicit .Vespid
T
19

You need to create your option element inside your loop, set attributes and text and append it to the select element:

var select = document.createElement('select'),
    option,
    i = 0,
    il = langArray.length;

for (; i < il; i += 1) {
    option = document.createElement('option');
    option.setAttribute('value', langArray[i].value);
    option.appendChild(document.createTextNode(langArray[i].text));
    select.appendChild(option);
}

This assumes that your langArray looks something like this:

var langArray = [
    {value: "val1", text: "text 1"},
    {value: "val2", text: "text 2"}
];

You'll need to tweak the code to match your array

Tight answered 6/7, 2011 at 18:21 Comment(0)
S
19

2021 answer is here:

const select_elem = document.createElement('select');
langArray.forEach(d=> select_elem.add(new Option(d.display,d.value)));
Stedt answered 6/5, 2021 at 18:4 Comment(0)
B
7
    var dynamicSelect = document.getElementById("selectID");

        langArray.forEach(function(item){ 
        {
                var newOption = document.createElement("option");
                newOption.text = item.toString();//item.whateverProperty

                dynamicSelect.add(newOption);

                //new select items should populated immediately
        });
Bacardi answered 25/2, 2019 at 10:0 Comment(1)
Please add some explanation to that code such that others can learn from itLoathly
T
6

As a more 'up-to-date' method based on @Ibu's (currently accepted and perfectly valid) answer, you can use the forEach method in JavaScript, like so:

let select_elem = document.createElement('select');

langArray.forEach((element, index) => {
  let option_elem = document.createElement('option');
  
  // Add index to option_elem
  option_elem.value = index;
  
  // Add element HTML
  option_elem.textContent = element;
  
  // Append option_elem to select_elem
  select_elem.appendChild(option_elem);
});

Using a forEach method tracks its own index, meaning you don't need to have to manually track your index (using something like var i=0; [...] i++) and is - I would argue - neater and more maintainable than a for loop. After all, you don't need to create any variables outside of the loop, or manually increment those variables, and - consequently - there is less chance of conflicts if the index variable (say, var i) is used elsewhere (e.g. if you have a loop within a loop).

It should be noted that this recommendation comes in a context - there will ultimately be contexts when a for loop is a best choice, and when a forEach loop will be a best choice. As I personally prioritise maintainability over speed, I would by default opt for a forEach loop. But that's not to say that it is the correct or only correct answer. Always, always, ALWAYS consider your personal use requirements over the advice of anyone on the Internet.

I have also swapped innerHTML for textContent. Ultimately the content within the option is always going to be text (you can't add HTML to an option) so using textContent is more descriptive to what you are ultimately going to be doing. And textContent is more performant than innerHTML as it does not parse the data being fed in. In fact, a benchmark shows that just changing innerHTML to textContent can improve performance by over x2.5.

As such this is likely to be more performant and more maintainable for those reading your code in the future. In this instance, unlike with a for loop, I can see no benefit to not using textContent over innerHTML.

Performance

One thing to note is that for-in loops are more performant than forEach loops. Though this is somewhat trivial (especially given the context), and in my opinion you should always prioritise maintainability over mere speed... unless performance is a vital criteria for what you are making (like, for example, if you are iterating over 1000s of values regularly and are experiencing bottlenecks). As the old saying goes though, "premature optimisation is the root of all evil".

Ultimately, maintainers of JS will work to increase the performance of most-used constructs, and the performance hit will in most cases be negligible and will probably decrease over time as devices get more powerful, and parsers are ever-more optimised.

The performance of an application that cannot be readily maintained, however, can be very high indeed. And will only ever go up, as poor maintainability precedes more bugs being introduced over time. Shaving 0.002ms off a loop now is not going to have any noticeable impact going forwards. A future developer trying to add a <strong> tag to an <option> element because they read, innerHTML = ... and assumed they could add HTML will have an impact going forwards.

Side note for older browsers

The forEach method works in all evergreen browsers, but not in IE11 or below. For this, you will need to either polyfill or use a service like Babel to compile the code into a pre-ES6 format.

You may also need to change the let keyword to var for older browsers too. The let keyword does work in IE11, though it has a number of issues. If you do not require support for older browsers though, using the keywords let and const are great habits to get into.

Touter answered 29/9, 2019 at 19:4 Comment(0)
J
0

Another way to do this:

for (let i = 0; i < langArray.length; i++) {
    let opt = document.createElement("option");
    opt.value = langArray[i].id; //or i, depending on what you need to do
    opt.innerHTML = langArray[i].name; 
    $('#some-input').append(opt); //Chuck it into the dom here if you want
}
  1. For loop is often simpler to understand.
  2. Adding the option during the loop will avoid overwriting css styles that may be set at the "select" level of the HTML.
  3. Will be marginally slower.
Jamaaljamaica answered 29/9, 2019 at 18:32 Comment(1)
Why do you say that a for loop is simpler to understand than a for-in or forEach loop, and why is it marginally slower? And why are you using jQuery?Touter
L
0
function ShowMPXRegPopup() {
        $.ajax({
        type: "GET",
        url: "/City/Citylist",
        data: "{}",
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: function(response) {
            console.log(response);
            alert(response[0].cityName);
            var  templateString = '<table class=table><tr><th> City List</th></tr>'
            $.each(response, function (i) {
              templateString += '<tr><td><input type=select id='+ i+' name=rdokyctype onclick="showlistcity(\'' + response[i].cityName + '\')"/><label for='+i+'>' + response[i].cityName + '</label></td></tr>'
            })
            templateString += '</table>'
            $('#ddlcities').append(templateString)

            $('#exampleModal').modal('show');
           
        },
        error: function(response) {
            alert(response.responseText);
        }
    });
}
Locust answered 25/5 at 10:27 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Selfwill

© 2022 - 2024 — McMap. All rights reserved.