Costruire una To-Do List è uno degli esercizi più classici per chi vuole imparare a programmare con JavaScript Vanilla, cioè JavaScript "puro", senza framework o librerie esterne. È un progetto semplice, ma allo stesso tempo molto utile, perché ti insegna a gestire concetti fondamentali come:
- la manipolazione del DOM;
- l'interazione con l'utente tramite eventi;
- la struttura dei dati in array e oggetti;
- la persistenza dei dati tramite Local Storage del browser.
Questa guida ti accompagnerò passo passo nella creazione di una vera e propria mini-app per la gestione delle attività quotidiane. Alla fine avrai un'app funzionante, con cui potrai aggiungere, cancellare e spuntare i task, e che salverà tutto anche se chiudi il browser. Pronto? Cominciamo!
Preparazione: cosa ci serve?
Per costruire la nostra To-Do List avremo bisogno di tre file principali:
- index.html: conterrà la struttura della pagina;
- style.css: darà un aspetto più ordinato e piacevole all'interfaccia;
- script.js: sarà il cuore pulsante dell'app, tutta la logica in JavaScript.
Puoi creare una cartella chiamata ad esempio todo-vanilla e al suo interno aggiungere questi tre file.
Struttura HTML: la base della nostra app
Iniziamo con la parte più semplice: l'HTML. Qui creiamo la struttura visiva della To-Do List, ovvero l'intestazione, un campo input per aggiungere le attività, un pulsante e una lista dove verranno mostrate.
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>To-Do List</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<h1>La mia To-Do List</h1>
<form id="todo-form">
<input type="text" id="todo-input" placeholder="Aggiungi un'attività">
<button type="submit">Aggiungi</button>
</form>
<ul id="todo-list"></ul>
</div>
<script src="script.js"></script>
</body>
</html>
Come puoi vedere, è una struttura molto pulita. L'elemento chiave è il form che conterrà il campo input per scrivere un'attività e il bottone per aggiungerla. Poi c'è una lista non ordinata dove andranno tutti i task.
CSS: rendiamola un po' più bella
Non siamo designer, ma un minimo di stile ci aiuta a lavorare meglio. Ecco un CSS semplice, efficace e anche responsive:
body {
background-color: #f5f5f5;
font-family: Arial, sans-serif;
display: flex;
justify-content: center;
padding: 50px;
}
.container {
background: white;
padding: 2rem;
border-radius: 10px;
width: 100%;
max-width: 400px;
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
}
form {
display: flex;
gap: 10px;
}
input {
flex: 1;
padding: 10px;
border-radius: 5px;
border: 1px solid #ccc;
}
button {
padding: 10px 15px;
background-color: #4CAF50;
color: white;
border: none;
border-radius: 5px;
cursor: pointer;
}
ul {
list-style: none;
padding: 0;
margin-top: 20px;
}
li {
display: flex;
justify-content: space-between;
padding: 10px;
margin-bottom: 10px;
background-color: #eee;
border-radius: 5px;
}
li.completed {
text-decoration: line-through;
color: #888;
}
.delete-btn {
background: none;
border: none;
color: red;
font-size: 18px;
cursor: pointer;
}
JavaScript: il cervello della nostra To-Do List
Apri il file script.js e segui con attenzione. Partiremo con le basi e aggiungeremo funzionalità passo dopo passo. Recuperiamo gli elementi HTML:
const form = document.getElementById('todo-form');
const input = document.getElementById('todo-input');
const list = document.getElementById('todo-list');
Salviamo in variabili gli elementi chiave della pagina, così possiamo lavorarci facilmente. Carichiamo poi le attività dal Local Storage:
let todos = JSON.parse(localStorage.getItem('todos')) || [];
Se ci sono attività già salvate, le recuperiamo. Altrimenti iniziamo con un array vuoto.
Funzione per il savataggio
function saveToLocalStorage() {
localStorage.setItem('todos', JSON.stringify(todos));
}
Ogni volta che modifichiamo l'elenco, salviamo tutto nel Local Storage.
Aggiunta di un'attività e visualizzazione della lista
form.addEventListener('submit', (e) => {
e.preventDefault();
const text = input.value.trim();
if (text) {
todos.push({ text, completed: false });
saveToLocalStorage();
renderTodos();
input.value = '';
}
});
Quando l'utente clicca "Aggiungi", creiamo un nuovo oggetto e lo inseriamo nell'array.
function renderTodos() {
list.innerHTML = '';
todos.forEach((todo, index) => {
const li = document.createElement('li');
li.className = todo.completed ? 'completed' : '';
li.innerHTML = `
<span>${todo.text}</span>
<button class="delete-btn" data-index="${index}">✖</button>
`;
li.addEventListener('click', () => toggleComplete(index));
list.appendChild(li);
});
}
Ogni volta che l'array todos cambia, ricreiamo visivamente la lista. Aggiungiamo quindi un listener anche per gestire il completamento:
function toggleComplete(index) {
todos[index].completed = !todos[index].completed;
saveToLocalStorage();
renderTodos();
}
Con un semplice toggle invertiamo lo stato completed di un task.
Cancellazione di un'attività
list.addEventListener('click', (e) => {
if (e.target.classList.contains('delete-btn')) {
const index = e.target.dataset.index;
todos.splice(index, 1);
saveToLocalStorage();
renderTodos();
}
});
Quando si clicca sulla X, eliminiamo l'attività dall'array e aggiorniamo.
Perché usare il Local Storage?
Il Local Storage è una funzionalità molto utile perché permette di salvare dati direttamente nel browser, senza bisogno di database esterni o backend. Perfetto per progetti semplici o app offline.
Con localStorage.getItem() e localStorage.setItem() possiamo leggere e scrivere dati come stringhe. Usando JSON.stringify() e JSON.parse() convertiamo facilmente gli oggetti in formato leggibile.
Possibili estensioni con JavaScript
Una volta che hai capito la logica, puoi divertirti a espandere il progetto:
- Aggiungere la possibilità di modificare le attività.
- Filtrare per "completati" o "in sospeso".
- Ordinare per data.
- Aggiungere date di scadenza.
- Collegare l'app a un backend (come un'API Node.js).
- Implementare la sincronizzazione su cloud.
Questo progetto permette di mettere in pratica molte delle conoscenze base di JavaScript e di combinare HTML, CSS e JavaScript per costruire una piccola applicazione interattiva. La To-Do List rappresenta una base solida per sviluppare app più complesse. Puoi espanderla in molte direzioni aggiungendo funzionalità come:
- Filtri per visualizzare solo le attività completate o quelle non completate.
- modificare le attività dopo che sono state aggiunte.
- Ordinare le attività in base alla data di creazione o scadenza.
- Aggiungere una priorità per le attività e ordinarle di conseguenza.
- Integrare il progetto con un backend, ad esempio un'API che memorizza le attività in un database, per sincronizzare i propri dati su più dispositivi.
Conclusione
Abbiamo completato la creazione di una To-Do List utilizzando JavaScript Vanilla, senza l'uso di librerie o framework. Questa app ci permette di aggiungere, eliminare e segnare come completate le attività, e la cosa più importante è che salva automaticamente i dati nel Local Storage, in modo che le attività rimangano anche dopo che il browser viene ricaricato o chiuso.
Nel corso di questa guida, abbiamo esplorato vari concetti fondamentali del web development, tra cui:
- Manipolazione del DOM: modificare il contenuto e la struttura della pagina in base alle interazioni dell'utente.
- Gestione degli eventi: intercettare e rispondere agli eventi di interazione, come il click del pulsante o l'invio del modulo.
- Persistenza dei dati con Local Storage: la capacità di memorizzare in modo persistente le informazioni nel browser, senza un backend o di una connessione internet.
- Strutture di dati: abbiamo utilizzato un array di oggetti per gestire attività e modificarne lo stato.
Comprendere i fondamenti di Local Storage permette di memorizzare dati in modo semplice e rapido senza dover ricorrere a un database esterno. Anche se ha dei limiti (non è sicuro per dati sensibili), è perfetto per applicazioni che non necessitano di una connessione continua a un server.
Questo tipo di progetto ti aiuterà a sviluppare una mentalità orientata alla risoluzione dei problemi, dato che imparerai a debuggare e ottimizzare il codice oltre a creare funzionalità aggiuntive quando necessario.