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().
Same as other answers, in jQuery fashion:
$.each(selectValues, function(key, value) {
$('#mySelect')
.append($("<option></option>")
.attr("value",key)
.text(value));
});
$("#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/… - Patrickvar mySelect = $("#mySelect") outside of the
each` loop. That would be much more efficient. See Carl's answer below - Patrickattr
and text
are actually methods of the $('<option/>')
-object - Blauhirn
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)
key
has some quotes or >, <
in it. - nickf
This is slightly faster and cleaner.
$.each(selectValues, function(key, value) {
$('#mySelect').append($("<option/>", {
value: key,
text: value
}));
});
var list = $("#selectList");
$.each(items, function(index, item) {
list.append(new Option(item.text, item.value));
});
var list = document.getElementById("selectList");
for(var i in items) {
list.add(new Option(items[i].text, items[i].value));
}
Option
object before. Is that built into all browsers? - Darryl Heinnew Option
, but found that it didn't work in IE6 & 7. I don't have a reason why, but many of the full jQuery options worked. - Darryl Heinnew Option('display', value, true)
- boatcoder
Using DOM Elements Creator plugin (my favorite):
$.create('option', {'value': 'val'}, 'myText').appendTo('#mySelect');
Using the Option
constructor (not sure about browser support):
$(new Option('myText', 'val')).appendTo('#mySelect');
Using document.createElement
(avoiding extra work parsing HTML with $("<option></option>")
):
$('#mySelect').append($(document.createElement("option")).
attr("value","val").text("myText"));
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(''));
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.
new Option(value, key);
? The parameter order is Options(text_visible_part, value_behind_the_scenes). - Bob Stein
@joshperry
It seems that plain .append also works as expected,
$("mySelect").append(
$.map(selectValues, function(v,k){
return $("<option>").val(k).text(v);
})
);
$.weakmap
to allow for GC
- Chef_Codemap()
construct, combined with the property of append()
to add an array of objects correctly! - Jochem Schulenklopper
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);
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
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.
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);
A compromise of sorts between the top two answers, in a "one-liner":
$.fn.append.apply($('mySelect'),
$.map(selectValues, function(val, idx) {
return $("<option/>")
.val(val.key)
.text(val.value);
})
);
Builds up an array of Option elements using map and then appends them all to the Select at once by using apply
to send each Option as a separate argument on the append
function.
The simple way is:
$('#SelectId').html("<option value='0'>select</option><option value='1'>Laguna</option>");
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: http://www.codecapers.com/post/Dynamic-Select-Lists-with-MVC-and-jQuery.aspx
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));
});
Yet another way of doing it:
var options = [];
$.each(selectValues, function(key, value) {
options.push($("<option/>", {
value: key,
text: value
}));
});
$('#mySelect').append(options);
$('#mySelect')
then refactored @rocktheroad answer... whatever, this is the more practical solution - Chef_Code
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.
$("#myselect").empty().append(opts);
with getElementById('myselect').innerHtml = opts;
- vahanpwns
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);
$.each
is slower than a for
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);
emp_id
? - Chris22
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');
You can just iterate over your json array with the following code
$('<option/>').attr("value","someValue").text("Option1").appendTo("#my-select-id");
A jQuery plugin could be found here: http://remysharp.com/2007/01/20/auto-populating-select-boxes-using-jquery-ajax/.
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));
};
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>
:
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);
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();
}
}
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
}
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(''));
$.each(selectValues, function(key, value) {
$('#mySelect').append($("<option/>", {
value: key, text: value
}));
});
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(''));
<!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>
value
is a string (and hard coded) it doesn't need to be quoted. - Darryl Hein