What is the best way to add options to a select from a JavaScript object with jQuery?
Asked Answered
R

37

1491

What is the best method for adding options to a <select> from a JavaScript object using jQuery?

I'm looking for something that I don't need a plugin to do, but I would also be interested in the plugins that are out there.

This is what I did:

selectValues = { "1": "test 1", "2": "test 2" };

for (key in selectValues) {
  if (typeof (selectValues[key] == 'string') {
    $('#mySelect').append('<option value="' + key + '">' + selectValues[key] + '</option>');
  }
}

A clean/simple solution:

This is a cleaned up and simplified version of matdumsa's:

$.each(selectValues, function(key, value) {
     $('#mySelect')
          .append($('<option>', { value : key })
          .text(value));
});

Changes from matdumsa's: (1) removed the close tag for the option inside append() and (2) moved the properties/attributes into an map as the second parameter of append().

Rate answered 4/10, 2008 at 20:58 Comment(6)
maybe of help: texotela.co.uk/code/jquery/select (it was a help for me after i stumbled upon this question)Mathematical
The cleaned up version listed above only works in Jquery 1.4+. For older versions use the one in matdumsa's answerRabbinate
{ value : key } should be { "value" : key } as seen in matdumsa's answer.Smolt
I don't believe so since value is a string (and hard coded) it doesn't need to be quoted.Rate
may be this would help you - kvcodes.com/2016/10/…Sphalerite
The title should be instead "What is the best way to add options to a select from a JSON object whith jQuery?Richellericher
A
1485

The same as other answers, in a jQuery fashion:

$.each(selectValues, function(key, value) {   
     $('#mySelect')
         .append($("<option></option>")
                    .attr("value", key)
                    .text(value)); 
});
Alvira answered 4/10, 2008 at 21:12 Comment(1)
I would first of all assign $("#mySelect") to a var, otherwise calling $("#mySelect") every time inside the loop is very wasteful, as is updating the DOM. See points #3 and #6 at artzstudio.com/2009/04/jquery-performance-rules/…Afroasian
F
296
var output = [];

$.each(selectValues, function(key, value)
{
  output.push('<option value="'+ key +'">'+ value +'</option>');
});

$('#mySelect').html(output.join(''));

In this way you "touch the DOM" only one time.

I'm not sure if the latest line can be converted into $('#mySelect').html(output.join('')) because I don't know jQuery internals (maybe it does some parsing in the html() method)

Fluellen answered 5/11, 2009 at 19:42 Comment(2)
You method is obviously the faster one than the 'correct' answer above since it uses less jQuery too.Illiquid
This breaks if the key has some quotes or >, < in it.Fronniah
H
216

This is slightly faster and cleaner.

var selectValues = {
  "1": "test 1",
  "2": "test 2"
};
var $mySelect = $('#mySelect');
//
$.each(selectValues, function(key, value) {
  var $option = $("<option/>", {
    value: key,
    text: value
  });
  $mySelect.append($option);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="mySelect"></select>
Hemichordate answered 1/7, 2010 at 7:0 Comment(1)
It think it will be a better idea to cache ` $('#mySelect')` , so that you look up only once before the loop. Currently it is searching the DOM for the element for every single option .Cloakroom
L
114

jQuery

var list = $("#selectList");
$.each(items, function(index, item) {
  list.append(new Option(item.text, item.value));
});

Vanilla JavaScript

var list = document.getElementById("selectList");
for(var i in items) {
  list.add(new Option(items[i].text, items[i].value));
}
Layout answered 31/5, 2011 at 22:52 Comment(0)
I
41

If you don't have to support old IE versions, using the Option constructor is clearly the way to go, a readable and efficient solution:

$(new Option('myText', 'val')).appendTo('#mySelect');

It's equivalent in functionality to, but cleaner than:

$("<option></option>").attr("value", "val").text("myText")).appendTo('#mySelect');
Incorporated answered 5/10, 2008 at 15:49 Comment(0)
H
33

This looks nicer, provides readability, but is slower than other methods.

$.each(selectData, function(i, option)
{
    $("<option/>").val(option.id).text(option.title).appendTo("#selectBox");
});

If you want speed, the fastest (tested!) way is this, using array, not string concatenation, and using only one append call.

auxArr = [];
$.each(selectData, function(i, option)
{
    auxArr[i] = "<option value='" + option.id + "'>" + option.title + "</option>";
});

$('#selectBox').append(auxArr.join(''));
Herv answered 21/12, 2009 at 15:50 Comment(0)
P
25

A refinement of older @joshperry's answer:

It seems that plain .append also works as expected,

$("#mySelect").append(
  $.map(selectValues, function(v,k){

    return $("<option>").val(k).text(v);
  })
);

or shorter,

$("#mySelect").append(
  $.map(selectValues, (v,k) => $("<option>").val(k).text(v))
  // $.map(selectValues, (v,k) => new Option(v, k)) // using plain JS
);
Pleasure answered 17/4, 2013 at 11:29 Comment(0)
B
22

All of these answers seem unnecessarily complicated. All you need is:

var options = $('#mySelect').get(0).options;
$.each(selectValues, function(key, value) {
        options[options.length] = new Option(value, key);
});

That is completely cross browser compatible.

Burge answered 11/10, 2013 at 17:20 Comment(0)
I
20
 var output = [];
 var length = data.length;
 for(var i = 0; i < length; i++)
 {
    output[i++] = '<option value="' + data[i].start + '">' + data[i].start + '</option>';
 }

 $('#choose_schedule').get(0).innerHTML = output.join('');

I've done a few tests and this, I believe, does the job the fastest. :P

Illiquid answered 9/11, 2009 at 6:29 Comment(0)
P
20

Be forwarned... I am using jQuery Mobile 1.0b2 with PhoneGap 1.0.0 on an Android 2.2 (Cyanogen 7.0.1) phone (T-Mobile G2) and could not get the .append() method to work at all. I had to use .html() like follows:

var options;
$.each(data, function(index, object) {
    options += '<option value="' + object.id + '">' + object.stop + '</option>';
});

$('#selectMenu').html(options);
Prose answered 16/9, 2011 at 13:22 Comment(0)
M
17

There's an approach using the Microsoft Templating approach that's currently under proposal for inclusion into jQuery core. There's more power in using the templating so for the simplest scenario it may not be the best option. For more details see Scott Gu's post outlining the features.

First include the templating js file, available from github.

<script src="Scripts/jquery.tmpl.js" type="text/javascript" />

Next set-up a template

<script id="templateOptionItem" type="text/html">
    <option value=\'{{= Value}}\'>{{= Text}}</option>
</script>

Then with your data call the .render() method

var someData = [
    { Text: "one", Value: "1" },
    { Text: "two", Value: "2" },
    { Text: "three", Value: "3"}];

$("#templateOptionItem").render(someData).appendTo("#mySelect");

I've blogged this approach in more detail.

Magill answered 8/7, 2010 at 5:0 Comment(0)
Q
15

I have made something like this, loading a dropdown item via Ajax. The response above is also acceptable, but it is always good to have as little DOM modification as as possible for better performance.

So rather than add each item inside a loop it is better to collect items within a loop and append it once it's completed.

$(data).each(function(){
    ... Collect items
})

Append it,

$('#select_id').append(items); 

or even better

$('#select_id').html(items);
Quartering answered 5/10, 2008 at 4:52 Comment(0)
A
12
function populateDropdown(select, data) {   
    select.html('');   
    $.each(data, function(id, option) {   
        select.append($('<option></option>').val(option.value).html(option.name));   
    });          
}   

It works well with jQuery 1.4.1.

For complete article for using dynamic lists with ASP.NET MVC & jQuery visit:

Dynamic Select Lists with MVC and jQuery

Almund answered 5/2, 2010 at 11:56 Comment(0)
H
12

The simple way is:

$('#SelectId').html("<option value='0'>select</option><option value='1'>Laguna</option>");
Headrace answered 25/3, 2010 at 15:4 Comment(0)
M
12

Most of the other answers use the each function to iterate over the selectValues. This requires that append be called into for each element and a reflow gets triggered when each is added individually.

Updating this answer to a more idiomatic functional method (using modern JS) can be formed to call append only once, with an array of option elements created using map and an Option element constructor.

Using an Option DOM element should reduce function call overhead as the option element doesn't need to be updated after creation and jQuery's parsing logic need not run.

$('mySelect').append($.map(selectValues, (k, v) => new Option(k, v)))

This can be simplified further if you make a factory utility function that will new up an option object:

const newoption = (...args) => new Option(...args)

Then this can be provided directly to map:

$('mySelect').append($.map(selectValues, newoption))

Previous Formulation

Because append also allows passing values as a variable number of arguments, we can precreate the list of option elements map and append them as arguments in a single call by using apply.

$.fn.append.apply($('mySelect'), $.map(selectValues, (k, v) => $("<option/>").val(k).text(v)));

It looks like that in later versions of jQuery, append also accepts an array argument and this can be simplified somewhat:

$('mySelect').append($.map(selectValues, (k, v) => $("<option/>").val(k).text(v)))
Murchison answered 1/10, 2010 at 17:22 Comment(0)
H
10

There's a sorting problem with this solution in Chrome (jQuery 1.7.1) (Chrome sorts object properties by name/number?) So to keep the order (yes, it's object abusing), I changed this:

optionValues0 = {"4321": "option 1", "1234": "option 2"};

to this

optionValues0 = {"1": {id: "4321", value: "option 1"}, "2": {id: "1234", value: "option 2"}};

and then the $.each will look like:

$.each(optionValues0, function(order, object) {
  key = object.id;
  value = object.value;
  $('#mySelect').append($('<option>', { value : key }).text(value));
}); 
Hiero answered 21/9, 2012 at 9:27 Comment(0)
O
9

Rather than repeating the same code everywhere, I would suggest it is more desirable to write your own jQuery function like:

jQuery.fn.addOption = function (key, value) {
    $(this).append($('<option>', { value: key }).text(value));
};

Then to add an option just do the following:

$('select').addOption('0', 'None');
Olva answered 3/2, 2016 at 16:21 Comment(0)
R
8

You can just iterate over your json array with the following code

$('<option/>').attr("value","someValue").text("Option1").appendTo("#my-select-id");

Rizzio answered 21/7, 2010 at 16:14 Comment(0)
M
8
  1. $.each is slower than a for loop
  2. Each time, a DOM selection is not the best practice in loop $("#mySelect").append();

So the best solution is the following

If JSON data resp is

[
    {"id":"0001", "name":"Mr. P"},
    {"id":"0003", "name":"Mr. Q"},
    {"id":"0054", "name":"Mr. R"},
    {"id":"0061", "name":"Mr. S"}
]

use it as

var option = "";
for (i=0; i<resp.length; i++) {
    option += "<option value='" + resp[i].id + "'>" + resp[i].name + "</option>";
}
$('#mySelect').html(option);
Moen answered 8/9, 2014 at 8:47 Comment(0)
E
7

A jQuery plugin could be found here: Auto-populating Select Boxes using jQuery & AJAX.

Entrant answered 24/12, 2010 at 16:23 Comment(0)
H
7

That's what I did with two-dimensional arrays: The first column is item i, add to innerHTML of the <option>. The second column is record_id i, add to the value of the <option>:

  1. PHP

    $items = $dal->get_new_items(); // Gets data from the database
    $items_arr = array();
    $i = 0;
    foreach ($items as $item)
    {
        $first_name = $item->first_name;
        $last_name = $item->last_name;
        $date = $item->date;
        $show = $first_name . " " . $last_name . ", " . $date;
        $request_id = $request->request_id;
        $items_arr[0][$i] = $show;
        $items_arr[1][$i] = $request_id;
        $i++;
    }
    
    echo json_encode($items_arr);
    
  2. JavaScript/Ajax

            function ddl_items() {
                if (window.XMLHttpRequest) {
                    // Code for Internet Explorer 7+, Firefox, Chrome, Opera, and Safari
                    xmlhttp=new XMLHttpRequest();
                }
                else{
                    // Code for Internet Explorer 6 and Internet Explorer 5
                    xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
                }
    
                xmlhttp.onreadystatechange=function() {
                if (xmlhttp.readyState==4 && xmlhttp.status==200) {
                    var arr = JSON.parse(xmlhttp.responseText);
                    var lstbx = document.getElementById('my_listbox');
    
                    for (var i=0; i<arr.length; i++) {
                        var option = new Option(arr[0][i], arr[1][i]);
                        lstbx.options.add(option);
                    }
                }
            };
    
            xmlhttp.open("GET", "Code/get_items.php?dummy_time=" + new Date().getTime() + "", true);
            xmlhttp.send();
        }
    }
    
