I like the ToDo App project in JavaScript. I’ve been working on my laptop that is hooked up to Tommy’s computer monitor and keyboard. It’s not bad, I do like the setup over here. I’m wondering if I should put in an email to FreeCodeCamp about how glitchy their site is on Safari. Maybe I will Google it to see if this is a common problem. I can download Chrome onto my Mac to see if this solves the problem. But I did pretty well today. At least I think I did.
I finally changed the auto-lock time on my phone to 5 minutes. I had it at one minute. However, I did find out that when put in power-saving mode, auto-lock only stays on for 30 seconds. That was proving to be annoying for me.
Again, I don’t have much to say. I’m glad it’s the end of Friday and we are now in the weekend. No, I don’t have plans this weekend. Next Friday, we are picking up Alexis from school for her Spring Break. She called me today to make sure we are coming to pick her up for Spring Break. I rode the bike and did yoga today. I’m getting pretty good at doing this every other day. Even when I don’t feel like exercising. Well, I’m going to get off the computer and read for a bit.
Normally I post this to Facebook from the computer but I’m not signed into my Facebook on my laptop. And my computer is off right now. I guess I will use my phone. Lol
JavaScript notes…
——————————–
Project Todo App Steps 1 – 25
Step 1
In this project, you will learn how localStorage works in JavaScript by building a Todo app. LocalStorage is a web storage feature of JavaScript that lets you persist data by storing the data as a key:value pair.
The HTML and CSS for this project have been provided for you. Take a look at the files to get yourself familiarized with them.
Begin by accessing the task-form, confirm-close-dialog, and open-task-form-btn elements with the getElementById() method. Save them in the variables taskForm, confirmCloseDialog, and openTaskFormBtn.
const taskForm = document.getElementById('task-form'); const confirmCloseDialog = document.getElementById('confirm-close-dialog'); const openTaskFormBtn = document.getElementById('open-task-form-btn');
Step 2
You need to access more elements with the getElementById() method. This time you need the close-task-form-btn, add-or-update-task-btn, and cancel-btn elements. Save them in the variables closeTaskFormBtn, addOrUpdateTaskBtn, and cancelBtn.
const closeTaskFormBtn = document.getElementById('close-task-form-btn'); const addOrUpdateTaskBtn = document.getElementById('add-or-update-task-btn'); const cancelBtn = document.getElementById('cancel-btn');
Step 3
Next, access the discard-btn, tasks-container, and title-input elements using the getElementById() method. Save them in variables named discardBtn, tasksContainer, and titleInput, respectively.
const discardBtn = document.getElementById('discard-btn'); const tasksContainer = document.getElementById('tasks-container'); const titleInput = document.getElementById('title-input');
Step 4
The last set of elements you need to get from the HTML file are the date-input and description-input elements. Save them in the variables dateInput and descriptionInput respectively.
const dateInput = document.getElementById('date-input'); const descriptionInput = document.getElementById('description-input');
Step 5
Create a taskData constant and set it to an empty array. This array will store all the tasks along with their associated data, including title, due date, and description. This storage will enable you to keep track of tasks, display them on the page, and save them to localStorage.
Use let to create a currentTask variable and set it to an empty object. This variable will be used to track the state when editing and discarding tasks.
const taskData = []; let currentTask = {};
Step 6
Now, you will work on opening and closing the form modal.
In earlier projects, you learned how to add and remove classes from an element with el.classList.add() and el.classList.remove(). Another method to use with the classList property is the toggle method.
The toggle method will add the class if it is not present on the element, and remove the class if it is present on the element.
element.classList.toggle(“class-to-toggle”);
Add an event listener to the openTaskFormBtn element and pass in a click event for the first argument and an empty callback function for the second argument.
For the callback function, use the classList.toggle() method to toggle the hidden class on the taskForm element.
Now you can click on the “Add new Task” button and see the form modal.
openTaskFormBtn.addEventListener("click", () => taskForm.classList.toggle("hidden"));
Step 7
The HTML dialog element has a showModal() method that can be used to display a modal dialog box on a web page.
dialogElement.showModal();
Add an event listener to the closeTaskFormBtn variable and pass in a click event for the first argument and a callback function for the second argument.
For the callback function, call the showModal() method on the confirmCloseDialog element. This will display a modal with the Discard and Cancel buttons.
closeTaskFormBtn.addEventListener("click", ()=> confirmCloseDialog.showModal());
Step 8
If the user clicks the Cancel button, you want to cancel the process and close the modal so the user can continue editing. The HTML dialog element has a close() method that can be used to close a modal dialog box on a web page.
dialogElement.close();
Add an event listener to the cancelBtn element and pass in a click event for the first argument and a callback function for the second argument.
For the callback function, call the close() method on the confirmCloseDialog element.
cancelBtn.addEventListener("click", () => confirmCloseDialog.close());
Step 9
If the user clicks the Discard button, you want to close the modal showing the Cancel and Discard buttons, then hide the form modal.
Add a click event listener to discardBtn, then use the close() method on the confirmCloseDialog variable. Also, use classList to toggle the class hidden on taskForm so the form modal will close too.
discardBtn.addEventListener("click", () => { confirmCloseDialog.close(); taskForm.classList.toggle("hidden"); });
Step 10
Now that you’ve worked on opening and closing the modal, it’s time to get the values from the input fields, save them into the taskData array, and display them on the page.
To start, add a submit event listener to your taskForm element and pass in e as the parameter of your arrow function. Inside the curly braces, use the preventDefault() method to stop the browser from refreshing the page after submitting the form.
taskForm.addEventListener("submit", (e) => { e.preventDefault(); })
Step 11
You will need to determine whether the task being added to the taskData array already exists or not. If the task does not exist, you will add it to the array. If it does exist, you will update it. To accomplish this, you can use the findIndex() method.
The findIndex() array method finds and returns the index of the first element in an array that meets the criteria specified by a provided testing function. If no such element is found, the method returns -1.
Here’s an example:
const numbers = [3, 1, 5, 6];
const firstNumLargerThanThree = numbers.findIndex((num) => num > 3);
console.log(firstNumLargerThanThree); // prints index 2
Use const to declare a variable called dataArrIndex and assign it the value of taskData.findIndex(). For the findIndex() method, pass in an arrow function with item as the parameter.
Within the arrow function, check if the id property of item is strictly equal to the id property of currentTask.
const dataArrIndex = taskData.findIndex((item) => item.id === currentTask.id);
Step 12
Next, retrieve the values from the input fields and store them in a taskObj object. Each task should also have a unique id.
Create a taskObj object with an id property as the first property. For the value of the id property, retrieve the value of the titleInput field, convert it to lowercase, and then use the split() and join() methods to hyphenate it.
Make sure all of those are in template literals because you need the id property value as a string.
const taskObj = { id: `${titleInput.value.toLowerCase().split(' ').join('-')}`, };
Step 13
To make the id more unique, add another hyphen and use Date.now().
Date.now() returns the number of milliseconds elapsed since January 1, 1970 00:00:00 UTC.
console.log(Date.now()); // 1628586800000
const taskObj = { id: `${titleInput.value.toLowerCase().split(' ').join('-')}-${Date.now()}`, };
Step 14
Retrieve the values from the titleInput, dateInput, and descriptionInput fields, and then save them in the properties title, date, and description of the taskObj object.
title: titleInput.value, date: dateInput.value, description: descriptionInput.value
Step 15
Now that you have obtained the values from the input fields and generated an id, you want to add them to your taskData array to keep track of each task. However, you should only do this if the task is new. If the task already exists, you will set it up for editing. This is why you have the dataArrIndex variable, which provides the index of each task.
Create an if statement with the condition dataArrIndex === -1. Within the if statement, use the unshift() method to add the taskObj object to the beginning of the taskData array.
unshift() is an array method that is used to add one or more elements to the beginning of an array.
N.B: Try adding a task and log taskData to the console to see what it looks like.
if (dataArrIndex === -1) { taskData.unshift(taskObj); }
Step 16
Now that you have saved the task in the taskData array, you should display the task on the page by looping through it.
Use forEach() on taskData, then destructure id, title, date, description as the parameters. Don’t return anything yet.
taskData.forEach(({id, title, date, description}) => { })
Step 17
Using arrow syntax complete the forEach callback function. Inside the callback function body use an addition assignment to set the innerHTML of tasksContainer to empty backticks.
taskData.forEach(({id, title, date, description}) => tasksContainer.innerHTML += `` );
Step 18
Create a div element with the class of task. Utilize template strings to set the id attribute of the div to the id you destructured from the task data.
Step 19
Create a p element and use template strings to set its content to the title you destructured. Right before the content of the p element, create a strong element with the text Title:.
Title:${title}
Step 20
Similarly to the previous step, create another p element, and interpolate the date you destructured as the text content. Inside this paragraph, create a strong element with the text Date:.
Date:${date}
Step 21
Create one more p element and interpolate the description you destructured as the text. Also, create a strong element inside the paragraph with the text Description:.
Description: ${description}
Step 22
To allow for task management, you need to include both a delete and an edit button for each task.
Create two button elements with the type attribute set to button and the class attribute set to btn. Set the text of the first button to Edit and the text of the second button to Delete.
Step 23
After adding the task to the page, you should close the form modal to view the task. To do this, utilize classList to toggle the hidden class on the taskForm element.
taskForm.classList.toggle("hidden");
Step 24
If you attempt to add another task now, you’ll notice that the input fields retain the values you entered for the previous task. To resolve this, you need to clear the input fields after adding a task.
Instead of clearing the input fields one by one, it’s a good practice to create a function that handles clearing those fields. You can then call this function whenever you need to clear the input fields again.
Use arrow syntax to create a reset function and set it to a pair of curly braces.
const reset = () => { }
Step 25
Inside the reset function, set each value of titleInput, dateInput, descriptionInput to an empty string.
Also, use classList to toggle the class hidden on the taskForm and set currentTask to an empty object. That’s because at this point, currentTask will be filled with the task the user might have added.
const reset = () => { titleInput.value = ""; dateInput.value = ""; descriptionInput.value = ""; taskForm.classList.toggle("hidden"); currentTask = {}; }