Search code examples
javascripthtmlgetelementbyidappendchild

Javascript - efficiently insert multiple HTML elements


I'd like to create a select element with a list of a user's Facebook friends (obtained as a JSON object). I hardcode <select id="friends"></select> into my HTML, then use the following Javascript code to parse the JSON and insert each friend as an option of the select element:

var msgContainer = document.createDocumentFragment();
for (var i = 0; i < response.data.length; i++) { 
    msgContainer.appendChild(document.createTextNode('<option value="'+response.data[i].id+'">'+response.data[i].name+'</option>'));    
}
document.getElementById("friends").appendChild(msgContainer);

This almost works, except that it inserts &lt; and &gt; instead of < and >. How can I fix it, and is there a more efficient way to insert multiple HTML elements using pure Javascript (not JQuery)?


Solution

  • Not sure why you're creating a text node, but it would seem that you want to create option elements, so you could use the Option constructor instead.

    var msgContainer = document.createDocumentFragment();
    
    for (var i = 0; i < response.data.length; i++) { 
        msgContainer.appendChild(new Option(response.data[i].name, response.data[i].id));
    }
    document.getElementById("friends").appendChild(msgContainer);
    

    Or you can use the generic document.createElement().

    var msgContainer = document.createDocumentFragment();
    
    for (var i = 0; i < response.data.length; i++) {
        var option = msgContainer.appendChild(document.createElement("option"));
        option.text = response.data[i].name;
        option.value = response.data[i].id;
    }
    document.getElementById("friends").appendChild(msgContainer);
    

    It's nice to have a helper function for creating elements and setting properties at the same time.

    Here's a simple example of one:

    function create(name, props) {
        var el = document.createElement(name);
        for (var p in props)
            el[p] = props[p];
        return el;
    }
    

    It can be expanded to cover some specific needs, but this will work for most cases.

    You'd use it like this:

    var msgContainer = document.createDocumentFragment();
    
    for (var i = 0; i < response.data.length; i++) {
        msgContainer.appendChild(create("option", {
            text: response.data[i].name,
            value: response.data[i].id
        }));
    }
    document.getElementById("friends").appendChild(msgContainer);