DEV Community

Cover image for Title: Building a Persistent Task Manager with JS and Bootstrap πŸš€
Abhishek Mishra
Abhishek Mishra

Posted on

Title: Building a Persistent Task Manager with JS and Bootstrap πŸš€

Intro

Have you ever wondered how to build a functional CRUD (Create, Read, Update, Delete) application without a complex framework like React or Angular? Today, we're diving deep into a Task Management app built using Vanilla JavaScript, Bootstrap 5, and Local Storage for data persistence.

**

The Core Concept

**
The Tasky Project is designed to help users manage daily tasks by creating interactive cards. Each task includes a title, description, type, and an optional image URL.

**

Key Features:

**

  • Persistent Storage: Tasks stay even after a page refresh thanks to localStorage.
  • Live Search: Filter through your tasks in real-time.
  • In-Place Editing: Modify task details directly on the card.
  • Fully Responsive: A clean UI that works on mobile and desktop using Bootstrap.

1. The Power of localStorage

One of the most important aspects of this project is ensuring that user data isn't lost. We use a central state object and synchronize it with the browser's storage.

JavaScript

// Function to sync our local state with browser storage
const updateLocalStorage = () => {
  localStorage.setItem(
    "task",
    JSON.stringify({
      tasks: state.taskList,
    })
  );
};
Enter fullscreen mode Exit fullscreen mode

When the application loads, it triggers loadInitialData() to fetch this stored string, convert it back into JSON, and render the cards on the screen.

2. Dynamic UI Rendering

Instead of hardcoding HTML, we use Template Literals to generate task cards dynamically based on the data. This allows for a much more scalable application.

JavaScript

const htmlTaskContent = ({ id, title, description, type, url }) => `
  <div class="col-md-6 col-lg-4 mt-3" id=${id}>
    <div class='card shadow-sm task__card'>
      <div class='card-header d-flex justify-content-end'>
          <button type='button' class='btn btn-outline-primary' onclick="editTask.apply(this, arguments)">
              <i class='fas fa-pencil-alt'></i>
          </button>
      </div>
      <div class='card-body'>
          <img src=${url || 'default-image.png'} class='card-img-top' />
          <h4 class='card-title'>${title}</h4>
          <p class='text-muted'>${description}</p>
          <span class='badge bg-primary'>${type}</span>
      </div>
    </div>
  </div>
`;
Enter fullscreen mode Exit fullscreen mode

3. Implementing Search Functionality

The search feature uses the .filter() method to match the user's input against the task titles in our state. Every time you type, the UI clears and re-renders only the matching tasks.

JavaScript

const searchTask = (e) => {
  const resultData = state.taskList.filter(({ title }) =>
    title.toLowerCase().includes(e.target.value.toLowerCase())
  );

  resultData.map((cardData) =>
      taskContents.insertAdjacentHTML("beforeend", htmlTaskContent(cardData))
  );
};
Enter fullscreen mode Exit fullscreen mode

4. Handling Edits with contenteditable

A cool trick used in this project is the contenteditable attribute. Instead of opening a new form, we make the existing card text editable, allowing for a seamless user experience.

JavaScript

// Making fields editable
taskTitle.setAttribute("contenteditable", "true");
taskDescription.setAttribute("contenteditable", "true");
taskType.setAttribute("contenteditable", "true");
Enter fullscreen mode Exit fullscreen mode

Conclusion

Building this project highlights how powerful Vanilla JavaScript can be when combined with utility-first CSS frameworks like Bootstrap. It teaches fundamental concepts like DOM manipulation, event handling, and state management.

Check out the full source code here: GitHub Repository

Top comments (0)