Handmaid answered 9/8, 2012 at 19:8 Comment(0)
F
7

Although the previous answers are all valid answers - it might be advisable to append all these to a documentFragmnet first, then append that document fragment as an element after...

See John Resig's thoughts on the matter...

Something along the lines of:

var frag = document.createDocumentFragment();

for(item in data.Events)
{
    var option = document.createElement("option");

    option.setAttribute("value", data.Events[item].Key);
    option.innerText = data.Events[item].Value;

    frag.appendChild(option);
}
eventDrop.empty();
eventDrop.append(frag);
Filippo answered 26/11, 2012 at 16:38 Comment(0)
E
7

Yet another way of doing it:

var options = [];    
$.each(selectValues, function(key, value) {
    options.push($("<option/>", {
        value: key,
        text: value
    }));
});
$('#mySelect').append(options);
Ermelindaermengarde answered 25/4, 2013 at 21:59 Comment(1)
I see what you did here... You took the advice to cache $('#mySelect') then refactored @rocktheroad answer... whatever, this is the more practical solutionSpume
C
7
if (data.length != 0) {
    var opts = "";
    for (i in data)
        opts += "<option value='"+data[i][value]+"'>"+data[i][text]+"</option>";

    $("#myselect").empty().append(opts);
}

This manipulates the DOM only once after first building a giant string.

