297

The example I see posted all of the time seems like it's suboptimal, because it involves concatenating strings, which seems so not jQuery. It usually looks like this:

$.getJSON("/Admin/GetFolderList/", function(result) { for (var i = 0; i < result.length; i++) { options += '<option value="' + result[i].ImageFolderID + '">' + result[i].Name + '</option>'; } }); 

Is there a better way?

0

18 Answers 18

511

Andreas Grech was pretty close... it's actually this (note the reference to this instead of the item in the loop):

var $dropdown = $("#dropdown"); $.each(result, function() { $dropdown.append($("<option />").val(this.ImageFolderID).text(this.Name)); }); 
Sign up to request clarification or add additional context in comments.

9 Comments

Ancient history here I know, but for googlers like me who just stumbled on this now, wouldn't be even faster if you cloned an <option/> element instead of creating each one?
I don't think so... either way it's going to instantiate a new item.
Nice! Though I think the example might be clearer if the element was named "#dropdown" or so, since it better reflects the actual parent element of the options.
I think constructing all options in memory (with a string variable) first and then append this string to parent select control should be more efficient, because this will cause only once page layout
Sorry if get notifications and see nothing. I deleted my previous comments. Because I understood the answer more after reading my own comments :)
|
77
$.getJSON("/Admin/GetFolderList/", function(result) { var options = $("#options"); //don't forget error handling! $.each(result, function(item) { options.append($("<option />").val(item.ImageFolderID).text(item.Name)); }); }); 

What I'm doing above is creating a new <option> element and adding it to the options list (assuming options is the ID of a drop down element.

PS My javascript is a bit rusty so the syntax may not be perfect

2 Comments

That's pretty close, and got me in the right direction. See my answer below.
Sweet! really helpful, I've been populating my dropdowns for a long time, and it always looked not professional
42

Sure - make options an array of strings and use .join('') rather than += every time through the loop. Slight performance bump when dealing with large numbers of options...

var options = []; $.getJSON("/Admin/GetFolderList/", function(result) { for (var i = 0; i < result.length; i++) { options.push('<option value="', result[i].ImageFolderID, '">', result[i].Name, '</option>'); } $("#theSelect").html(options.join('')); }); 

Yes. I'm still working with strings the whole time. Believe it or not, that's the fastest way to build a DOM fragment... Now, if you have only a few options, it won't really matter - use the technique Dreas demonstrates if you like the style. But bear in mind, you're invoking the browser's internal HTML parser i*2 times, rather than just once, and modifying the DOM each time through the loop... with a sufficient number of options. you'll end up paying for it, especially on older browsers.

Note: As Justice points out, this will fall apart if ImageFolderID and Name are not encoded properly...

4 Comments

You should encode result[i].ImageFolderID and result[i].Name as html-attribute-value and html-text respectively. I would not assume they come from the server pre-encoded, since I would assume that the server returns json, not bastardized json.
@Justice: you're right, but since Jeff's example omitted it, I did as well. Will add a note though, thanks.
I voted for the answer @Ricibald gave because oddly, based on this test I came across, it turns out concatenation is faster than join in virtually every browser.
I try to avoid doing appends in a loop, so this is the best answer on this page. You can skip the join() if you assemble a string of options instead.
32

Or maybe:

var options = $("#options"); $.each(data, function() { options.append(new Option(this.text, this.value)); }); 

1 Comment

var myOptions = { val1 : 'text1', val2 : 'text2' }; $.each(myOptions, function(val, text) { $('#mySelect').append( new Option(text,val) ); });
20

The fastest way is this:

 $.getJSON("/Admin/GetFolderList/", function(result) { var optionsValues = '<select>'; $.each(result, function(item) { optionsValues += '<option value="' + item.ImageFolderID + '">' + item.Name + '</option>'; }); optionsValues += '</select>'; var options = $('#options'); options.replaceWith(optionsValues); }); 

According to this link is the fastest way because you wrap everything in a single element when doing any kind of DOM insertion.

1 Comment

however with replaceWith you replace the select in dom an lose the events already attached to the select i think it would be better with options.html(optionsValue) if you want to preserve events
14

I found this to be working from jquery site

$.getJSON( "/Admin/GetFolderList/", function( data ) { var options = $("#dropdownID"); $.each( data, function(key, val) { options.append(new Option(key, val)); }); }); 

1 Comment

This works very well, only exchange the positions of the Option parameters to Option(val, key) as the object expects the text to come first.
5

I've read that using document fragments is performant because it avoids page reflow upon each insertion of DOM element, it's also well supported by all browsers (even IE 6).

var fragment = document.createDocumentFragment(); $.each(result, function() { fragment.appendChild($("<option />").val(this.ImageFolderID).text(this.Name)[0]); }); $("#options").append(fragment);

I first read about this in CodeSchool's JavaScript Best Practices course.

Here's a comparison of different approaches, thanks go to the author.

1 Comment

This is definitely the speedy way. Even better - skip jQuery with this all together: result.forEach(function(el){var option=document.createElement('option').option.textContent=el.name;option.value=el.ImageFolderID);fragment.appendChild(el);
5

Other approach with ES6

fetch('https://restcountries.eu/rest/v1/all') .then((response) => { return response.json() }) .then((countries) => { var options = document.getElementById('someSelect'); countries.forEach((country) => { options.appendChild(new Option(country.name, country.name)); }); }) 

Comments

3

I hope it helps. I usually use functions instead write all code everytime.

 $("#action_selector").change(function () { ajaxObj = $.ajax({ url: 'YourURL', type: 'POST', // You can use GET data: 'parameter1=value1', dataType: "json", context: this, success: function (data) { json: data }, error: function (request) { $(".return-json").html("Some error!"); } }); json_obj = $.parseJSON(ajaxObj.responseText); var options = $("#selector"); options.empty(); options.append(new Option("-- Select --", 0)); $.each(ajx_obj, function () { options.append(new Option(this.text, this.value)); }); }); }); 

Comments

2

I use the selectboxes jquery plugin. It turns your example into:

$('#idofselect').ajaxAddOption('/Admin/GetFolderList/', {}, false); 

Comments

2
$.get(str, function(data){ var sary=data.split('|'); document.getElementById("select1").options.length = 0; document.getElementById("select1").options[0] = new Option('Select a State'); for(i=0;i<sary.length-1;i++){ document.getElementById("select1").options[i+1] = new Option(sary[i]); document.getElementById("select1").options[i+1].value = sary[i]; } }); 

Comments

2

For a newbie like me to JavaScript let alone JQuery, the more JavaScript way of doing it is:

result.forEach(d=>$("#dropdown").append(new Option(d,d))) 

Comments

1
function LoadCategories() { var data = []; var url = '@Url.Action("GetCategories", "InternalTables")'; $.getJSON(url, null, function (data) { data = $.map(data, function (item, a) { return "<option value=" + item.Value + ">" + item.Description + "</option>"; }); $("#ddlCategory").html('<option value="0">Select</option>'); $("#ddlCategory").append(data.join("")); }); } 

Comments

1
function generateYears() { $.ajax({ type: "GET", url: "getYears.do", data: "", dataType: "json", contentType: "application/json", success: function(msg) { populateYearsToSelectBox(msg); } }); } function populateYearsToSelectBox(msg) { var options = $("#selectYear"); $.each(msg.dataCollecton, function(val, text) { options.append( $('<option></option>').val(text).html(text) ); }); } 

Comments

1

here is an example i did on change i get children of the first select in second select

jQuery(document).ready(function($) { $('.your_select').change(function() { $.ajaxSetup({ headers:{'X-CSRF-TOKEN': $("meta[name='csrf-token']").attr('content')} }); $.ajax({ type:'POST', url: 'Link', data:{ 'id': $(this).val() }, success:function(r){ $.each(r, function(res) { console.log(r[res].Nom); $('.select_to_populate').append($("<option />").val(r[res].id).text(r[res].Nom)); }); },error:function(r) { alert('Error'); } }); }); 

});enter code here

Comments

0

I have been using jQuery and calling a function to populate drop downs.

function loadDropDowns(name,value) { var ddl = "#Categories"; $(ddl).append('<option value="' + value + '">' + name + "</option>'"); } 

Comments

0

Below is the Jquery way of populating a drop down list whose id is "FolderListDropDown"

$.getJSON("/Admin/GetFolderList/", function(result) { for (var i = 0; i < result.length; i++) { var elem = $("<option></option>"); elem.attr("value", result[i].ImageFolderID); elem.text(result[i].Name); elem.appendTo($("select#FolderListDropDown")); } }); 

Comments

-1

You can create options from SQL side (coalesce) and return as string and append that string to drop-down You can remove loop in the code. Ie, if you are using any back end like SQL server You can create options tag using coalesce Ie you will get a string containing entire option

Then you can return the entire string from back end and append to your drop-down

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.