295

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?

Jeff Putz
  • 14,504
  • 11
  • 41
  • 52

18 Answers18

507

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));
});
João Pimentel Ferreira
  • 14,289
  • 10
  • 80
  • 109
Jeff Putz
  • 14,504
  • 11
  • 41
  • 52
  • 5
    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 `` element instead of creating each one? – tedders Jan 10 '13 at 23:44
  • 2
    I don't think so... either way it's going to instantiate a new item. – quillbreaker Jan 31 '14 at 01:17
  • 9
    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. – Anders Mar 30 '15 at 09:58
  • 4
    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 – Wint Jul 02 '15 at 14:41
  • really it's more speed :) – Osama khodroj Feb 28 '16 at 14:43
  • This is the fastest method and so for my purposes, the best! Thank you. – David O'Regan Mar 08 '16 at 16:42
  • 1
    Sorry if get notifications and see nothing. I deleted my previous comments. Because I understood the answer more after reading my own comments :) – ivange Aug 21 '16 at 12:26
  • I'm not sure why this answer works. Andreas answer is easy to understand because I know what an `item` is. What is `this` in this context? – Dean P Jul 05 '22 at 14:46
  • @DeanP `item` is the item in the `result` array. – Jeff Putz Jul 05 '22 at 17:17
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

Andreas Grech
  • 105,982
  • 98
  • 297
  • 360
  • 1
    That's pretty close, and got me in the right direction. See my answer below. – Jeff Putz May 04 '09 at 03:20
  • 1
    Sweet! really helpful, I've been populating my dropdowns for a long time, and it always looked not professional – Kyle Sep 30 '15 at 14:37
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...

Community
  • 1
  • 1
Shog9
  • 156,901
  • 35
  • 231
  • 235
  • 1
    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. – yfeldblum May 02 '09 at 16:34
  • @Justice: you're right, but since Jeff's example omitted it, I did as well. Will add a note though, thanks. – Shog9 May 02 '09 at 16:41
  • 1
    I voted for the answer @Ricibald gave because oddly, based on [this test](http://jsperf.com/array-join-vs-string-connect) I came across, it turns out concatenation is faster than `join` in virtually every browser. – weir Jul 20 '12 at 15:34
  • 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. – thdoan Aug 10 '21 at 19:11
31

Or maybe:

var options = $("#options");
$.each(data, function() {
    options.append(new Option(this.text, this.value));
});
xinthink
  • 1,460
  • 1
  • 18
  • 22
  • 6
    var myOptions = { val1 : 'text1', val2 : 'text2' }; $.each(myOptions, function(val, text) { $('#mySelect').append( new Option(text,val) ); }); – The Demz Jul 22 '13 at 23:23
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.

Ricibald
  • 9,369
  • 7
  • 47
  • 62
  • 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 – Geomorillo Nov 15 '14 at 04:35
12

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));
  });
});
binshi
  • 1,248
  • 2
  • 17
  • 33
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.

Dapeng Li
  • 3,282
  • 1
  • 24
  • 18
  • 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);` – dgo Jan 14 '19 at 22:02
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));
    });
  })
Israel Perales
  • 2,192
  • 2
  • 25
  • 30
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));
        });
    });
});
2

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

$('#idofselect').ajaxAddOption('/Admin/GetFolderList/', {}, false);
Brian Yarger
  • 1,965
  • 18
  • 17
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];
            }
            });
sunil
  • 21
  • 1
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(""));
    });
}
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)
    );
});
}
Du-Lacoste
  • 11,530
  • 2
  • 71
  • 51
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

1

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)))
tash
  • 711
  • 5
  • 13
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>'");
}
Elim Garak
  • 1,728
  • 1
  • 16
  • 21
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"));
     }
});
Hang Yu
  • 11
  • 2
-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

Shyam
  • 1
  • 3