I have a function that creates a li element with buttons. But when I call it via an eventListener, the element created in return was just a list without the innerHTML content.
What's happening and how do I fix that?
Here's my JS script:
const inputField = document.querySelector("input.inputField");
const addToList = document.querySelector("input.addToList");
const list = document.querySelector("div.list");
createTodo = () => {
var li = document.createElement("li");
let up = "<button class='up'>Up</button>";
li.innerHTML += up;
let down = "<button class='down'>Down</button>";
li.innerHTML += down;
let remove = "<button class='remove'>Remove</button>";
li.innerHTML += remove;
return li;
};
addToList.addEventListener("click", () => {
let todo = inputField.value;
var li = createTodo();
console.log(li);
li.textContent = todo;
list.appendChild(li);
inputField.value = "";
});
The problem is that you're destroying the existing element nodes in the li
when you do this:
li.textContent = todo;
What you could instead do is use .insertAdjacentText()
to append new text nodes without losing the element nodes.
li.insertAdjacentText("beforeend", todo);
Also, generally using +=
with .innerHTML
can cause problems. It's not too bad in your code, but there are better ways, for example using .insertAdjacentHTML()
.
And the multiple insertions seems more verbose than needed. I'd do this instead:
const createTodo = () => {
const li = document.createElement("li");
li.insertAdjacentHTML("beforeend", `
<button class='up'>Up</button>
<button class='down'>Down</button>
<button class='remove'>Remove</button>
`;
return li;
};
And then why not have your function receive the todo
text as an argument? You can then use string interpolation to make it really simple:
const inputField = document.querySelector("input.inputField");
const addToList = document.querySelector("input.addToList");
const list = document.querySelector("div.list");
const createTodo = (todo) => {
const li = document.createElement("li");
li.insertAdjacentHTML("beforeend", `
<button class='up'>Up</button>
<button class='down'>Down</button>
<button class='remove'>Remove</button>
${todo}
`;
return li;
};
addToList.addEventListener("click", () => {
list.appendChild(createTodo(inputField.value));
inputField.value = "";
});