Created
January 30, 2021 12:48
-
-
Save thepassle/dbaa29eac687bcefb4889a73483839ec to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<body> | |
<form id="todoInput"> | |
<input type="text" name="todo"></input> | |
<button type="submit">submit</button> | |
</form> | |
<ul id="todoList"> | |
</ul> | |
<script> | |
// This will be a placeholder to store our todos, this is a `let` variable because a user might delete a todo | |
let todos = []; | |
// We need to keep track of an index for our todos, so we know which one to delete | |
let id = 0; | |
// Get a reference to the <form> element | |
const form = document.getElementById("todoInput"); | |
// Get a reference to the todoList <ul> | |
const todoList = document.getElementById("todoList"); | |
// This function will construct the HTML that we want to 'render' in our unordered list | |
// This is its own function because we'll need to reuse it multiple times | |
function constructListHTML() { | |
let todolistHtml = ''; | |
todos.forEach(todoItem => { | |
todolistHtml += ` | |
<li> | |
<input type="checkbox"></input> | |
<span>${todoItem.value}</span> | |
<button id="${todoItem.id}">❌</button> | |
</li> | |
`; | |
}); | |
return todolistHtml; | |
} | |
/** | |
* We add an eventListener (a creeper) to the form event so that whenever the form has been | |
* 'submitted', we can execute some JavaScript. In this case, we want to construct a new | |
* todo object with a `value` and an `id`. | |
* | |
* Then we want to construct the HTML we need to render the list, and set the todoList's | |
* innerHTML value to the list we want to render. | |
*/ | |
form.addEventListener("submit", (event) => { | |
event.preventDefault(); | |
todos.push({ | |
value: event.target.elements["todo"].value, | |
id: id | |
}); | |
todoList.innerHTML = constructListHTML(); | |
// Finally, dont forget to increment the ID so it'll always be unique :) | |
id++; | |
}); | |
/** | |
* Here we add a click event listener to the unordered list. The unordered list by itself is not | |
* an interactive element, but we use a clever trick called 'event delegation'. | |
* | |
* The unordered list element will listen to any click events from any of its children. In this | |
* case, we're only interested in HTML tags that are <button>s. | |
*/ | |
todoList.addEventListener("click", (event) => { | |
if(event.target.tagName === 'BUTTON') { | |
// If we know the click event came from a button, we want to get its ID, and make sure we parse it as an integer! | |
const id = parseInt(event.target.id); | |
// Then we want to _filter_ out the todoItem with the `id`, this essentially creates a new array | |
// and assigns it to our `todos` variable, but the item we want to delete has been removed from it. | |
todos = todos.filter(todoItem => { | |
return todoItem.id !== id; | |
}); | |
// And finally, we want to reconstruct our HTML again, and 'render' it. | |
todoList.innerHTML = constructListHTML(); | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment