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 <
and >
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)?
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 <
and >
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)?
3 Answers
Reset to default 25Not 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);
Try this in your for loop instead:
var o = document.createElement('option');
o.setAttribute('value', response.data[i].id);
o.appendChild(document.createTextNode(response.data[i].name));
msgContainer.appendChild(o);
For those who need similar functionality, you can generate an html snippet using template literals and insert it using innerHTML
property. Plus you can set attributes and selected while iterating over the items:
const el = document.createElement('select');
el.innerHTML = ['John', 'Sally', 'Betty'].reduce((acc, prev, i) => {
if (i === 1) {
return acc + `<option selected>${prev}</option>`;
}
return acc + `<option>${prev}</option>`;
}, '');
const root = document.querySelector('#app');
root.appendChild(el);
In modern browsers this is faster than creating elements one by one imperatively.