My WebDev Notes: A simple TO-DO List application

Habdul Hazeez - Apr 18 '20 - - Dev Community

Check the application is online: https://ziizium.github.io/my-webdev-notes/todoapp/

We all keep a list of things we'll like to do in the future and conventionally we use pen and paper. Then as technology advances, we use mobile and online applications to keep track of our daily activities.

A to-do list application is a mobile or an online application that allows us to keep track of our activities. There are many to-do list applications online, this experiment is about creating a minimalist to-do list application using HTML, CSS, and JavaScript, and with one addition: dark mode.

The HTML

The HTML code consist of noscript tag with information that is displayed to users with JavaScript turned off or disabled in their browser.

The header tags consist of the toggle switch used for switching to night mode

Then in the main tag, we have the form instruction, the form itself, the un-ordered list that will contain the generated li tags which in turn will contain the names of each to-do item.

Then at the bottom of the page, we link to two separate files polyfill.js and tasklist.js

<body id="body">

    <noscript> <!-- Shown to browsers with JavaScript disabled -->
        <p style="padding: 0.5em; text-align: center; font-size: 1.2em;">This application works best with JavaScript enabled in your browser.</p>
    </noscript>

    <header class="header" id="header">
        <div class="header__inner">
            <h2><a href="index.html">To Do List</a></h2>
            <form>
                <label class="changeTheme" id="changeTheme-js">
                    <input type="checkbox" id="changeTheme" class="changeTheme__input">
                    <div class="changeTheme__slider round"></div>
                </label>
            </form>
        </div>
    </header>

    <main>

        <div class="row">

            <div class="form-instruction" id="form-instruction">
                <em>The following are allowed: letters, numbers, commas, apostrophes, hyphens, question marks, and spaces</em>
            </div>

            <form class="taskForm">
                <label for="taskForm__input" class="taskForm__label visuallyHidden">Enter TO DO</label>
                <input type="text" id="taskForm__input" placeholder="Enter your task name" class="taskForm__input">
                <input id="taskForm__submitInput" type="submit" name="addTask" value="Add Task" class="taskForm__submitInput">
            </form>

        </div>

        <!-- The tasks will be list items in an un-ordered list-->
        <ul id="taskList" class="taskList"></ul>

    </main>

    <!-- We require a polyfill for the ChildNode.remove() method which is not
    supported in IE -->
    <script src="polyfill.js"></script>

    <script src="tasklist.js"></script>
Enter fullscreen mode Exit fullscreen mode

The CSS

The CSS used in styling the application is not explained in detail because it's not the focus of this experiment but you can check styles.css in the GitHub repository.

The JavaScript

JavaScript is the essential part of the application (excluding the code that's used for switching to dark mode) therefore, we'll dissect it together.

Tha pseudocode for creating the to-do item is as follows:

  • Get the user input
  • Verify it's in the right format
  • Create the task item

We'll be selecting a lot of HTML elements via their attributes so it is best if we have a single function for doing this instead of typing multiple API methods every time we need one.

let $ = function (selector) {
    return document.querySelector(selector);
};
Enter fullscreen mode Exit fullscreen mode

Next, we'll be validating the user input to prevent them from entering unwanted data in the form input. We'll use regular expression for this. The regular expression will only allow letters, numbers, spaces, hyphens, apostrophe, and question marks. You can make the regular expression better and adapt it to your needs.

let validateInput = function (strValue)  {
    var objRegExp = /^[0-9a-zA-z\s\-\.\'\?]+$/; // specify allowed characters
    return objRegExp.test(strValue); // test the string against the specified pattern
};
Enter fullscreen mode Exit fullscreen mode

We use the remove() method to delete a task when it's no longer needed. There is a tendency that you'll create many to-do's therefore, we create a function that is attached to all to-do items.

let removeParent = function (classname) {
    let div = this.parentElement;
    div.remove();
};
Enter fullscreen mode Exit fullscreen mode

Next, we need to get the name of the to-do task via the form input and we'll use this name to create the to-do item.

The to-do item will be created when the user submits the form. All we have to do is check when the user clicks on the submit button then we create the to-do task.

We'll make use of an anonymous function to create the to-do task. Inside the function, we perform the following steps:

  • Trim white-spaces from the beginning and the end of the input
  • Validate the input
  • Create a new li tag
  • Create a new variable named newTask and set it to false
  • If the input validation passes
    • The input is passed to the createTextNode() method and assigned to the newTask variable
  • Else the form input is cleared and we alert the user
  • If the newTask is not empty and not false:
    • The form input is cleared
    • The li is appended to the ul
    • The to-do task is appended to the li
    • Create an element that will be used to delete the task
    • Add a class name to the created element
    • Append this element to the li
    • Attach an event handler and set it to removeParent
  • Prevent the form from submitting

The resulting JavaScript Code:

$('.taskForm').onsubmit =  function() {

    let taskName = $("#taskForm__input").value.trim();
    let validatedData = validateInput(taskName);

    let taskItem = document.createElement('li');
    let newTask = false;

    if (validatedData && validatedData !== "") {
        newTask = document.createTextNode(taskName); // create the name of the task
    } else {
        taskForm__input.value = ""; // clear the form input
        alert("Your task name contains invalid characters");
    }

    if (newTask !== "" && newTask !== false) {

        taskForm__input.value = ""; // Clear the form input

        taskList.appendChild(taskItem);

        taskItem.appendChild(newTask);

        let deleteTask = document.createElement("SPAN");

        let deleteIcon = document.createTextNode("\u00D7");

        deleteTask.className = "delete-task";

        deleteTask.appendChild(deleteIcon);

        taskItem.appendChild(deleteTask);

    }

    let getDeleteTask = $("#taskList").getElementsByClassName('delete-task');

    for (let i = 0; i < getDeleteTask.length; i++) {
        getDeleteTask[i].onclick = removeParent;
    }

    // Prevent the form from submitting
    return false;

}
Enter fullscreen mode Exit fullscreen mode

When you mark a to-do item as done, a little check mark as added before it, a strike-through text-decoration is applied to the text and the background color is changed. All this possible thanks to JavaScript. Let's explain how it works.

The JavaScript code has to listen for an event, in this case, it will listen for the click event i.e when the user clicks on the unordered list (ul) that contains the to-do tasks (li). When this happens we write a function that accepts an event as a parameter and ensures that a li tag was actually clicked. How can we do this?

Well, events have a target attribute associated with it, here the target is the HTML li tags. The name of li tags is available in its capitalized form i.e LI to the target attribute via the tagName attribute.

After checking that the li tag was actually clicked, we use the classList which has a toggle attribute to add the CSS checked class to the li tag.

// We get the unordered list which contains the list
// items
let taskList = $('#taskList');

// Attach an event
taskList.addEventListener('click', function(event) {
    if (event.target.tagName === 'LI') {
        event.target.classList.toggle('checked')
    }
}, false);
Enter fullscreen mode Exit fullscreen mode

Here is the CSS that gets added to the li tags:

.taskList li.checked {
    background: #888888;
    color: #ffffff;
    text-decoration: line-through;
}
Enter fullscreen mode Exit fullscreen mode

The remaining JavaScript code is for adding dark mode functionality.

The Github repo:

GitHub logo ziizium / my-webdev-notes

Code snippets for series of articles on DEV about my experiments in web development

My WebDev Notes

This repositiory contains code snippets, and links for series of articles on DEV about my experiments in Web development.

List of articles






Have fun!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .