Everything you need as a full stack developer

Building a todo list application to manage tasks

- Posted in Frontend Developer by

TL;DR Developers can create a todo list application with features such as creating new tasks, editing existing tasks, deleting completed or irrelevant tasks, filtering tasks by category, and sorting tasks by priority, date, and category using HTML5, CSS3, JavaScript for the frontend and Node.js with Express to create API endpoints for interacting with MongoDB.

Building a Todo List Application to Manage Tasks

As developers, we've all been there – struggling to stay on top of our tasks and deadlines. A well-organized task management system can be the difference between a productive day and a chaotic one. In this article, we'll embark on a journey to build a todo list application that will revolutionize the way you manage your tasks.

What We're Building

Our todo list application will have the following features:

  • Create new tasks with due dates and reminders
  • Edit existing tasks
  • Delete completed or irrelevant tasks
  • Filter tasks by category (e.g., work, personal)
  • Sort tasks by priority, date, and category

Frontend Development

We'll start with the frontend, using HTML5, CSS3, and JavaScript to create a user-friendly interface. Our application will have the following pages:

  1. Home Page: Displays all available categories (work, personal, etc.)
  2. Task List Page: Shows all tasks for the selected category
  3. New Task Form: Allows users to create new tasks with due dates and reminders

Home Page

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List App</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <!-- Categories list -->
    <ul id="categories-list">
        <li><a href="#" data-category="work">Work</a></li>
        <li><a href="#" data-category="personal">Personal</a></li>
    </ul>

    <script src="scripts.js"></script>
</body>
</html>

Task List Page

<!-- task-list.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List App</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <!-- Task list -->
    <ul id="task-list">
        {% for task in tasks %}
            <li>
                <h2>{{ task.title }}</h2>
                <p>{{ task.description }}</p>
                <p>Due Date: {{ task.due_date }}</p>
                <button class="delete-task">Delete</button>
            </li>
        {% endfor %}
    </ul>

    <script src="scripts.js"></script>
</body>
</html>

New Task Form

<!-- new-task.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Todo List App</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <!-- New task form -->
    <form id="new-task-form">
        <input type="text" id="task-title" placeholder="Task Title">
        <input type="date" id="due-date" placeholder="Due Date">
        <button class="create-task">Create Task</button>
    </form>

    <script src="scripts.js"></script>
</body>
</html>

Backend Development

For the backend, we'll use Node.js with Express to create API endpoints for creating, reading, updating, and deleting tasks. We'll also use MongoDB as our database to store task data.

Task Model

// models/task.js
const mongoose = require('mongoose');

const taskSchema = new mongoose.Schema({
    title: String,
    description: String,
    due_date: Date,
    category: String
});

module.exports = mongoose.model('Task', taskSchema);

API Endpoints

// routes/task.js
const express = require('express');
const Task = require('../models/task');

const router = express.Router();

router.get('/tasks', async (req, res) => {
    const tasks = await Task.find().exec();
    res.json(tasks);
});

router.post('/tasks', async (req, res) => {
    const task = new Task(req.body);
    await task.save();
    res.json(task);
});

router.put('/tasks/:id', async (req, res) => {
    const task = await Task.findByIdAndUpdate(req.params.id, req.body, {new: true});
    res.json(task);
});

router.delete('/tasks/:id', async (req, res) => {
    await Task.findByIdAndRemove(req.params.id);
    res.status(204).send();
});

module.exports = router;

Putting it all Together

With our frontend and backend components in place, we can now combine them to create a fully functional todo list application.

Frontend Code

// scripts.js
document.addEventListener('DOMContentLoaded', () => {
    // Initialize task list page
    const taskListPage = document.getElementById('task-list');
    fetch('/tasks')
        .then(response => response.json())
        .then(tasks => {
            tasks.forEach(task => {
                const taskElement = document.createElement('li');
                taskElement.innerHTML = `
                    <h2>${task.title}</h2>
                    <p>${task.description}</p>
                    <p>Due Date: ${task.due_date.toISOString()}</p>
                    <button class="delete-task">Delete</button>
                `;
                taskListPage.appendChild(taskElement);
            });
        });

    // Handle new task form submission
    const newTaskForm = document.getElementById('new-task-form');
    newTaskForm.addEventListener('submit', async (event) => {
        event.preventDefault();
        const taskTitle = document.getElementById('task-title').value;
        const dueDate = document.getElementById('due-date').value;
        const category = 'work'; // Replace with actual category
        const response = await fetch('/tasks', {
            method: 'POST',
            headers: { 'Content-Type': 'application/json' },
            body: JSON.stringify({ title: taskTitle, description: '', due_date: new Date(dueDate), category })
        });
        const task = await response.json();
        console.log(task);
    });

    // Handle delete task button click
    document.querySelectorAll('.delete-task').forEach((button) => {
        button.addEventListener('click', async (event) => {
            event.preventDefault();
            const taskId = event.target.parentNode.dataset.id;
            await fetch(`/tasks/${taskId}`, { method: 'DELETE' });
            window.location.reload();
        });
    });
});

Conclusion

Congratulations! You've just built a fully functional todo list application from scratch. This application allows users to create new tasks, edit existing tasks, delete completed or irrelevant tasks, filter tasks by category, and sort tasks by priority, date, and category.

This is just the beginning of your journey as a full-stack developer. Practice building more complex applications, experimenting with different technologies, and exploring new features to enhance user experience.

Key Use Case

Workflow:

  1. User creates a new task: The user fills out the new task form on the frontend, selecting the category (e.g., work, personal) and entering the due date.
  2. Frontend sends request to backend: When the user submits the form, the frontend JavaScript code sends a POST request to the /tasks endpoint with the task data in JSON format.
  3. Backend creates new task document: The Node.js Express server receives the request and uses Mongoose to create a new Task document in the MongoDB database.
  4. Frontend retrieves updated task list: After creating the new task, the frontend JavaScript code sends a GET request to the /tasks endpoint to retrieve the updated list of tasks.
  5. User views updated task list: The frontend updates the task list page with the new task and displays it to the user.

Use case:

  • A user wants to create a new task for their work category with a due date of tomorrow. They fill out the new task form on the frontend, select "work" as the category, and enter the due date.
  • The frontend JavaScript code sends a POST request to the /tasks endpoint with the task data in JSON format.
  • The Node.js Express server receives the request and creates a new Task document in the MongoDB database with the specified details.
  • The frontend retrieves the updated list of tasks from the backend and updates the task list page, displaying the new task to the user.

Finally

As we continue to build our todo list application, let's focus on implementing the backend logic for creating, reading, updating, and deleting tasks. We'll use Node.js with Express to create API endpoints for interacting with our MongoDB database. The task model will be defined using Mongoose, allowing us to easily interact with our MongoDB collection.

// models/task.js
const mongoose = require('mongoose');

const taskSchema = new mongoose.Schema({
    title: String,
    description: String,
    due_date: Date,
    category: String
});

module.exports = mongoose.model('Task', taskSchema);

With the task model in place, we can now define our API endpoints using Express. We'll create routes for creating new tasks, retrieving existing tasks, updating existing tasks, and deleting tasks.

// routes/task.js
const express = require('express');
const Task = require('../models/task');

const router = express.Router();

router.get('/tasks', async (req, res) => {
    const tasks = await Task.find().exec();
    res.json(tasks);
});

router.post('/tasks', async (req, res) => {
    const task = new Task(req.body);
    await task.save();
    res.json(task);
});

router.put('/tasks/:id', async (req, res) => {
    const task = await Task.findByIdAndUpdate(req.params.id, req.body, {new: true});
    res.json(task);
});

router.delete('/tasks/:id', async (req, res) => {
    await Task.findByIdAndRemove(req.params.id);
    res.status(204).send();
});

module.exports = router;

By combining the frontend and backend components, we can create a fully functional todo list application that allows users to manage their tasks efficiently. With this implementation, we've covered the key features of creating new tasks, editing existing tasks, deleting completed or irrelevant tasks, filtering tasks by category, and sorting tasks by priority, date, and category.

Recommended Books

  • "The Pragmatic Programmer: From Journeyman to Master" by Andrew Hunt and David Thomas - A classic book for programmers that provides practical advice on improving coding skills, communication, and collaboration.
  • "Clean Code: A Handbook of Agile Software Craftsmanship" by Robert C. Martin - A comprehensive guide to writing clean, maintainable code with principles and techniques for improving code quality.
  • "Introduction to Algorithms" by Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford Stein - A thorough textbook on algorithms that covers data structures, sorting, searching, and graph algorithms.
Fullstackist aims to provide immersive and explanatory content for full stack developers Fullstackist aims to provide immersive and explanatory content for full stack developers
Backend Developer 103 Being a Fullstack Developer 107 CSS 109 Devops and Cloud 70 Flask 108 Frontend Developer 357 Fullstack Testing 99 HTML 171 Intermediate Developer 105 JavaScript 206 Junior Developer 124 Laravel 221 React 110 Senior Lead Developer 124 VCS Version Control Systems 99 Vue.js 108

Recent Posts

Web development learning resources and communities for beginners...

TL;DR As a beginner in web development, navigating the vast expanse of online resources can be daunting but with the right resources and communities by your side, you'll be well-equipped to tackle any challenge that comes your way. Unlocking the World of Web Development: Essential Learning Resources and Communities for Beginners As a beginner in web development, navigating the vast expanse of online resources can be daunting. With so many tutorials, courses, and communities vying for attention, it's easy to get lost in the sea of information. But fear not! In this article, we'll guide you through the most valuable learning resources and communities that will help you kickstart your web development journey.

Read more

Understanding component-based architecture for UI development...

Component-based architecture breaks down complex user interfaces into smaller, reusable components, improving modularity, reusability, maintenance, and collaboration in UI development. It allows developers to build, maintain, and update large-scale applications more efficiently by creating independent units that can be used across multiple pages or even applications.

Read more

What is a Single Page Application (SPA) vs a multi-page site?...

Single Page Applications (SPAs) load a single HTML file initially, handling navigation and interactions dynamically with JavaScript, while Multi-Page Sites (MPS) load multiple pages in sequence from the server. SPAs are often preferred for complex applications requiring dynamic updates and real-time data exchange, but MPS may be suitable for simple websites with minimal user interactions.

Read more