Hi everyone,
I was working on a To-do list with vanilla JavaScript. I am trying to use an array of elements to update my to-do list. First, I make an array of tasks that I update with an “Add Task” button. Then I convert that array to another array of DOM List Elements. However, whenever I add a task, the array is still correct. However, the list is not updating on the page. So here is my code:
HTML
<!DOCTYPE html>
<html>
<head>
<title>Basic Web Page</title>
<meta name="viewport" content="width=device-width,initial-scale=1" >
<link href="style.css" rel="stylesheet">
</head>
<body>
<h1>Appending List Items</h1>
<div id="input-box">
<input name="task" type="text" id="task">
<button id="add-task-button">Add Task</button>
</div>
<div id="task-list-box">
<ul id='task-list'>
</ul>
</div>
<script src="script.js"></script>
</body>
</html>
JavaScript
const taskList = document.getElementById('task-list');
const addTaskButton = document.getElementById('add-task-button');
class Task {
constructor(id, taskString) {
this.id = id;
this.taskString = taskString;
}
}
const task1 = new Task(1, "Test Task 1")
let taskListArray = [task1];
function addTask(event) {
let task = document.getElementById('task');
let id;
if (taskListArray.length < 1) {
id = 1;
} else {
id = taskListArray[taskListArray.length-1].id + 1;
}
let NewTask = new Task(id, task.value);
taskListArray.push(NewTask);
console.log(taskListArray);
}
addTaskButton.addEventListener("click", addTask);
const taskListNodes = taskListArray.map(function(task) {
const newTask = document.createElement('li');
newTask.textContent = `${task.taskString}`;
return newTask;
});
taskListNodes.forEach(function(taskNode) {
taskList.appendChild(taskNode);
});
I am wondering why the .map() and .forEach methods are not updating my webpage. Any help would be appreciated.
You did not add the li elements inside of the function you are using for the event listener, addTask
.
Inside of the addTask
function,
at the end of it,
you could put
const taskListNodes = taskListArray.map(function(task) {
const newTask = document.createElement('li');
newTask.textContent = `${task.taskString}`;
return newTask;
});
taskList.innerHTML = "\n"; // deletes all the li elements
taskListNodes.forEach(function(taskNode) { // adds the li elements from the array
taskList.appendChild(taskNode);
});
so that the li elements are erased, created, and added from the array appropriately each time the button is clicked.
I prefer an approach where you deal with one item at a time, instead of an array:
The entire JavaScript file would be
const taskList = document.getElementById('task-list');
const addTaskButton = document.getElementById('add-task-button');
const task = document.getElementById('task');
const tasks = []; // array of strings
function addTask() {
const taskString = task.value;
const newTask = document.createElement('li');
newTask.textContent = taskString;
taskList.appendChild(newTask);
tasks.push(taskString);
}
addTaskButton.addEventListener("click", addTask);
Awesome!
It worked. Thank you for your suggestion.
I was thinking about encoding some of the information in an array so I could eventually remove the element from being displayed.