Chariot answered 2/10, 2013 at 17:16 Comment(1)
you can optimise this further and avoid the use of jQuery altogether by replacing $("#myselect").empty().append(opts); with getElementById('myselect').innerHtml = opts;Tripalmitin
C
6

I found that this is simple and works great.

for (var i = 0; i < array.length; i++) {
    $('#clientsList').append($("<option></option>").text(array[i].ClientName).val(array[i].ID));
};
Cannell answered 6/8, 2012 at 17:47 Comment(0)
T
5

The JSON format:

[{
    "org_name": "Asset Management"
}, {
    "org_name": "Debt Equity Foreign services"
}, {
    "org_name": "Credit Services"
}]

And the jQuery code to populate the values to the Dropdown on Ajax success:

success: function(json) {
    var options = [];
    $('#org_category').html('');  // Set the Dropdown as Blank before new Data
    options.push('<option>-- Select Category --</option>');
    $.each(JSON.parse(json), function(i, item) {
        options.push($('<option/>',
        {
           value: item.org_name, text: item.org_name
        }));
    });
    $('#org_category').append(options);  // Set the Values to Dropdown
}
Trimetric answered 30/7, 2016 at 10:43 Comment(0)
R
4

Using the $.map() function, you can do this in a more elegant way:

$('#mySelect').html( $.map(selectValues, function(val, key){
    return '<option value="' + val + '">'+ key + '</option>';
}).join(''));
Richellericher answered 10/7, 2017 at 18:24 Comment(1)
That is kind of shorter, but the one problem is dealing with escaping of the val and key vars which the accepted answer does do.Rate
K
3
<!DOCTYPE html>
<html lang="en">
<head>
  <title>append selectbox using jquery</title>
  <meta charset="utf-8">
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>

  <script type="text/javascript">
    function setprice(){
        var selectValues = { "1": "test 1", "2": "test 2" };
        $.each(selectValues, function(key, value) {   
     $('#mySelect')
         .append($("<option></option>")
                    .attr("value",key)
                    .text(value)); 
});

    }
  </script>
</head>
<body onload="setprice();">


      <select class="form-control" id="mySelect">
    <option>1</option>
    <option>2</option>
    <option>3</option>
    <option>4</option>
  </select>


</body>
</html>
Kinnard answered 29/3, 2018 at 16:3 Comment(0)
I
3
 $.each(response, function (index,value) {
                        $('#unit')
                            .append($("<option></option>")
                                .attr("value", value.id)
                                .text(value.title));
                    });
Inconsiderable answered 22/10, 2021 at 5:44 Comment(0)
P
2

I combine the two best answers into a great answer.

var outputConcatenation = [];

$.each(selectValues, function(i, item) {   
     outputConcatenation.push($("<option></option>").attr("value", item.key).attr("data-customdata", item.customdata).text(item.text).prop("outerHTML"));
});

$("#myselect").html(outputConcatenation.join(''));
Polak answered 8/10, 2015 at 3:6 Comment(0)
L
2
$.each(selectValues, function(key, value) {
    $('#mySelect').append($("<option/>", {
        value: key, text: value
    }));
});
Legionary answered 30/10, 2017 at 13:27 Comment(0)
C
2

Set your HTML select id into following line below. In here mySelect is used as the id of the select element.

   var options = $("#mySelect");

then get the object which is the selectValues in this scenario and sets it to the jquery for each loop. It will use the value and text of the objects accordingly and appends it into the option selections as follows.

