Building an Offline-Enabled To-Do List Web App 🚀

Building an Offline-Enabled To-Do List Web App 🚀

Building an Offline-Enabled To-Do List Web App

After getting huge success on my previous article. Here is a use case of building an Offline-Enabled Website.

In today’s world, where connectivity isn’t always guaranteed, creating web applications that work offline can greatly enhance user experience. In this tutorial, we’ll walk through the process of building a simple To-Do List web app that functions both online and offline. We’ll be using basic HTML, CSS, and JavaScript, along with a service worker for caching resources.

See Source Code and Live Preview

Prerequisites

Basic knowledge of HTML, CSS, and JavaScript
A text editor
A browser that supports service workers (most modern browsers)

Setting Up the Project

Let’s start by setting up the basic structure of our project. Create the following files in a new directory:

index.html
styles.css
app.js
service-worker.js

The HTML Structure (index.html)

Our main HTML file will contain the structure of our To-Do List web app. Here’s a basic layout:

<!DOCTYPE html>
<html lang=“en”>
<head>
<meta charset=“UTF-8”>
<meta name=“viewport” content=“width=device-width, initial-scale=1.0”>
<title>Offline To-Do List</title>
<link rel=“stylesheet” href=“styles.css”>
</head>
<body>
<div class=“container”>
<h1>Offline To-Do List</h1>
<div class=“form”>
<input type=“text” id=“taskInput” placeholder=“Add new task…”>
<button onclick=“addTask()”>Add Task</button>
</div>
<ul id=“taskList”>
<!– Tasks will be dynamically added here –>
</ul>
</div>
<script src=“app.js”></script>
</body>
</html>

Styling (styles.css)

Let’s add some basic styles to make our app look presentable:

body {
font-family: Arial, sans-serif;
margin: 20px;
}

.container {
max-width: 600px;
margin: 0 auto;
}

h1 {
text-align: center;
}

.form {
display: flex;
margin-bottom: 20px;
}

input[type=“text”] {
flex: 1;
padding: 10px;
}

button {
padding: 10px 20px;
background-color: #007bff;
color: #fff;
border: none;
cursor: pointer;
}

button:hover {
background-color: #0056b3;
}

ul {
list-style-type: none;
padding: 0;
}

li {
margin-bottom: 10px;
}

.completed {
text-decoration: line-through;
color: #888;
}

Adding Functionality (app.js)

Our JavaScript file will handle the logic for adding tasks, toggling completion, deleting tasks, rendering tasks, and saving tasks to localStorage. It will also register the service worker.

let tasks = [];

// Check if there are tasks in localStorage
const storedTasks = localStorage.getItem(tasks);
if (storedTasks) {
tasks = JSON.parse(storedTasks);
renderTasks();
}

function addTask() {
const taskInput = document.getElementById(taskInput);
const taskText = taskInput.value.trim();
if (taskText !== ) {
tasks.push({ text: taskText, completed: false });
taskInput.value = ;
renderTasks();
saveTasks();
}
}

function toggleTask(index) {
tasks[index].completed = !tasks[index].completed;
renderTasks();
saveTasks();
}

function deleteTask(index) {
tasks.splice(index, 1);
renderTasks();
saveTasks();
}

function renderTasks() {
const taskList = document.getElementById(taskList);
taskList.innerHTML = ;
tasks.forEach((task, index) => {
const li = document.createElement(li);
li.innerHTML = `
<span class=”
${task.completed ? completed : }” onclick=”toggleTask(${index})”>${task.text}</span>
<button onclick=”deleteTask(
${index})”>Delete</button>
`
;
taskList.appendChild(li);
});
}

function saveTasks() {
localStorage.setItem(tasks, JSON.stringify(tasks));
}

// Service Worker Registration
if (serviceWorker in navigator) {
navigator.serviceWorker.register(/service-worker.js)
.then(reg => {
console.log(Service Worker registered);
})
.catch(error => {
console.error(Service Worker registration failed:, error);
});
}

Service Worker (service-worker.js)

The service worker file is responsible for caching the necessary files and handling requests when the app is offline:

const cacheName = offline-v1;
const cacheFiles = [
/,
/index.html,
/styles.css,
/app.js
];

self.addEventListener(install, e => {
console.log(Service Worker: Installed);
e.waitUntil(
caches.open(cacheName)
.then(cache => {
console.log(Service Worker: Caching Files);
cache.addAll(cacheFiles);
})
.then(() => self.skipWaiting())
);
});

self.addEventListener(activate, e => {
console.log(Service Worker: Activated);
e.waitUntil(
caches.keys().then(cacheNames => {
return Promise.all(
cacheNames.map(cache => {
if (cache !== cacheName) {
console.log(Service Worker: Clearing Old Cache);
return caches.delete(cache);
}
})
);
})
);
});

self.addEventListener(fetch, e => {
console.log(Service Worker: Fetching);
e.respondWith(
fetch(e.request)
.then(response => {
const clone = response.clone();
caches.open(cacheName)
.then(cache => {
cache.put(e.request, clone);
});
return response;
})
.catch(() => caches.match(e.request).then(response => response))
);
});

Conclusion

By following this tutorial, you’ve learned how to create an offline-enabled To-Do List web app using basic web technologies. Users can add tasks, mark them as completed, and delete them – all while offline. The service worker ensures that the app functions seamlessly even without an internet connection by caching the necessary files.

Feel free to expand upon this project by adding more features like editing tasks, due dates, or even syncing with a backend server when connectivity is restored. This is just the beginning of what you can achieve with offline web applications!

Happy coding! 🚀

Leave a Reply

Your email address will not be published. Required fields are marked *