Revisiting Flatiron JavaScript Lab — Task Lister Lite
Now that I have a couple projects under my belt I decided to revisit an old vanilla JavaScript lab that I initially struggled with. The first challenge was understanding my code that I haven’t touched in awhile and deciphering my notes and bits and pieces of trials and errors.
I reorganized everything and made progress. It felt good to realize that I haven’t completely forgotten everything I learned in my time at Flatiron.
Then, the final challenge. The syntax needed to delete a specific list item from an unordered list based on the ‘click’ event of a button attached (appended) to that specific list item.
Note: That last sentence is a lot more detailed than my google search of “javascript remove 1 item from unordered list” that took some digging around to find a hint of the syntax I sought. Most of the search results were for deleting all of the list items instead of just one. Or, for deleting a list item by index.
Lesson learned: be more specific with google searches.
So, I ended up brushing up on the DOM to understand more on parent and child node relationships.
DOM
The Document Object Model is used to basically access the “document” object and modify it.
A pretty abstract concept that you can dive deeper into sometime but, I mainly want to focus on the nodes that make up the “DOM tree”.
You’ll also need to be somewhat familiar with basic HTML terminology because everything will be based on an HTML file (index.html) and the JavaScript written (in a .js file, of course) will build upon that HTML file using tags, ids, classes etc.
Keep in mind that everything between the opening and closing tag in HTML is an ‘element’.
ex: <label for="new-task-description">Task description:</label>
Nodes
There are 12 types of nodes. Remember, all items in the DOM are nodes.
So far I’ve only worked with element nodes and that is what I’ll be focusing on here.
Element nodes => HTML elements
ex: <h1>An element node</h1>
Fun fact: “the document itself is a ‘document’ node, the root of all other nodes”
This seems to explains the syntax of why most methods so far begin with ‘document’. We’re acting on the base document node to grab, alter and create elements within it.
DOM Tree & Relationships
Because each node is nested within another node we can map them into a tree.
Looking back at my index.html, I can map the element nodes like so:
Think of element nodes as being a parent, child and/or sibling node based on where they are in relation to each other.
Get Element By Id — method
So, when we want to access an element we’ll use the getElementById()
method to grab the whole line.
ex: document.getElementById("tasks");
To avoid repeatedly typing this whole line every time we want to access this element we can set it to a variable.
ex: const theList = document.getElementById("tasks");
Now, anytime I want to interact with this particular element I can just type “theList”.
It’s good practice to do this with every element you grab. Just in case. It also helps to make the code a bit easier to read by breaking it down into shorter lines.
Create Element — method
The syntax for creating a list element (li) and assigning it to a variable looks like:
const newTask = document.createElement('li');
You can follow this syntax for other HTML tags.
Append Child — method
The goal is for new list elements (li) to be created and added to the already established unordered list (ul) in the index.html file.
First, grab the ‘ul’ element so we can attach new ‘li’ elements to it.
const theList = document.getElementById('tasks');
*This will be the parent node.
Once you have access to an element(s) you can create new elements with JavaScript and later ‘attach’ them to the elements that already exist and/or were just created in the DOM.
This is very important. If you create new elements but they have nothing to attach onto they are not going to show up in the browser.
Next, create the ‘li’ element.
const newTask = document.createElement('li');
*This will be the child node.
The syntax for attaching (appending) a child node to a parent node looks like:
parentNode.appendChild(childNode);
Finally,
theList.appendChild(newTask);
Events
There are several types of events that you can read more about here:
I mainly use the EventTarget.addEventListener
method. It basically “listens” for an event that happens in the DOM, such as a “click” or “submit”, and will trigger a method(s).
This is where the fun happens!
MDN Web Docs says it “sets up a function that will be called whenever the specified event is delivered to the target. Common targets are Element, Document and Window, but the target may be any object that supports events”.
To reword this, the EventTarget
is the Element, Document or Window on which the EventListener
is called.
A button is the most common element that an EventListener
is added onto.
ex: btn.addEventListener('click', (e) => deleteTask(e));
One interesting thing that can happen here is that the ‘event’ can be passed as an object to functions activated by the EventTarget.addEventListener
method. In the prior example, I have it encompassed in “e” being passed to the deleteTask function (the callback function).
In the deleteTask function, I need to grab the specific list item (li) from an unordered list (ul) based on the ‘click’ event of a button attached (appended) to that specific list item in order to delete it.
The addEventListener
was called on the btn
element.
This means e.target
= that btn
element.
Node.parentElement
This was the syntax I was looking for to complete the final task for Task Lister Lite. This essentially returns the parent element of the node it is called on.
e.target.parentElement
= that very specific ‘li’ element attached to that btn
the EventListener
acted on.
Remove Child — method
Pretty similar syntax to the appendChild
method.
parentNode.removeChild(childNode);
Variable theList
that represents the ‘ul’ has already been defined and again will be the parentNode.
The ‘li’ I want to delete can be contained in a variable like so:
const selectedTask = e.target.parentElement;
And finally,
theList.removeChild(selectedTask);
Conclusion
Even though these are just the basics for the Task Lister Lite and I have yet to tackle the stretch deliverables, this was a good dive back into JavaScript. I explored nodes and events a little closer and definitely have a better understanding than when I first tackled this lab. Until the next task, thanks for reading!