$.each(selectValues, function(val, text) {
            options.append(
             $('<option></option>').val(val).html(text)
          );
      });

This will display text as the option list when drop down list is selected and once a text is selected value of the selected text will be used.

Eg.

"1": "test 1", "2": "test 2",

Dropdown,

display name: test 1 -> value is 1 display name: test 2 -> value is 2

Christopherchristopherso answered 11/4, 2018 at 5:35 Comment(1)
please describe a bit about the solution.Inellineloquent
V
2

Actually, for getting the improved performance, it's better to make option list separately and append to select id.

var options = [];
$.each(selectValues, function(key, value) {
    options.push ($('<option>', { value : key })
          .text(value));
});
 $('#mySelect').append(options);

http://learn.jquery.com/performance/append-outside-loop/

Vitreous answered 6/9, 2018 at 5:20 Comment(0)
D
2

Pure JS

In pure JS adding next option to select is easier and more direct

mySelect.innerHTML+= `<option value="${key}">${value}</option>`;

let selectValues = { "1": "test 1", "2": "test 2" };

for(let key in selectValues) { 
  mySelect.innerHTML+= `<option value="${key}">${selectValues[key]}</option>`;
}
<select id="mySelect">
  <option value="0" selected="selected">test 0</option>
</select>
Derogate answered 25/8, 2020 at 20:9 Comment(0)
S
1

I decided to chime in a bit.

  1. Deal with prior selected option; some browsers mess up when we append
  2. ONLY hit DOM once with the append
  3. Deal with multiple property while adding more options
  4. Show how to use an object
  5. Show how to map using an array of objects

// objects as value/desc
let selectValues = {
  "1": "test 1",
  "2": "test 2",
  "3": "test 3",
  "4": "test Four"
};
//use div here as using "select" mucks up the original selected value in "mySelect"
let opts = $("<div />");
let opt = {};
$.each(selectValues, function(value, desc) {
  opts.append($('<option />').prop("value", value).text(desc));
});
opts.find("option").appendTo('#mySelect');

// array of objects called "options" in an object
let selectValuesNew = {
  options: [{
      value: "1",
      description: "2test 1"
    },
    {
      value: "2",
      description: "2test 2",
      selected: true
    },
    {
      value: "3",
      description: "2test 3"
    },
    {
      value: "4",
      description: "2test Four"
    }
  ]
};

//use div here as using "select" mucks up the original selected value
let opts2 = $("<div />");
let opt2 = {}; //only append after adding all options
$.map(selectValuesNew.options, function(val, index) {
  opts2.append($('<option />')
    .prop("value", val.value)
    .prop("selected", val.selected)
    .text(val.description));
});
opts2.find("option").appendTo('#mySelectNew');
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<select id="mySelect">
  <option value="" selected="selected">empty</option>
</select>

<select id="mySelectNew" multiple="multiple">
  <option value="" selected="selected">2empty</option>
</select>
Slough answered 6/8, 2018 at 14:9 Comment(0)
V
1

Since JQuery's append can take an array as an argument, I'm surprised nobody suggested making this a one-liner with map

$('#the_select').append(['a','b','c'].map(x => $('<option>').text(x)));

or reduce

['a','b','c'].reduce((s,x) => s.append($('<option>').text(x)), $('#the_select'));
Vile answered 17/1, 2019 at 20:15 Comment(0)
E
1

Getting the object keys to get the object values. Using map() to add new Options.

const selectValues = {
  "1": "test 1",
  "2": "test 2"
}
const selectTest = document.getElementById('selectTest')
Object.keys(selectValues).map(key => selectTest.add(new Option(selectValues[key], key)))
<select id="selectTest"></select>
Erection answered 27/2, 2020 at 11:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.