Learning the basics of Javascript and HTML is fun and challenging, just like learning your first words in a foreign language. Going in, you don't know what you don't know. Each lesson opens a new door giving you a glimpse of exactly what you don't know yet. It's thrilling to take a little deep dive into one of those rabbit holes and coming out with a deeper understanding of a concept. But there's nothing more thrilling than completing your first project.
My first project was a very basic task-lister. I was provided a very basic HTML layout, a complete CSS file, and an empty JavaScript file. My tasks were to create a task list where a user can type a task input into a field, click a submit button, and see the task appear on a list. Pretty simple, right? Create a form in HTML that is visible upon loading the page, take input, and add an event listener that appends text content to the list once the submit button is clicked. Where it got really interesting was in the stretch deliverables where I tried to make the list behave in a way that I would want if i were actually using it.
First, I added another button that would delete the task from the list when clicked. Again, it sounded like such a simple task, but with every refresh I realized there was yet another step. The button needed to only appear once a task was created. The button needed to contain text, in this case, and "x". The button needs to "listen" for a click on it to perform its actions. Oh my gosh it works
But actually, I really like being able to cross off my tasks when they're done and see what I've accomplished in the day. Okay, let's try something else. I created another button, this time with the text "Done". My goal was to take a task, turn the color grey, and strike through the text. I had created a few buttons by this point, so the set-up was easy peasy. But now I had entered new territory. How on earth do I strike through text or change the color? This is CSS territory, not JavaScript territory, right? A quick search later: well, yeah. But only kind-of. I learned that I can, in fact, change how text appears using JavaScript because it needs to be able to happen after an event, not just upon loading. A quick little event listener and 2 lines later:
and some fixing spelling/syntax errors one too many times
newTask.style.textDecoration = "line-through";
newTask.style.color = "grey";
It works AGAIN!!!
Now I'm on top of the world. I can change ANYTHING. How about the color of every task based on priority that the user selects from a drop-down menu?
Okay, I may have gotten a little carried away here, but I learned how to create a drop down using <select>
and I saw that there were not only options, but also optgroups. I wanted to use all of it. I wanted to see all of my options. I wanted to know what it would look like. And was it useful?
<select id="importance" name="i-am-confused" placeholder="importance">
<option value="" disabled selected>Select Importance</option>
<optgroup label="Critical">
<option value="black">Black</option>
</optgroup>
<optgroup label="High">
<option value="red">Red</option>
<option value="orange">Orange</option>
</optgroup>
<optgroup label="Medium">
<option value="yellow">Yellow</option>
<option value="green">Green</option>
</optgroup>
<optgroup label="Low">
<option value="blue">Blue</option>
<option value="purple">Purple</option>
</optgroup>
</select>
Yes- I used every color. Even a barely visible yellow.
Yes- for some reason black is the most critical color.
Yes- I set the name attribute for my drop-down selector to "i-am-confused".
No- It's not really practical for a user.
I had figured out that "placeholder" is the text that shows up within the element, and that "value="" disabled" allows the text assigned to "placeholder" to show up as default instead of the first option. I had no idea what "name" did. And I didn't figure it out until after completing another project later. Now I know that the "name" attribute allows me to select it with specific syntax if I wanted to do something with it using JavaScript. But, for now, in my task-lister this selection menu is still named "i-am-confused" as a little reminder of my learning progress.
But what about all those colors? Yeah, I probably wouldn't do that again. It was great to learn from and see my pretty little rainbow of a list populate as if they were throwing confetti as little celebration of my successful progress. But its functionality was wildly impractical.
Before that little celebration, though, I had to figure out a way to assign the text of each little task a different color. At first I wrote every color into an if/else statement. It kind-of worked, but I realized there was a much neater way to do it. Switch statements!
switch (importanceColor) {
case 'red':
newTask.style.color = "red";
break;
case 'orange':
newTask.style.color = "orange";
break;
case 'yellow':
newTask.style.color = "gold";
break;
case 'green':
newTask.style.color = "green";
break;
case 'blue':
newTask.style.color = "blue";
break;
case 'purple':
newTask.style.color = "purple";
break;
default:
newTask.style.color = "black";
break;
}
I learned why a default in a switch statement is useful. In this case, it takes care of what happens when the user doesn't make a selection in the drop down. I also learned that yellow is completely unreadable on a pink background - and gold isn't much better. But I wanted my rainbow.
Okay, amazing. I have a list, a done function, a delete function, and I can color my text. But it would be much more helpful if tasks of equal importance and color were grouped together, and if the tasks were listed in order of importance.
I'm not going to lie, this part was rather hard and took a couple searches to figure out.
// Sort tasks by color priority
function sortTasksByColor() {
const tasksList = document.querySelector("#tasks");
const taskArray = Array.from(tasksList.children);
const colorPriority = {
red: 1,
orange: 2,
gold: 3,
green: 4,
blue: 5,
purple: 6,
grey: 7
};
taskArray.sort((taskA, taskB) => {
const colorA = taskA.style.color;
const colorB = taskB.style.color;
return colorPriority[colorA] - colorPriority[colorB];
});
In simple terms, I assigned each color a number that represents its priority. I put the tasks into an array and sorted them by comparing the numerical value of the tasks against each other. Wow, what a pretty rainbow! More importantly, the most important tasks are now at the top with priority decreasing as you read down the list. And tasks marked "Done" are sent to the bottom.
...But what if I make a mistake and want to fix my task
Big sigh
Okay, last step, I promise.
I started with a step I've done several times in this project alone. Create a button. Then, add an event listener. I'm a pro at this now. So, what happens if I click this button now?
First I tried to make new text boxes and dropsdowns appear on the task clicked. It worked but I was confused and the user flow was clunky, so I tried again. This time, I used the original text boxes and drop down selection. The idea was to type an edit into the original box or make a new selection and click the "edit" button on a task to implement those changes on an individual task. The user flow is not intuitive and quite clunky, but I decided that that's a problem for another day.
To edit the task, the event listener needs to listen for the click and change the text content of the task to whatever is in the text box now. Pretty simple. The priority assignment took a few more tries. At first, the task would be edited, but the original assignment and importance selections were not retained. This was an issue I was not expecting.
I wrote a series of if statements to try to retain the original values, then I realized that this would be a great use for comparison operators!
const newText = form.querySelector("#new-task-description").value || currentText;
const newAssignment = form.querySelector("#assigned-to-description").value || currentAssignment;
I also copy-and-pasted the color assignment block to take care of the color selection. If I were to continue on with this project, I would see if I could turn that block of code into a callback function so that it can be called to color tasks rather than write it all out each time.
Another surprise: all of my buttons disappeared! No biggie, I re-appended each button and everything looked great again.
I have so many more ideas still-
What if I want to make check-boxes? Or create a separate list of finished tasks? Or make a date due option? Or or or...
But those will need to be saved for another day.
Oh, and lets not forget
form.reset();
And now, I am ready for the next task.
Top comments (0)