Tutti gli altri (6-10)

This commit is contained in:
2026-02-03 00:08:30 +01:00
parent 0043f1f83f
commit e6f6f17769
54 changed files with 3205 additions and 0 deletions

View File

@@ -0,0 +1,16 @@
/**
* Esercizio Intermedio: Convertitore Celsius-Fahrenheit
*
* Obiettivo: Utilizzare .map() per trasformare dati numerici.
*
* GradiFahrenheit = (GradiCelsius * 1.8) + 32
*
* 1. Dato l'array 'temperatureCelsius' fornito.
* 2. Usa il metodo .map() per creare un nuovo array 'temperatureFahrenheit'.
* 3. Assicurati che ogni numero venga convertito correttamente.
* 4. Stampa il nuovo array.
*/
let temperatureCelsius = [0, 10, 20, 30, 100];
// Scrivi qui il tuo codice usando .map()

View File

@@ -0,0 +1,18 @@
/**
* Esercizio Intermedio: Debugging Indici (CORREGGI IL CODICE)
*
* Obiettivo: Identificare e correggere un errore comune relativo agli indici degli array.
*
* Il codice sottostante dovrebbe stampare l'ultimo colore della lista ('Viola').
* Tuttavia, stampa 'undefined'. Perché?
*
* 1. Analizza il codice.
* 2. Correggi l'indice utilizzato nel console.log.
*/
let coloriArcobaleno = ['Rosso', 'Arancione', 'Giallo', 'Verde', 'Blu', 'Indaco', 'Viola'];
// CODICE NON FUNZIONANTE DA CORREGGERE
let ultimoColore = coloriArcobaleno[coloriArcobaleno.length];
console.log("L'ultimo colore è:", ultimoColore);

View File

@@ -0,0 +1,12 @@
/**
* Esercizio Intermedio: Gestione lista Pianeti
*
* Obiettivo: Manipolare un array aggiungendo e rimuovendo elementi.
*
* 1. Inizia con l'array 'pianeti' seguente: "Mercurio", "Venere", "Terra", "Marte".
* 2. Usa i metodi degli array per arrivare a questo risultato: ["Terra", "Giove"]
* 3. Stampa l'array risultante.
*
*/
// Scrivi qui il tuo codice

View File

@@ -0,0 +1,23 @@
/**
* Esercizio Extra: Debugging Inventario Negozio (CORREGGI IL CODICE)
*
* Obiettivo: Risolvere un bug logico dove l'array viene modificato in modo errato.
*
* Il codice dovrebbe rimuovere l'ultimo oggetto e aggiornare l'inventario,
* ma sembra che stia rimuovendo l'oggetto sbagliato o causando errori.
*
* 1. Esegui il codice (mentalmente o con Node) per vedere cosa succede.
* 2. Correggi la logica affinché 'Mouse' venga rimosso correttamente.
* 3. Assicurati che anche i prezzi vengano aggiornati correttamente.
*/
let inventario = ['Tastiera', 'Monitor', 'Laptop', 'Mouse'];
let prezzi = [20, 150, 800, 15];
prezzi.pop();
inventario[inventario.length] = 'Tablet';
inventario.shift();
prezzi[0] = 15;
console.log("Inventario rimasto:", inventario);
console.log("Prezzi attuali:", prezzi);

View File

@@ -0,0 +1,23 @@
/**
* Esercizio Extra: Simulatore Playlist Musicale
*
* Obiettivo: Combinare push, shift e la logica degli array per gestire una coda di riproduzione.
*
* Immagina di gestire una playlist dinamica:
* 1. Crea un array chiamato 'canzoni' con almeno 5 titoli di canzoni (stringhe).
* 2. Crea un array vuoto chiamato 'inCoda' che rappresenta la coda di riproduzione.
* 3. Aggiungi 3 canzoni casuali alla playlist 'inCoda':
* - Usa 'push' per aggiungere canzoni in coda.
* - Non rimuovere le canzoni dalla lista 'canzoni'.
* - Per selezionare l'indice casuale delle canzoni:
* 1. Usa Math.random() per generare un numero casuale.
* 2. Moltiplica per la lunghezza dell'array 'canzoni'.
* 3. Usa Math.floor() per ottenere un indice valido.
* - Non importa se ci sono duplicati nella playlist.
* 4. Simula la riproduzione della prima canzone in coda:
* - Stampa "In riproduzione: [Nome Canzone]"
* - Rimuovi quella canzone dalla lista 'inCoda'.
* 5. Stampa le canzoni rimanenti in coda e il numero totale di canzoni rimaste.
* 6. Esegui il codice e verifica che funzioni come previsto
* (ogni esecuzione dovrebbe dare risultati diversi a causa della casualità).
*/

View File

@@ -0,0 +1,14 @@
/**
* Esercizio Extra: Calcolo IVA Scontrino
*
* Obiettivo: Utilizzare .map() per calcoli finanziari su una lista.
*
* Hai una lista di prezzi netti. Devi calcolare il prezzo finale aggiungendo l'IVA al 22%.
*
* 1. Dato un array di prezzi netti: [100, 50, 200, 10].
* 2. Crea un nuovo array 'prezziIvati' usando .map().
* 3. La logica all'interno di map deve essere: prezzo * 1.22.
* 4. Formattare i numeri risultanti come stringhe con "€" davanti (es. "€122"), facendo una seconda map.
* 5. Stampa la lista dei prezzi finali.
* 6. Calcola il totale dei prezzi ivati e stampalo.
*/

View File

@@ -0,0 +1,99 @@
// TUTORIAL INTERATTIVO: Array e Metodi Fondamentali
// Segui gli step, leggi i commenti e completa i TODO.
// Esegui questo file con Node.js per verificare i risultati.
/**
* =============================================
* === 1. Creazione e Accesso tramite Indici ===
*
* Un array è una lista ordinata di elementi.
* Gli elementi sono numerati (indicizzati) partendo da 0.
* Esempio: let numeri = [10, 20, 30];
* numeri[0] è 10.
*/
let frutti = ['Mela', 'Banana', 'Ciegia'];
// TODO: Stampa in console il primo elemento ('Mela') e il terzo elemento ('Ciegia') usando gli indici.
/**
* ==================================
* === 2. Modifica degli Elementi ===
*
* Puoi cambiare il valore di un elemento esistente usando il suo indice.
* Esempio: numeri[1] = 99; (ora l'array è [10, 99, 30])
*/
let colori = ['Rosso', 'Verde', 'Blu'];
// TODO: Cambia 'Verde' in 'Giallo' accedendo all'indice corretto, poi stampa l'intero array.
/**
* ==============================
* === 3. La Proprietà Length ===
*
* La proprietà .length ti dice quanti elementi ci sono nell'array.
* L'ultimo indice è sempre (length - 1).
*/
let animali = ['Gatto', 'Cane', 'Coniglio', 'Criceto'];
// TODO: Stampa la lunghezza dell'array 'animali'
// TODO: Stampa l'ultimo elemento usando la proprietà length.
/**
* =====================================================
* === 4. Aggiungere e Rimuovere in Coda (push, pop) ===
*
* .push(elemento) aggiunge un elemento alla fine.
* .pop() rimuove l'ultimo elemento e lo restituisce.
*/
let stack = [1, 2, 3];
// TODO: Aggiungi il numero 7 all'array usando push.
// TODO: Poi rimuovi l'ultimo elemento usando pop e stampalo.
/**
* ========================================
* === 5. Rimuovere dalla Testa (shift) ===
*
* .shift() rimuove il PRIMO elemento dell'array.
* Attenzione: Tutti gli indici degli altri elementi scaleranno di 1.
*/
let fila = ['Primo', 'Secondo', 'Terzo'];
// TODO: Rimuovi il primo elemento della fila usando shift. Stampa l'array rimasto.
/**
* ===============================
* === 6. Ciclare gli Elementi ===
*
* Puoi usare un ciclo for per iterare su ogni elemento dell'array.
* O puoi usare un for...of per un approccio più semplice.
*/
let giorni = ['Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì'];
// TODO: Usa un ciclo for per stampare ogni elemento dell'array 'giorni'.
// TODO: Usa un ciclo for...of per fare lo stesso.
/**
* ===============================
* === 7. Trasformazione (map) ===
*
* .map() crea un NUOVO array trasformando ogni elemento del vecchio array secondo una funzione.
* Esempio: let doppi = numeri.map(n => n * 2);
*/
let prezzi = [10, 20, 30];
// TODO: Usa map per creare un nuovo array 'prezziScontati' dove ogni prezzo è diviso per 2.

View File

@@ -0,0 +1,12 @@
/**
* Esercizio Intermedio: Profilo Social
*
* Obiettivo: Creare e manipolare un oggetto che rappresenta un profilo utente.
*
* 1. Crea un oggetto 'utente' con: username, email, e online (booleano).
* 2. Dopo averlo creato, cambia lo stato di 'online' impostandolo al contrario di quello che è (es. se true diventa false).
* 3. Aggiungi una nuova proprietà 'biografia' con un testo a piacere.
* 4. Stampa l'oggetto finale.
*/
// Scrivi qui il tuo codice

View File

@@ -0,0 +1,17 @@
/**
* Esercizio Intermedio: Debugging Accesso Proprietà
*
* Il codice seguente genera un errore.
* L'intenzione è stampare una proprietà della pizza.
*
* 1. Analizza perché il codice fallisce.
* 2. Correggi il codice affinché stampi correttamente.
*/
let pizza = {
tipo: "Margherita",
prezzo: 7
};
console.log(pizza[tipo]);
console.log(pizza[prezzo]);

View File

@@ -0,0 +1,11 @@
/**
* Esercizio Intermedio: Aggiornamento Listino
*
* Obiettivo: Eseguire operazioni matematiche sui valori delle proprietà.
*
* 1. Crea un oggetto 'biglietto' con proprietà: 'tipo' ("Cinema") e 'costo' (10).
* 2. Immagina che ci sia uno sconto: sottrai 2 dal valore della proprietà 'costo'.
* 3. Stampa una frase: "Il biglietto per il [tipo] costa [costo] euro."
*/
// Scrivi qui il tuo codice

View File

@@ -0,0 +1,15 @@
/**
* Esercizio Extra: Carrello E-Commerce (Array di Oggetti)
*
* Obiettivo: Lavorare con una lista (Array) dove ogni elemento è un prodotto (Oggetto).
*
* 1. Crea un array chiamato 'carrello'.
* 2. Inserisci dentro l'array due oggetti prodotto manualmente.
* Ogni oggetto deve avere: 'nome' (stringa) e 'prezzo' (numero).
* Es: { nome: "Mouse", prezzo: 20 }, { nome: "Tastiera", prezzo: 50 }
* 3. Aggiungi un terzo prodotto all'array usando il metodo .push().
* Il prodotto è: { nome: "Monitor", prezzo: 100 }
* 4. Calcolo Totale: Crea una variabile 'totale' e calcola la somma dei prezzi dei tre prodotti.
* Usa un ciclo for per iterare sull'array 'carrello'.
* 5. Stampa: "Il totale del carrello è: [totale]"
*/

View File

@@ -0,0 +1,22 @@
/**
* Esercizio Extra: Dashboard Utente Complessa (Oggetti Annidati)
*
* Obiettivo: Accedere e modificare dati dentro oggetti che sono dentro altri oggetti.
*
* Struttura Dati:
* Hai un oggetto 'dashboard' che contiene le impostazioni di un utente.
*
* 1. Crea l'oggetto seguendo questa struttura:
* dashboard = {
* utente: "Admin",
* preferenze: {
* tema: "Scuro",
* notifiche: { email: true, sms: false }
* }
* }
* 2. Senza toccare la dichiarazione iniziale, modifica il valore di 'sms' in true.
* (Suggerimento: usa più punti, es. oggetto.livello1.livello2...)
* 3. Stampa in console solo il valore del 'tema'.
* 4. Aggiungi una nuova proprietà 'push' dentro l'oggetto 'notifiche' e impostala a true.
* 5. Stampa l'intero oggetto dashboard finale.
*/

View File

@@ -0,0 +1,24 @@
/**
* Esercizio Extra: Debugging Destrutturazione
*
* La "Destrutturazione" è un modo veloce per estrarre proprietà in variabili:
* const { nome } = persona; (Crea una variabile 'nome' col valore di persona.nome).
*
* Il codice sotto cerca di estrarre la città dell'utente, ma stampa 'undefined'.
*
* 1. Analizza la struttura dell'oggetto 'user'.
* 2. Correggi la riga della destrutturazione.
*/
const user = {
id: 1,
profilo: {
username: "anna92",
citta: "Roma"
}
};
// CODICE BUGGATO
const { citta } = user;
console.log("L'utente vive a:", citta);

View File

@@ -0,0 +1,84 @@
/**
* Esercizio Extra: Debugging Accesso Proprietà Oggetti
*
* Un cliente entra nella pizzeria e ordina alcune cose:
* - Una margherita
* - Un calzone ricotta e spinaci
* - Una birra
*
* Nel seguente codice sono presenti alcuni errori che impediscono
* il corretto calcolo del totale dell'ordine.
*
* 1. Analizza il codice e individua gli errori (dalla riga 73 in poi).
* 2. Correggi il codice in modo che stampi correttamente il totale dell'ordine.
* 3. Il totale corretto dell'ordine dovrebbe essere: 6 + 8 + 4 = 18
*
* Nota: il menù è un pò lungo e può dar fastidio ma si può
* minimizzare cliccando a sinistra del LET (appare una freccetta).
*
* [4 righe di codice da correggere, 6 errori in totale]
*/
let menu = [
{
tipo: "pizza",
nome: "margherita",
prezzo: 6
},
{
tipo: "pizza",
nome: "diavola",
prezzo: 8
},
{
tipo: "pizza",
nome: "quattro_stagioni",
prezzo: 9
},
{
tipo: "pizza",
nome: "vegetariana",
prezzo: 7
},
{
tipo: "calzone",
nome: "classico",
prezzo: 7
},
{
tipo: "calzone",
nome: "ricotta_e_spinaci",
prezzo: 8
},
{
tipo: "bevanda",
nome: "acqua",
prezzo: 2
},
{
tipo: "bevanda",
nome: "cola",
prezzo: 3
},
{
tipo: "bevanda",
nome: "birra",
prezzo: 4
}
];
let ordine = ["margherita", "ricotta_e_spinaci", "birra"];
let totaleOrdine = 0;
// CODICE BUGGATO
for (let i = 1; i < menu.length; i++) {
let oggetto = menu[i];
if (!ordine.includes(oggetto.tipo)) {
console.log(oggetto.tipo + ": €" + oggetto.prezzo);
totaleOrdine += oggetto.nome;
}
}
console.log("Totale: €" + totaleOrdine);

View File

@@ -0,0 +1,123 @@
// TUTORIAL INTERATTIVO: Oggetti in JavaScript
// Segui gli step, leggi i commenti e completa i TODO.
// Esegui questo file con Node.js per verificare i risultati.
/**
* ===========================================
* === 1. Creazione di un Oggetto ===
*
* Un oggetto è una collezione di coppie chiave-valore.
* Si usano le parentesi graffe { }.
* Esempio: let palla = { colore: "Rosso", dimensione: 10 };
*/
// TODO: Crea un oggetto chiamato 'persona' con le proprietà: 'nome' (stringa) e 'eta' (numero).
// TODO: Stampa l'intero oggetto in console.
// OUTPUT ATTESO: { nome: 'Mario', eta: 25 }
/**
* ===========================================
* === 2. Accesso con la "Dot Notation" (Punto) ===
*
* Per leggere un valore, usiamo il punto seguito dal nome della proprietà.
* Esempio: palla.colore
*/
let cane = {
razza: "Labrador",
colore: "Miele",
haIlGuinzaglio: true
};
// TODO: Stampa solo la razza del cane usando il punto.
// OUTPUT ATTESO: Labrador
/**
* ===========================================
* === 3. Accesso con la "Bracket Notation" (Parentesi Quadre) ===
*
* Possiamo anche usare le parentesi quadre e il nome della proprietà come stringa.
* Questo è utile se il nome della proprietà contiene spazi o caratteri speciali.
* Esempio: palla["colore"]
*/
let libro = {
"titolo libro": "Il Signore degli Anelli",
pagine: 500
};
// TODO: Stampa il titolo del libro usando le parentesi quadre e le virgolette.
// OUTPUT ATTESO: Il Signore degli Anelli
/**
* ===========================================
* === 4. Modifica di una Proprietà ===
*
* Gli oggetti sono mutabili. Puoi cambiare il valore di una proprietà esistente.
* Esempio: palla.colore = "Blu";
*/
let studente = {
nome: "Luca",
voto: 6
};
// TODO: Cambia il voto dello studente a 10. Poi stampa l'oggetto aggiornato.
// OUTPUT ATTESO: { nome: 'Luca', voto: 10 }
/**
* ===========================================
* === 5. Aggiungere/Rimuovere Proprietà ===
*
* Se assegni un valore a una proprietà che non esiste, JavaScript la crea.
* Esempio: palla.materiale = "Gomma";
*
* Puoi rimuovere una proprietà usando la parola chiave 'delete'.
* Esempio: delete palla.dimensione;
*/
let prodotto = {
id: 123,
nome: "Smartphone",
prezzo: 800
};
// TODO: Aggiungi una proprietà 'marca' con valore 'Samsung'.
// TODO: Rimuovi la proprietà 'id' dall'oggetto. Stampa l'oggetto finale.
// OUTPUT ATTESO: { nome: 'Smartphone', prezzo: 800, marca: 'Samsung' }
/**
* ===========================================
* === 6. Oggetti Annidati ===
*
* Le proprietà di un oggetto possono essere altri oggetti.
* Esempio: let auto = { motore: { tipo: "V8", cavalli: 400 } };
*/
let computer = {
marca: "Dell",
specifiche: {
ram: "16GB",
cpu: "Intel i7"
}
};
// TODO: Stampa la quantità di RAM del computer accedendo all'oggetto annidato.
// OUTPUT ATTESO: 16GB
/**
* ===========================================
* === 7. Destrutturazione di Oggetti ===
*
* La destrutturazione permette di estrarre proprietà da un oggetto in variabili.
* Esempio: let { colore, dimensione } = palla;
*/
// TODO: Destruttura l'oggetto 'computer' per ottenere 'marca' e 'specifiche' in variabili separate.
// TODO: Poi destruttura 'specifiche' per ottenere 'ram' e 'cpu' in variabili separate.

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Profilo Utente</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
<div class="card-container">
<div class="card-header">
<img id="img-profilo" src="https://placehold.co/150" alt="Foto Profilo">
<h2 id="nome-completo">Nome Cognome</h2>
<p id="ruolo" class="ruolo-badge">Ruolo</p>
</div>
<div class="card-body">
<div class="dettaglio">
<strong>Email:</strong>
<span id="email">...</span>
</div>
<div class="dettaglio">
<strong>Telefono:</strong>
<span id="telefono">...</span>
</div>
<div class="dettaglio">
<strong>Indirizzo:</strong>
<span id="indirizzo">...</span>
</div>
<div id="box-verifica" class="verifica nascosto">
✅ Utente Verificato
</div>
</div>
<div class="card-footer">
<button id="btn-stampa">Stampa Profilo</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,53 @@
// DATI (Oggetto Singolo)
// Immagina che questi dati arrivino da un server o da un database.
const utente = {
nome: "Giulia",
cognome: "Verdi",
eta: 30,
email: "giulia.verdi@example.com",
telefono: "+39 333 1234567",
indirizzo: "Via Roma 10, Milano",
professione: "Graphic Designer",
fotoUrl: "https://randomuser.me/api/portraits/women/44.jpg", // Url di una foto vera
verificato: true // Prova a mettere false per vedere cosa succede
};
// 1. SELEZIONE ELEMENTI DOM
// Esercizio: Completa i querySelector abbinando gli ID corretti presi dall'HTML
const elNomeCompleto = document.querySelector(''); // es. #nome-completo
const elRuolo = document.querySelector('');
const elEmail = document.querySelector('');
const elTelefono = document.querySelector('');
const elIndirizzo = document.querySelector('');
const elImmagine = document.querySelector('');
const boxVerifica = document.querySelector('');
/**
* 2. RIEMPIMENTO DATI
* Ora devi prendere i dati dall'oggetto 'utente' e metterli dentro gli elementi HTML.
*/
// A. Testo Semplice (textContent)
// elNomeCompleto.textContent = ...
// ...
// B. Attributi (src)
// elImmagine.src = ...
// ...
// C. Logica Condizionale
// Se l'utente è "verificato" (true), mostriamo il box verde.
// Altrimenti lo lasciamo nascosto (o lo nascondiamo esplicitamente).
/**
* 3. EVENTI
* Fai funzionare il bottone "Stampa Profilo"
* Quando cliccato, deve lanciare un alert() con scritto: "Sto stampando il profilo di [NOME]"
* Alert permette di mostrare un messaggio all'utente e bloccare l'esecuzione finché non preme "OK".
* Il suo utilizzo è semplice: alert("Messaggio da mostrare");
*/
const btnStampa = document.querySelector('#btn-stampa');

View File

@@ -0,0 +1,105 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
min-height: 100vh;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
color: #2c3e50;
}
.card-container {
background: white;
width: 320px;
border-radius: 20px;
overflow: hidden;
box-shadow: 0 15px 35px rgba(0,0,0,0.1);
text-align: center;
}
.card-header {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 30px 20px;
}
#img-profilo {
width: 100px;
height: 100px;
border-radius: 50%; /* Cerchio perfetto */
border: 4px solid white;
object-fit: cover;
margin-bottom: 10px;
}
h2 {
margin: 10px 0 5px 0;
font-size: 24px;
}
.ruolo-badge {
background: rgba(255, 255, 255, 0.2);
display: inline-block;
padding: 5px 15px;
border-radius: 20px;
font-size: 14px;
margin: 0;
}
.card-body {
padding: 20px;
text-align: left;
}
.dettaglio {
margin-bottom: 15px;
border-bottom: 1px solid #eee;
padding-bottom: 5px;
color: #555;
}
strong {
color: #333;
display: block;
font-size: 12px;
text-transform: uppercase;
letter-spacing: 1px;
}
.verifica {
text-align: center;
color: #27ae60;
font-weight: bold;
margin-top: 20px;
padding: 10px;
background-color: #e8f8f5;
border-radius: 5px;
}
.nascosto {
display: none;
}
.card-footer {
padding: 15px;
background: #f9f9f9;
}
button {
background: linear-gradient(to right, #667eea, #764ba2); /* Riprende l'header */
color: white;
border: none;
padding: 12px 25px;
border-radius: 30px; /* Bottone a pillola moderno */
cursor: pointer;
font-weight: bold;
box-shadow: 0 4px 15px rgba(118, 75, 162, 0.4);
transition: 0.2s;
}
button:hover {
transform: scale(1.05);
box-shadow: 0 6px 20px rgba(118, 75, 162, 0.6);
}

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Lista della Spesa</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
<div class="container">
<h1>🛒 Lista della Spesa</h1>
<div class="input-group">
</div>
<div class="totale-container">
</div>
<hr>
<ul id="lista-spesa">
</ul>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,93 @@
// DATI INIZIALI
// Questa lista funge da "Database" locale. Tutto ciò che vedi a schermo DEVE derivare da qui.
// Inizialmente contiene due prodotti di esempio (rimuovete se volete)
let lista = [
{ prodotto: 'Pane', prezzo: 1.50, sbarrato: false },
{ prodotto: 'Latte', prezzo: 1.20, sbarrato: false },
{ prodotto: 'Uova', prezzo: 2.30, sbarrato: false },
{ prodotto: 'Mele', prezzo: 0.80, sbarrato: true },
{ prodotto: 'Caffè', prezzo: 3.50, sbarrato: false }
];
// Pre-esercizi: RIFERIMENTI AL DOM
// Seleziona gli elementi necessari che DEVI definire nell'HTML se mancano
const inputProdotto = document.querySelector('');
const inputPrezzo = document.querySelector('');
const btnAggiungi = document.querySelector('');
const listaSpesa = document.querySelector('');
const contenitoreTotale = document.querySelector('');
/**
* FUNZIONE 1: Visualizza/Aggiorna Lista
* Questa funzione è il "motore" grafico. Deve:
* 1. Pulire la lista attuale nel DOM
* 2. Ciclare l'array 'lista'
* 3. Per ogni elemento, chiamare la funzione 'creaElementoLista'
* 4. Chiamare la funzione 'aggiornaTotale' alla fine per ricalcolare il conto
*/
function aggiornaLista() {
}
/**
* FUNZIONE 2: Crea Elemento HTML (li)
* Questa funzione si occupa di creare il singolo pezzetto di HTML.
* Deve:
* 1. Creare un tag <li>
* 2. Impostare il testo (es. "Pane - 1.50 €")
* 3. Se l'elemento ha la proprietà .sbarrato === true, aggiungere la classe CSS 'preso'
* 4. Gestire il click: se clicco sull'li, devo chiamare la funzione toggleSbarrato(elemento)
* 5. Appendere l'li alla listaSpesa (ul)
*/
function creaElementoLista(elemento) {
}
/**
* FUNZIONE 3: Gestione Click (Toggle Sbarrato)
* Questa funzione viene chiamata quando clicco su una riga.
* Non modifica il DOM direttamente! Deve:
* 1. Cambiare la proprietà 'sbarrato' dell'oggetto (da true a false o viceversa)
* 2. Richiamare aggiornaLista() per ridisegnare tutto aggiornato
*/
function toggleSbarrato(elemento) {
}
/**
* FUNZIONE 4: Calcola Totale
* Deve:
* 1. Creare una variabile somma = 0
* 2. Ciclare l'array 'lista'
* 3. Sommare i prezzi
* 4. (Opzionale) Somma solo quelli NON sbarrati
* 5. Scrivere il risultato nel contenitoreTotale
*/
function aggiornaTotale() {
}
/**
* EVENTO PRINCIPALE: Click su Aggiungi
* 1. Leggere i valori degli input (value)
* Nota che il prezzo deve essere convertito in numero.
* Per farlo usa parseFloat(valore) o Number(valore)
* 2. Validazione: se i campi sono pieni e il prezzo > 0
* 3. Creare un nuovo oggetto { prodotto: ..., prezzo: ..., sbarrato: false }
* 4. Aggiungerlo all'array 'lista' (push)
* 5. Richiamare aggiornaLista()
* 6. Svuotare gli input
*/
btnAggiungi.addEventListener('click', function () {
});
// AVVIO
// Chiamata iniziale per mostrare i dati di esempio (Pane e Latte)
aggiornaLista();

View File

@@ -0,0 +1,112 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
min-height: 100vh;
margin: 0;
padding: 20px;
display: flex;
justify-content: center;
align-items: center;
color: #2c3e50;
}
.container {
background: white;
width: 450px;
padding: 30px;
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
}
.input-group {
display: flex;
gap: 10px;
margin-bottom: 20px;
flex-wrap: wrap;
}
input {
padding: 12px;
border: 2px solid #eee;
background-color: #f9f9f9;
border-radius: 10px;
flex: 1;
font-size: 1rem;
transition: 0.3s;
}
input:focus {
border-color: #007bff;
background-color: #fff;
outline: none;
}
/* Facciamo l'input del prezzo un po' più piccolo */
input[type="number"] {
flex: 0 0 80px;
}
button {
padding: 12px 25px;
background: linear-gradient(135deg, #28a745 0%, #218838 100%);
color: white;
border: none;
border-radius: 10px;
cursor: pointer;
font-weight: bold;
box-shadow: 0 4px 10px rgba(40, 167, 69, 0.3);
transition: transform 0.2s;
}
button:hover {
transform: translateY(-2px);
}
ul {
list-style: none;
padding: 0;
}
li {
background: #fff;
border: 1px solid #eee;
margin-bottom: 8px;
border-radius: 8px;
padding: 15px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
transition: all 0.2s;
box-shadow: 0 2px 5px rgba(0,0,0,0.02);
}
li:hover {
background-color: #f8f9fa;
transform: translateX(5px);
border-color: #007bff;
}
h1 {
text-align: center;
color: #333;
}
.totale-container {
text-align: right;
font-size: 1.2em;
font-weight: bold;
color: #333;
margin-bottom: 10px;
}
/* Stili per la lista */
/* ESERCIZIO CSS:
Aggiungi qui sotto la classe .preso
Deve avere:
- testo sbarrato (text-decoration: line-through)
- colore grigino
- sfondo un po' scuro
*/

View File

@@ -0,0 +1,43 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Gestionale Dipendenti</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold; font-size: 14px;">← Dashboard</a>
<h1>Gestione Dipendenti</h1>
<div class="controls">
<div>
<h3>Aggiungi Nuovo</h3>
<input type="text" id="input-nome" placeholder="Nome">
<input type="text" id="input-ruolo" placeholder="Ruolo">
<button id="btn-aggiungi">Aggiungi</button>
</div>
<div>
<h3>Cerca</h3>
<input type="text" id="input-ricerca" placeholder="Cerca per nome...">
</div>
<div>
<!-- <h3>Azioni</h3> -->
<!-- Zona per extra bottoni futuri -->
</div>
</div>
<table>
<thead>
<tr>
<th>Nome</th>
<th>Ruolo</th>
<th>Azioni</th>
</tr>
</thead>
<tbody id="tabella-corpo">
</tbody>
</table>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,137 @@
// DATI INIZIALI
const dipendenti = [
{ nome: "Mario Rossi", ruolo: "Sviluppatore" },
{ nome: "Luigi Bianchi", ruolo: "Sviluppatore" },
{ nome: "Paolo Gialli", ruolo: "Sviluppatore" },
{ nome: "Anna Neri", ruolo: "Sviluppatore" },
{ nome: "Carlo Verdi", ruolo: "Project Manager" },
{ nome: "Luca Bianchi", ruolo: "Designer" },
];
// RIFERIMENTI DOM
const tbody = document.querySelector('#tabella-corpo');
const btnAggiungi = document.querySelector('#btn-aggiungi');
const inputNome = document.querySelector('#input-nome');
const inputRuolo = document.querySelector('#input-ruolo');
const inputRicerca = document.querySelector('#input-ricerca');
/**
* FUNZIONE PRINCIPALE: Visualizza Tabella
* Questa funzione deve:
* - Pulire il contenuto del tbody
* - Per ogni dipendente nell'array passato come argomento:
* - Creare una riga (usando la funzione creaRiga)
* - Aggiungere la riga al tbody
*/
function visualizzaTabella(lista) {
}
/**
* FUNZIONE 1: Crea Riga
* Questa funzione deve:
* - Creare una riga (tr)
* - Creare 3 celle (td): Nome, Ruolo, Azioni
* - Popolare le celle Nome e Ruolo con i dati corretti
* - Nella cella Azioni, aggiungere un bottone "Elimina"
* - Aggiungere un event listener al bottone "Elimina" per rimuovere il dipendente dall'array e visualizzare la tabella
* - Aggiungere le tre celle alla riga
* - Aggiungere la riga al tbody
*
* Nota: Usare il metodo dipendenti.splice(i, 1) per rimuovere l'elemento dall'array
* e poi richiamare visualizzaTabella(dipendenti) per mostrare la tabella aggiornata.
*/
function creaRiga(dipendente, indice) {
}
/**
* FUNZIONE 2: Aggiungi Dipendente
* 1. Leggere i valori degli input
* 2. SE non sono vuoti:
* - Creare un oggetto { nome: ..., ruolo: ... }
* - Aggiungerlo all'array 'dipendenti'
* - Richiamare visualizzaTabella() per aggiornare la vista
* - Pulire gli input (settarli a stringa vuota)
*/
btnAggiungi.addEventListener('click', () => {
});
/**
* FUNZIONE 3: Ricerca
* 1. Leggere il testo nel campo ricerca
* 2. Filtrare l'array 'dipendenti' usando:
* - array.filter()
* - dipendente.nome.includes(testoRicerca)
* 3. Passare l'array filtrato a visualizzaTabella()
*/
inputRicerca.addEventListener('input', () => {
});
/**
* FUNZIONE 4: Emoji per Ruolo
* Aggiungere automaticamente un'emoji accanto al nome in base al ruolo.
*
* Passi:
* 1. Sviluppa la funzione getEmojiPerRuolo(ruolo) che ritorna:
* - "💻" per "Sviluppatore"
* - "🎨" per "Designer"
* - "👤" per altri ruoli
* 2. Modifica la funzione creaRiga per usare getEmojiPerRuolo
* 3. Usare la concatenazione stringhe per la cellaNome.textContent = emoji + " " + dipendente.nome;
*/
function getEmojiPerRuolo(ruolo) {
// Implementa la logica qui
}
// AVVIO
// Chiamare visualizzaTabella(dipendenti) all'inizio per mostrare i dati iniziali
visualizzaTabella(dipendenti);
/************************************************************************/
/************************* ESERCIZI EXTRA *******************************/
/************************************************************************/
/** ESERCIZIO EXTRA:
* Migliorare la funzione creaRiga per aggiungere una classe CSS speciale
* alle righe dei dipendenti che sono "Project Manager".
*
* Passi:
* 1. Aggiungi una classe .manager (o .evidenziato) che evidenzi la riga (es. background-color: #feffae;)
* 2. Modificare la funzione creaRiga:
* - Controllare se dipendente.ruolo === "Project Manager"
* - Se vero, aggiungere una classe CSS speciale alla riga (es. riga.classList.add('manager'))
*/
/** ESERCIZIO EXTRA 2:
* Aggiungere nel file index.html un bottone "Elimina Tutti" sopra la tabella.
*
* Passi:
* 1. Aggiungere il bottone con un id specifico (es. id="btn-elimina-tutti")
* 2. Stilizzare il bottone con CSS se necessario (colore rosso per esempio)
* 3. Aggiungere un event listener al bottone nel file script.js
* 4. Nell'event listener, svuotare l'array dipendenti (es. dipendenti.length = 0)
* 5. Richiamare visualizzaTabella(dipendenti) per aggiornare la vista
*/
/**
* ESERCIZIO EXTRA 3:
* Aggiungere un contatore sopra la tabella che mostra il numero totale di dipendenti.
*
* Passi:
* 1. Aggiungere un elemento HTML (es. un div o span) con un id specifico (es. id="contatore-dipendenti")
* 2. Mettere questo elemento sopra la tabella e stilizzarlo con CSS (metterlo almeno a destra)
* 3. Creare una funzione aggiornaContatore()
* - Questa funzione deve aggiornare il contenuto dell'elemento contatore con il numero di dipendenti (es. dipendenti.length)
* 4. Chiamare aggiornaContatore() ogni volta che la tabella viene aggiornata (dopo aggiungere, eliminare, o filtrare dipendenti)
*/

View File

@@ -0,0 +1,114 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; /* Stesso font dashboard */
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); /* Stesso sfondo dashboard */
min-height: 100vh;
margin: 0;
padding: 20px;
justify-content: center;
align-items: center;
color: #2c3e50;
display: block;
padding: 40px;
}
.controls {
background: white;
padding: 25px;
border-radius: 15px;
border: none;
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
margin-bottom: 30px;
}
/* Esempio di combinatore figlio diretto (>) */
.controls > div {
border-bottom: 1px solid #f0f0f0;
}
.controls > div:last-child {
border-bottom: none;
}
input[type="text"] {
padding: 10px;
border: 1px solid #ddd;
border-radius: 6px;
background: #f9f9f9;
}
button {
padding: 10px 20px;
background-color: #007bff; /* Blu base */
color: white;
border: none;
border-radius: 6px;
cursor: pointer;
}
table {
width: 100%;
border-collapse: separate; /* Necessario per border-radius sulla tabella */
border-spacing: 0;
margin-top: 20px;
background: white;
border-radius: 15px;
overflow: hidden; /* Taglia gli angoli */
box-shadow: 0 10px 30px rgba(0,0,0,0.05);
}
th {
background: linear-gradient(135deg, #007bff 0%, #0056b3 100%);
color: white;
padding: 15px;
text-transform: uppercase;
font-size: 0.85rem;
letter-spacing: 1px;
border: none;
}
td {
border-bottom: 1px solid #eee;
padding: 15px;
color: #555;
}
tr:last-child td {
border-bottom: none;
}
/************************************************************/
/* ESERCIZI CSS: "RECUPERA GLI STILI PERSI" */
/* Usa solo selettori di TAG, ID (#), CLASSI (.) */
/* e combinatori di SPAZIO (discendente) */
/************************************************************/
/* LIVELLO 1: Il bottone Elimina (Discendenza)
Il bottone "Elimina" non ha classi, ma sappiamo che sta DENTRO il tbody.
Seleziona tutti i button che sono dentro il #tabella-corpo.
Obiettivo: Sfondo rosso (#ff4444), testo bianco, nessun bordo.
*/
/* LIVELLO 2: Interattività (Hover su discendente)
Vogliamo che il bottone elimina diventi più scuro quando ci passi sopra.
Obiettivo: Cambia il background-color in #cc0000 al passaggio del mouse.
Suggerimento: usa lo stesso selettore di prima + :hover
*/
/* LIVELLO 3: Leggibilità Riga (Hover su riga)
Vogliamo evidenziare tutta la riga (tr) della tabella quando il mouse ci passa sopra.
ATTENZIONE: Deve succedere solo nel corpo della tabella, non nell'intestazione!
Obiettivo: Background-color grigio chiaro (#f1f1f1) al passaggio del mouse sulla riga.
*/
/* LIVELLO 4 (Extra): Focus sugli Input
Vogliamo evidenziare gli input di testo quando l'utente ci clicca dentro (:focus).
Ma solo quelli dentro la zona .controls!
Obiettivo: Bordo blu (2px solid blue) e sfondo giallo chiaro (#ffffe0).
*/

View File

@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hub Esercizi DOM</title>
<style>
/* RESET & BASE */
* { box-sizing: border-box; }
body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); margin: 0; padding: 40px; min-height: 100vh; display: flex; align-items: center; justify-content: center; }
/* CONTENITORE PRINCIPALE */
.hub-container { background: white; width: 100%; max-width: 600px; padding: 40px; border-radius: 20px; box-shadow: 0 15px 35px rgba(0,0,0,0.1); }
h1 { text-align: center; color: #333; margin-bottom: 10px; font-size: 2.5rem; }
p.subtitle { text-align: center; color: #666; margin-bottom: 40px; font-size: 1.1rem; }
/* LISTA CARD */
.exercise-list { display: flex; flex-direction: column; gap: 20px; }
/* CARD ESERCIZIO */
.card { display: flex; align-items: center; text-decoration: none; background: #fff; border: 2px solid #eee; border-radius: 12px; padding: 20px; transition: all 0.3s ease; position: relative; overflow: hidden; }
.card:hover { transform: translateY(-5px); border-color: #007bff; box-shadow: 0 10px 20px rgba(0,123,255,0.15); }
/* ICONA E TESTI */
.icon { font-size: 2.5rem; margin-right: 20px; width: 50px; text-align: center; }
.info { flex: 1; }
.info h3 { margin: 0 0 5px 0; color: #2c3e50; font-size: 1.2rem; }
.info p { margin: 0; color: #7f8c8d; font-size: 0.9rem; }
/* TAG DIFFICOLTA' */
.badge { font-size: 0.75rem; font-weight: bold; padding: 4px 8px; border-radius: 6px; text-transform: uppercase; letter-spacing: 1px; margin-left: 10px; white-space: nowrap; }
.easy { background-color: #e8f5e9; color: #2e7d32; } /* Verde */
.medium { background-color: #fff3e0; color: #ef6c00; } /* Arancione */
.hard { background-color: #ffebee; color: #c62828; } /* Rosso */
/* FRECCIA AL PASSAGGIO DEL MOUSE */
.arrow { font-size: 1.5rem; color: #ccc; transition: 0.3s; }
.card:hover .arrow { color: #007bff; transform: translateX(5px); }
</style>
</head>
<body>
<div class="hub-container">
<h1>Esercizi DOM</h1>
<p class="subtitle">Corso Web Developer</p>
<div class="exercise-list">
<a href="01_card_profilo/index.html" class="card">
<div class="icon">👤</div>
<div class="info">
<h3>1. Profilo Utente <span class="badge easy">Base</span></h3>
<p>Manipolazione statica, Oggetti e attributi.</p>
</div>
<div class="arrow"></div>
</a>
<a href="02_lista_spesa/index.html" class="card">
<div class="icon">🛒</div>
<div class="info">
<h3>2. Lista Spesa <span class="badge medium">Intermedio</span></h3>
<p>Array, Cicli, Creazione elementi e Totali.</p>
</div>
<div class="arrow"></div>
</a>
<a href="03_gestionale/index.html" class="card">
<div class="icon">💼</div>
<div class="info">
<h3>3. Gestionale <span class="badge hard">Avanzato</span></h3>
<p>Tabelle, Filtri di ricerca, aggiunta/rimozione dipendenti.</p>
</div>
<div class="arrow"></div>
</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,19 @@
/**
* ESERCIZIO 1: Selezione e Lettura
*
* ISTRUZIONI:
* 1. Usa `document.querySelector` per selezionare l'h1 con id 'titolo-principale'.
* - Stampa in console il suo `textContent`.
*
* 2. Usa `document.querySelector` per selezionare l'elemento con classe '.prezzo'.
* - Stampa in console il suo `textContent`.
*
* 3. Usa `document.querySelector` per selezionare l'immagine 'img-prodotto'.
* - Stampa in console il valore del suo attributo `src` (puoi usare .src o .getAttribute('src')).
* - Stampa in console il valore del suo attributo `alt`.
*
* 4. Usa `document.querySelectorAll` per trovare tutti i `div` nella pagina.
* - Stampa in console quanti div ci sono (usa la proprietà .length della lista risultante).
*/
// Scrivi qui sotto il tuo codice:

View File

@@ -0,0 +1,20 @@
/**
* ESERCIZIO 2: Modifica Stile e Classi
*
* ISTRUZIONI:
* 1. Seleziona il div con id 'messaggio-sistema'.
* - Cambia il suo `style.backgroundColor` in '#ccffcc' (verde chiaro).
* - Cambia il suo `style.border` in '2px solid green'.
* - Cambia il suo `style.color` in 'green'.
*
* 2. Seleziona il titolo h1 ('titolo-principale').
* - Cambia il suo `style.textAlign` in 'center'.
* - Cambia il suo `style.textTransform` in 'uppercase'.
*
* 3. Seleziona il div con id 'status-magazzino'.
* - Al momento ha la classe 'out-of-stock' (scritta rossa barrata).
* - Usa `classList.remove('out-of-stock')` per togliere lo stile vecchio.
* - Usa `classList.add('in-stock')` per aggiungere lo stile nuovo (scritta verde).
*/
// Scrivi qui sotto il tuo codice:

View File

@@ -0,0 +1,22 @@
/**
* ESERCIZIO 3: Modifica Testo e Attributi
*
* ISTRUZIONI:
* 1. Il messaggio di sistema dice "ERRORE DI SISTEMA...".
* - Selezionalo e cambia il suo `textContent` in "Sistema Operativo: Tutto OK!".
*
* 2. Il prodotto è sconosciuto.
* - Seleziona l'elemento con id 'nome-prodotto'.
* - Cambia il suo testo in "Smartphone Super 3000".
*
* 3. Manca la descrizione.
* - Seleziona il paragrafo con classe '.descrizione' (usa querySelector).
* - Cambia il suo `innerHTML` inserendo: "Ultimo modello <b>disponibile ora</b> in offerta.".
*
* 4. L'immagine è un placeholder.
* - Seleziona l'immagine.
* - Cambia il suo attributo `src` in 'https://placehold.co/300x150/0000FF/0000FF'.
* - Cambia il suo attributo `alt` in 'Foto Smartphone Blu'.
*/
// Scrivi qui sotto il tuo codice:

View File

@@ -0,0 +1,16 @@
/**
* Esercizio Intermedio 1: Il Semaforo (Manipolazione Stili e Classi)
*
* OBIETTIVO:
* Simulare l'accensione delle luci di un semaforo modificando il colore di sfondo.
*
* ISTRUZIONI:
* 1. Seleziona i tre div delle luci (id: 'luce-rossa', 'luce-gialla', 'luce-verde').
* 2. Seleziona i due bottoni (id: 'btn-attiva-rosso', 'btn-attiva-verde').
* 3. Aggiungi un event listener al bottone "Attiva Rosso":
* - Deve cambiare il background della luce rossa da '#500' a '#f00' (o 'red').
* - Deve spegnere le altre luci (impostando il background a '#550' o '#050').
* 4. Fai lo stesso per il bottone "Attiva Verde" (luce passa da '#050' a '#0f0' o 'green').
*/
// Scrivi qui il tuo codice...

View File

@@ -0,0 +1,18 @@
/**
* Esercizio Intermedio 2: Contatore Click (Eventi e Testo)
*
* OBIETTIVO:
* Creare un contatore che aumenta ogni volta che si preme un bottone.
*
* ISTRUZIONI:
* 1. Seleziona lo span che contiene il numero (id: 'contatore-valore') e i bottoni.
* 2. Crea una variabile let `conteggio` inizializzata a 0.
* 3. Al click su 'btn-incrementa':
* - Aumenta la variabile `conteggio` di 1.
* - Aggiorna il testo dello span con il nuovo valore.
* 4. Al click su 'btn-reset':
* - Riporta `conteggio` a 0.
* - Aggiorna il testo dello span.
*/
// Scrivi qui il tuo codice...

View File

@@ -0,0 +1,20 @@
/**
* Esercizio Intermedio 3: Debugging (Trova l'errore)
*
* DESCRIZIONE:
* Il codice qui sotto dovrebbe colorare di blu TUTTI i paragrafi con classe 'testo-colorato'
* quando si preme il bottone. Ma non funziona o genera errore.
*
* TASK:
* 1. Apri la console e leggi l'errore quando clicchi il bottone.
* 2. Capisci perché `style` non funziona.
* 3. Correggi il codice.
*/
const bottone = document.getElementById('btn-colora-tutti');
const paragrafi = document.querySelectorAll('.testo-colorato');
bottone.addEventListener('click', function() {
paragrafi.style.color = 'blue';
console.log("Colorati!");
});

View File

@@ -0,0 +1,86 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Esercizi DOM</title>
<style>
body { font-family: sans-serif; padding: 20px; max-width: 800px; margin: 0 auto }
section { border: 1px solid #bbb; padding: 15px; margin-bottom: 30px; border-radius: 8px; background-color: #f9f9f9}
h2 { background: #eee; padding: 10px; margin-top: 0; }
/* Stili comuni agli esercizi della parte 1 */
.scheda-prodotto { border: 1px solid #ccc; padding: 15px; background: white; border-radius: 8px; max-width: 300px; margin-bottom: 20px; }
.prezzo { font-weight: bold; color: #333; }
.in-stock { color: green; }
.out-of-stock { color: red; text-decoration: line-through; }
.nascosto { display: none; }
#messaggio-sistema { padding: 10px; background: #ffcccc; border: 1px solid red; color: darkred; margin-bottom: 20px; }
/* Stili per esercizi della parte 2 */
.esercizio-box { min-height: 50px; border: 1px dashed #999; padding: 10px; margin: 10px 0; }
.error { color: red; }
.success { color: green; }
</style>
</head>
<body>
<h1>Pagina Esercizi</h1>
<p>Collega <strong>TUTTI</strong> gli script in fondo a questa pagina per risolvere gli esercizi.</p>
<!-- Sezione iniziale comune a tutti gli esercizi della parte 1 -->
<section id="es-init">
<h2 id="titolo-principale">Benvenuti nel Negozio</h2>
<div id="messaggio-sistema">ERRORE DI SISTEMA: Connessione persa.</div>
<div class="scheda-prodotto">
<img id="img-prodotto" src="" alt="Immagine Generica">
<h2 id="nome-prodotto">Prodotto Sconosciuto</h2>
<p class="descrizione">Descrizione non disponibile al momento.</p>
<p class="prezzo">€ 0.00</p>
<div id="status-magazzino" class="out-of-stock">Esaurito</div>
</div>
</section>
<!-- Gli esercizi della parte 2 iniziano qui, ognuno in una sezione separata -->
<section id="es-base">
<h2>Esercizio 1: Il Semaforo</h2>
<div id="semaforo" style="width: 50px; height: 150px; background: #333; padding: 10px; display: flex; flex-direction: column; gap: 10px;">
<div id="luce-rossa" style="width: 50px; height: 50px; background: #500; border-radius: 50%;"></div>
<div id="luce-gialla" style="width: 50px; height: 50px; background: #550; border-radius: 50%;"></div>
<div id="luce-verde" style="width: 50px; height: 50px; background: #050; border-radius: 50%;"></div>
</div>
<br>
<button id="btn-attiva-rosso">Attiva Rosso</button>
<button id="btn-attiva-verde">Attiva Verde</button>
</section>
<section id="es-contatore">
<h2>Esercizio 2: Contatore Click</h2>
<p>Numero di click: <span id="contatore-valore">0</span></p>
<button id="btn-incrementa">Cliccami (+)</button>
<button id="btn-reset">Reset</button>
</section>
<section id="es-debug">
<h2>Esercizio 3: Debug Colori</h2>
<p class="testo-colorato">Paragrafo 1</p>
<p class="testo-colorato">Paragrafo 2</p>
<p class="testo-colorato">Paragrafo 3</p>
<button id="btn-colora-tutti">Colora Tutti di Blu</button>
</section>
<!-- Sezione extra per esercizi opzionali -->
<section id="zona-extra">
<h2>Zona Extra</h2>
<div id="container-extra-debug" class="esercizio-box"></div>
<div id="container-extra-box" class="esercizio-box"></div>
<div id="container-extra-validatore" class="esercizio-box"></div>
</section>
<!-- Script collegati della parte 1 -->
<script src="esercizi1/lettura.js"></script>
<script src="esercizi1/modifica_stile.js"></script>
<script src="esercizi1/modifica_testo.js"></script>
<!-- Collega qui i tuoi script per la parte 2 & extra -->
</body>
</html>

View File

@@ -0,0 +1,30 @@
/**
* Esercizio Extra: Debug Avanzato (Problemi di Logica DOM)
*
* DESCRIZIONE:
* Vogliamo spostare un elemento da una lista A a una lista B al click.
* Il codice sotto crea le liste dinamicamente, ma c'è un problema logico o di selezione.
*
* TASK:
* 1. Analizza il codice, includilo nel file HTML, ed eseguilo.
* 2. Il problema: Il codice tenta di aggiungere un event listener a un elemento che forse non esiste ancora o sbaglia il riferimento.
* 3. Correggi il codice affinché cliccando su 'item-1', questo si sposti nella Lista B.
*/
// Setup del DOM per l'esercizio
// NON TOCCARE QUESTA PARTE, SERVE PER L'ESERCIZIO
const container = document.getElementById('container-extra-debug');
container.innerHTML = `
<ul id="lista-a"><li>Item 1</li></ul>
<ul id="lista-b"></ul>
`;
// CODICE BUGGATO:
const item = document.querySelector('li');
const listaB = document.getElementById('lista-b');
// Vogliamo che al click, l'item vada nella lista B
item.addEventListener('click', function () {
// Codice attuale che non fa nulla o da errore se non completato:
listaB.innerHTML = item;
});

View File

@@ -0,0 +1,16 @@
/**
* Esercizio Extra: Generatore di Box (Creazione complessa)
*
* OBIETTIVO:
* Creare una griglia di quadrati colorati generati dinamicamente.
*
* ISTRUZIONI:
* 1. Seleziona il div 'container-extra-box' nella pagina esercizi.html.
* 2. Crea un array di colori: const colori = ['red', 'blue', 'green', 'orange', 'purple'];
* 3. Usa un ciclo `for` che va da 0 a 4 (o lunghezza array):
* - Crea un nuovo `div`.
* - Assegnagli una larghezza e altezza di 100px.
* - Assegnagli il colore di sfondo prendendolo dall'array in base all'indice.
* - Aggiungi un evento 'click' al div: quando cliccato, il div deve rimuoversi da solo (`this.remove()`).
* - Aggiungi il div al 'container-extra-box'.
*/

View File

@@ -0,0 +1,16 @@
/**
* Esercizio Extra: Validatore Input (Logica e Stili)
*
* OBIETTIVO:
* Creare un campo input che cambia colore se il testo è troppo corto.
*
* ISTRUZIONI (Usa 'container-extra-validatore' per generare l'HTML necessario via JS o scrivilo a mano):
* 1. Crea/Inserisci un input type="text" e un paragrafo per il messaggio di errore.
* 2. Ascolta l'evento 'input' (mentre l'utente scrive).
* 3. Se la lunghezza del valore (`value.length`) è inferiore a 5 caratteri:
* - Bordo dell'input: Rosso.
* - Messaggio: "Troppo corto!".
* 4. Se la lunghezza è 5 o più:
* - Bordo dell'input: Verde.
* - Messaggio: "OK!".
*/

View File

@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Tutorial DOM Parte 1</title>
<style>
body { font-family: sans-serif; padding: 20px; }
.tutorial { border: 2px solid #000; padding: 15px; margin-bottom: 30px; }
.box { padding: 20px; border: 1px solid #ccc; margin-top: 10px; }
.evidenziato { background-color: yellow; font-weight: bold; }
.nascosto { display: none; }
ul { list-style-type: none; padding: 0; }
li { background: #f0f0f0; margin: 5px 0; padding: 10px; border-bottom: 1px solid #ddd; cursor: pointer; }
li:hover { background: #e0e0e0; }
#area-messaggi { margin-top: 20px; padding: 10px; border: 1px dashed blue; min-height: 50px; }
input { padding: 5px; width: 200px; display: block; margin-bottom: 10px; }
</style>
</head>
<body>
<div class="tutorial">
<h1 id="titolo-principale">Tutorial DOM</h1>
<div id="contenitore-info">
<p class="paragrafo-testo">Questo è il primo paragrafo.</p>
<p class="paragrafo-testo">Questo è il secondo paragrafo.</p>
<p id="paragrafo-unico">Questo paragrafo ha un ID speciale.</p>
</div>
<input type="text" id="input-nome" placeholder="Inserisci il tuo nome">
<a id="link-google" href="#">Link vuoto</a>
<div id="box-stile" class="box">Modifica il mio stile!</div>
</div>
<div class="tutorial">
<h1>Tutorial DOM<br>Creazione ed Eventi</h1>
<div id="controlli">
<button id="btn-aggiungi">Aggiungi Elemento</button>
<button id="btn-rimuovi-tutti">Rimuovi Tutti</button>
</div>
<h3>Lista Dinamica:</h3>
<ul id="lista-dinamica">
<li>Elemento Esistente 1</li>
<li>Elemento Esistente 2</li>
</ul>
<h3>Area Input:</h3>
<input type="text" id="input-utente" placeholder="Scrivi qualcosa...">
<p>Hai scritto: <span id="output-testo"></span></p>
</div>
<script src="tutorial_interattivo_parte1.js"></script>
<script src="tutorial_interattivo_parte2.js"></script>
</body>
</html>

View File

@@ -0,0 +1,73 @@
// TUTORIAL INTERATTIVO: DOM Parte 1 - Selezione e Manipolazione
// Apri il file 'tutorial_parte1.html' nel browser e guarda la CONSOLE (F12).
/**
* ===========================================
* === 1. Selezionare tramite ID ===
* Il metodo `querySelector` seleziona un singolo elemento.
* Possiamo usare un selettore CSS per identificare l'elemento.
*/
// TODO: Seleziona l'elemento h1 con id 'titolo-principale' e salvalo in una variabile.
// TODO: Stampa la variabile in console.
// TODO: Seleziona l'elemento p e salvalo in una variabile.
// TODO: Stampa la variabile in console e verifica q chi appartiene il paragrafo.
/**
* ===========================================
* === 2. QuerySelectorAll ===
* `querySelector` trova il PRIMO elemento che corrisponde al selettore CSS.
* `querySelectorAll` trova TUTTI gli elementi e restituisce una lista.
*/
// TODO: Usa `querySelectorAll` per selezionare tutti gli elementi con classe 'paragrafo-testo'.
// TODO: Usa `querySelectorAll` per selezionare tutti gli elementi p nella pagina.
// TODO: Stampa entrambi i risultati in console.
/**
* ===========================================
* === 3. Modificare Testo e HTML ===
* `textContent` modifica solo il testo visibile.
* `value` modifica il valore di input (es. campi di testo).
* `innerHTML` può inserire tag HTML all'interno dell'elemento.
*/
// TODO: Cambia il testo dell'elemento 'titolo-principale' in "Workshop JavaScript".
// TODO: Cambia il valore dell'input con id 'input-nome' a "Mario Rossi".
// TODO: Cambia il testo del paragrafo con id 'paragrafo-unico' in "<b>Testo in grassetto</b>".
// TODO: Usa `innerHTML` al posto di `textContent` per inserire il testo in grassetto.
/**
* ===========================================
* === 4. Leggere e Modificare Attributi ===
* `getAttribute` legge un valore (es. href, src, id).
* `setAttribute` imposta un nuovo valore.
* Un attributo si può anche accedere direttamente come proprietà dell'elemento.
*/
// TODO: Seleziona il link con id 'link-google'.
// TODO: Imposta il suo attributo 'href' a 'https://www.google.com'.
// TODO: Cambia il testo del link in "Vai a Google".
/**
* ===========================================
* === 5. Modificare lo Stile (CSS) ===
* Puoi accedere alle proprietà CSS tramite l'oggetto `.style`.
* Le proprietà usano il camelCase (es. background-color diventa backgroundColor).
*/
// TODO: Seleziona il div con id 'box-stile'.
// TODO: Cambia il suo `style.color` in 'red'.
// TODO: Cambia il suo `style.border` in '2px solid red'.
/**
* ===========================================
* === 6. Gestire le Classi CSS ===
* `classList` permette di aggiungere, rimuovere o alternare classi CSS.
* Metodi utili: .add(), .remove(), .toggle().
*/
// TODO: Seleziona nuovamente il div 'box-stile'.
// TODO: Aggiungi la classe 'evidenziato' (definita nel CSS) usando `classList.add`.
// TODO: Rimuovi la classe 'box' usando `classList.remove`.
// TODO: Alterna la classe 'box' o la classe 'evidenziato' usando `classList.toggle`.

View File

@@ -0,0 +1,60 @@
// TUTORIAL INTERATTIVO: DOM Parte 2 - Creazione, Rimozione ed Eventi
// Apri il file 'tutorial_parte2.html'.
/**
* ===========================================
* === 1. Creazione di Elementi ===
* `document.createElement(tagName)` crea un nuovo elemento in memoria (non ancora visibile).
*/
// TODO: Crea un nuovo elemento 'li' e salvalo in una variabile chiamata `nuovoElemento`.
// TODO: Imposta il suo `textContent` a "Sono un nuovo elemento creato via JS".
/**
* ===========================================
* === 2. Aggiunta di Elementi al DOM ===
* `genitore.appendChild(figlio)` o `genitore.append(figlio)` aggiunge l'elemento alla pagina.
*/
// TODO: Seleziona la lista `ul` con id 'lista-dinamica'.
// TODO: Aggiungi `nuovoElemento` alla lista usando `appendChild`.
/**
* ===========================================
* === 3. Rimozione di Elementi ===
* `elemento.remove()` elimina l'elemento dal DOM.
*/
// TODO: Seleziona il PRIMO elemento `li` della lista (puoi usare querySelector che prende il primo).
// TODO: Rimuovilo usando il metodo `.remove()`.
/**
* ===========================================
* === 4. AddEventListener (Click) ===
* Permette di eseguire una funzione quando avviene un evento.
*/
// TODO: Seleziona il bottone con id 'btn-aggiungi'.
// TODO: Aggiungi un ascoltatore per l'evento 'click'.
// TODO: Nella funzione, mostra un `alert("Hai cliccato il bottone!")`.
/**
* ===========================================
* === 5. Eventi Comuni (Input) ===
* L'evento 'input' scatta ogni volta che si digita in un campo di testo.
*/
// TODO: Seleziona l'input con id 'input-utente' e lo span con id 'output-testo'.
// TODO: Aggiungi un listener 'input' al campo di testo.
// TODO: Nella funzione, copia il valore dell'input (`input.value`) dentro l'`textContent` dello span.
/**
* ===========================================
* === 6. Event Object (e.target) ===
* La funzione dell'evento riceve un argomento (spesso chiamato `e` o `event`) che contiene dettagli.
* `e.target` è l'elemento specifico che ha scatenato l'evento.
*/
// TODO: Seleziona l'intera lista `ul` ('lista-dinamica').
// TODO: Aggiungi un listener 'click' alla LISTA INTERA (non ai singoli li).
// TODO: Nella funzione, usa `e.target.style.color = 'red'`.

View File

@@ -0,0 +1,41 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Calcolatrice JS</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold;">← Dashboard</a>
<div class="calcolatrice">
<input type="text" id="display" placeholder="Es: 10 + 5">
<div id="messaggio-errore" class="nascosto">⚠️ Formato errato! Usa: num spazio op spazio num</div>
<div class="tastiera">
<button class="tasto">7</button>
<button class="tasto">8</button>
<button class="tasto">9</button>
<button class="tasto op">/</button>
<button class="tasto">4</button>
<button class="tasto">5</button>
<button class="tasto">6</button>
<button class="tasto op">*</button>
<button class="tasto">1</button>
<button class="tasto">2</button>
<button class="tasto">3</button>
<button class="tasto op">-</button>
<button class="tasto" id="btn-cancella">C</button>
<button class="tasto">0</button>
<button class="tasto" id="btn-uguale">=</button>
<button class="tasto op">+</button>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,94 @@
// SELEZIONE ELEMENTI
const display = document.querySelector('#display');
const btnUguale = document.querySelector('#btn-uguale');
const btnCancella = document.querySelector('#btn-cancella');
const msgErrore = document.querySelector('#messaggio-errore');
// Selezioniamo tutti i tasti "normali" (numeri e operazioni) per farli scrivere nel display
const tasti = document.querySelectorAll('.tasto:not(#btn-uguale):not(#btn-cancella)');
// Array di operatori validi (utile per la validazione)
const operatoriValidi = ['+', '-', '*', '/'];
/**
* 1. FUNZIONE: Aggiungi caratteri al display
* Per ogni tasto, aggiungiamo un event listener che, quando cliccato,
* prende il testo del tasto e lo aggiunge al display.
* Bisono fare attenzione agli spazi per gli operatori.
*
* Passi:
* - Per ogni tasto, aggiungiamo un event listener
* - Quando clicchiamo, prendiamo il testo del tasto e lo aggiungiamo al display
* - Se è un operatore, aggiungiamo spazi prima e dopo per facilitare il calcolo
* - Altrimenti aggiungiamo solo il numero
*/
/**
* 2. FUNZIONE: Cancella display
* Quando clicchiamo il tasto "C", il display deve essere svuotato.
*
* Passi:
* - Aggiungiamo un event listener al tasto "C"
* - Quando clicchiamo, svuotiamo il valore del display
*/
/**
* 3. FUNZIONE: Calcola
* Prendiamo in input un numero, un operatore e un altro numero,
* e restituiamo il risultato del calcolo in base all'operatore.
* Se l'operatore non è valido, mostriamo un messaggio di errore.
*
* Passi:
* - Prendiamo in input il primo numero, l'operatore e il secondo numero
* - In base all'operatore, eseguiamo il calcolo
* - Restituiamo il risultato
* - Se l'operatore non è valido, mostriamo un messaggio di errore con mostraErrore() e restituiamo null
* Nota: Si può usare uno switch per semplicità senza break (dato che restituiamo subito il risultato)
*/
function calcola(num1, operatore, num2) {
}
/**
* 4. FUNZIONE: Calcola risultato
* Quando clicchiamo il tasto "=", dobbiamo prendere il testo del display,
* analizzarlo, eseguire il calcolo e mostrare il risultato.
*
* Passi:
* A. Prendi il testo del display e puliscilo (rimuovi spazi inutili all'inizio e alla fine)
* B. Spezza la stringa in parti (numero, operatore, numero) in base agli spazi
* C. Valida i dati:
* - Controlla che ci siano esattamente 3 pezzi
* - Controlla che i numeri siano validi (trasforma e controlla non NaN)
* - Controlla che l'operatore sia valido (tra quelli definiti)
* D. Esegui il calcolo chiamando la funzione calcola()
* E. Mostra il risultato nel display
*/
function calcolaRisultato() {
}
/****************************************************/
/********* FUNZIONI HELPER E EVENT LISTENER *********/
/****************************************************/
function mostraErrore() {
msgErrore.classList.remove('nascosto');
display.style.borderColor = "red";
setTimeout(() => {
display.style.borderColor = "#bdc3c7";
msgErrore.classList.add('nascosto');
}, 2000);
}
// Aggiungiamo gli event listener per il calcolo del risultato
btnUguale.addEventListener('click', calcolaRisultato);
// Permettiamo anche di premere "Enter" per calcolare
display.addEventListener('keypress', (e) => {
if (e.key === 'Enter') calcolaRisultato();
});

View File

@@ -0,0 +1,79 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.calcolatrice {
background: #ecf0f1;
padding: 20px;
border-radius: 10px;
box-shadow: 0 10px 25px rgba(0,0,0,0.2);
width: 300px;
}
#display {
width: 100%;
padding: 15px;
font-size: 1.5rem;
text-align: right;
margin-bottom: 10px;
border: 2px solid #bdc3c7;
border-radius: 5px;
box-sizing: border-box; /* Importante per il padding */
}
#messaggio-errore {
color: red;
font-size: 0.8rem;
text-align: center;
margin-bottom: 10px;
height: 20px; /* Per non far saltare il layout */
}
.nascosto {
visibility: hidden; /* Nasconde ma tiene lo spazio */
}
.tastiera {
display: grid;
grid-template-columns: repeat(4, 1fr); /* 4 colonne uguali */
gap: 10px;
}
.tasto {
padding: 20px;
font-size: 1.2rem;
border: none;
background: white;
border-radius: 5px;
cursor: pointer;
transition: 0.2s;
}
.tasto:hover {
background-color: #dfe6e9;
}
.tasto.op {
background-color: #f39c12;
color: white;
}
.tasto.op:hover {
background-color: #e67e22;
}
#btn-uguale {
background-color: #27ae60;
color: white;
}
#btn-cancella {
background-color: #c0392b;
color: white;
}

View File

@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>Username Generator</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<a href="../index.html" style="position: absolute; top: 20px; left: 20px; text-decoration: none; color: #555; font-weight: bold;">← Dashboard</a>
<div class="card-generator">
<h2>🆔 Crea il tuo Username</h2>
<p>Inserisci i tuoi dati, genereremo un nome utente sicuro.</p>
<div class="input-group">
<label>Nome</label>
<input type="text" id="input-nome" placeholder="Es: Mario ">
</div>
<div class="input-group">
<label>Cognome</label>
<input type="text" id="input-cognome" placeholder="Es: Rossi Esposito">
</div>
<button id="btn-genera">Genera Username</button>
<div id="box-risultato" class="hidden">
<p>Username suggerito:</p>
<div id="output-username" class="username-box">...</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,56 @@
// SELEZIONE ELEMENTI DOM
const inputNome = document.querySelector('#input-nome');
const inputCognome = document.querySelector('#input-cognome');
const btnGenera = document.querySelector('#btn-genera');
const boxRisultato = document.querySelector('#box-risultato');
const outputUsername = document.querySelector('#output-username');
/**
* FUNZIONE: Genera Username
* Obiettivo: Creare un username formato da:
* [Prime 3 lettere Nome] + [Cognome Pulito] + [Numero Random]
* Tutto in minuscolo.
* * Passi da completare:
* 1. Recupera i valori degli input (nome e cognome).
* 2. Validazione: se uno dei due è vuoto, avvisa con alert() e fermati.
* 3. Pulizia NOME:
* - Rimuovi spazi vuoti ai lati (.trim())
* - Prendi solo le prime 3 lettere (.slice(0, 3) oppure .substring(0, 3))
* - Converti in minuscolo (.toLowerCase())
* 4. Pulizia COGNOME:
* - Rimuovi spazi vuoti ai lati (.trim())
* - Sostituisci eventuali spazi interni (es. "De Luca") con un punto o niente (.replace(" ", "") oppure .replaceAll)
* - Converti in minuscolo
* 5. Genera un numero casuale tra 10 e 99 (Math.random, Math.floor).
* 6. Unisci tutto (Nome + Cognome + Numero) e mostralo nell'output.
*/
btnGenera.addEventListener('click', function() {
// --- SCRIVI QUI IL TUO CODICE ---
// 1. Leggi
// let nome = ...
// let cognome = ...
// 2. Valida
// 3. Elabora Nome (trim, slice, toLowerCase)
// let parteNome = ...
// 4. Elabora Cognome (trim, replace, toLowerCase)
// let parteCognome = ...
// 5. Numero Random (tra 10 e 99)
// Formula: Math.floor(Math.random() * (max - min + 1)) + min
// let numero = ...
// 6. Output
// let risultato = ...
// outputUsername.textContent = risultato;
// --- FINE CODICE ---
// Mostra il risultato
boxRisultato.classList.remove('hidden');
});

View File

@@ -0,0 +1,91 @@
body {
font-family: 'Segoe UI', sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.card-generator {
background: white;
padding: 40px;
border-radius: 15px;
box-shadow: 0 10px 30px rgba(0,0,0,0.1);
width: 350px;
text-align: center;
}
.input-group {
text-align: left;
margin-bottom: 15px;
}
label {
display: block;
font-size: 0.9rem;
color: #666;
margin-bottom: 5px;
}
input {
width: 100%;
padding: 10px;
border: 2px solid #eee;
border-radius: 8px;
font-size: 1rem;
box-sizing: border-box;
transition: 0.3s;
}
input:focus {
border-color: #6c5ce7;
outline: none;
}
button {
width: 100%;
padding: 12px;
background-color: #6c5ce7;
color: white;
border: none;
border-radius: 8px;
cursor: pointer;
font-weight: bold;
margin-top: 10px;
transition: 0.2s;
}
button:hover {
background-color: #5649c0;
transform: translateY(-2px);
}
.hidden {
display: none;
}
#box-risultato {
margin-top: 25px;
padding-top: 20px;
border-top: 1px solid #eee;
animation: fadeIn 0.5s;
}
.username-box {
background: #f0f3f4;
color: #2d3436;
font-family: 'Courier New', monospace;
font-size: 1.4rem;
font-weight: bold;
padding: 10px;
border-radius: 8px;
letter-spacing: 1px;
border: 1px dashed #b2bec3;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(10px); }
to { opacity: 1; transform: translateY(0); }
}

View File

@@ -0,0 +1,191 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Hub Esercizi DOM</title>
<style>
/* RESET & BASE */
* {
box-sizing: border-box;
}
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%);
margin: 0;
padding: 40px;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
/* CONTENITORE PRINCIPALE */
.hub-container {
background: white;
width: 100%;
max-width: 650px;
padding: 40px;
border-radius: 20px;
box-shadow: 0 15px 35px rgba(0, 0, 0, 0.1);
}
h1 {
text-align: center;
color: #333;
margin-bottom: 5px;
font-size: 2.5rem;
}
p.subtitle {
text-align: center;
color: #666;
margin-bottom: 40px;
font-size: 1.1rem;
}
/* LISTA CARD */
.exercise-list {
display: flex;
flex-direction: column;
gap: 15px;
}
/* CARD ESERCIZIO */
.card {
display: flex;
align-items: center;
text-decoration: none;
background: #fff;
border: 2px solid #f0f0f0;
border-radius: 12px;
padding: 20px;
transition: all 0.2s ease;
}
.card:hover {
transform: translateY(-3px);
border-color: #007bff;
box-shadow: 0 5px 15px rgba(0, 123, 255, 0.1);
}
/* ICONA E TESTI */
.icon {
font-size: 2rem;
margin-right: 20px;
width: 40px;
text-align: center;
}
.info {
flex: 1;
}
.info h3 {
margin: 0 0 5px 0;
color: #2c3e50;
font-size: 1.1rem;
display: flex;
align-items: center;
}
.info p {
margin: 0;
color: #7f8c8d;
font-size: 0.9rem;
}
/* TAG DIFFICOLTA' */
.badge {
font-size: 0.7rem;
font-weight: bold;
padding: 3px 8px;
border-radius: 6px;
text-transform: uppercase;
letter-spacing: 0.5px;
margin-left: 10px;
}
.tutorial {
background-color: #e3f2fd;
color: #1565c0;
border: 1px solid #bbdefb;
}
/* Blu */
.easy {
background-color: #e8f5e9;
color: #2e7d32;
}
/* Verde */
.medium {
background-color: #fff3e0;
color: #ef6c00;
}
/* Arancione */
.hard {
background-color: #ffebee;
color: #c62828;
}
/* Rosso */
/* FRECCIA AL PASSAGGIO DEL MOUSE */
.arrow {
font-size: 1.5rem;
color: #ddd;
transition: 0.3s;
}
.card:hover .arrow {
color: #007bff;
transform: translateX(5px);
}
</style>
</head>
<body>
<div class="hub-container">
<h1>Esercizi DOM</h1>
<p class="subtitle">Corso Web Developer</p>
<div class="exercise-list">
<a href="tutorial.html" class="card">
<div class="icon">🧪</div>
<div class="info">
<h3>Tutorial<span class="badge tutorial">Tutorial</span></h3>
<p>Impara a pulire stringhe, gestire numeri e filtrare array.</p>
</div>
<div class="arrow"></div>
</a>
<a href="calcolatrice/index.html" class="card">
<div class="icon">🧮</div>
<div class="info">
<h3>Calcolatrice <span class="badge medium">Logica</span></h3>
<p>Validazione input, Parsing numeri, Switch case.</p>
</div>
<div class="arrow"></div>
</a>
<a href="generatore_utenti/index.html" class="card">
<div class="icon">👤</div>
<div class="info">
<h3>Generatore Utenti<span class="badge medium">Stringhe</span></h3>
<p>Manipolazione stringhe, generazione numeri casuali.</p>
</div>
<div class="arrow"></div>
</a>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,116 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f0f2f5;
color: #333;
max-width: 900px;
margin: 0 auto;
}
h1 {
text-align: center;
color: #1a73e8;
}
.controls {
text-align: center;
margin-bottom: 30px;
position: sticky;
top: 0px;
z-index: 100;
background-color: white;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}
button {
padding: 12px 24px;
font-size: 16px;
cursor: pointer;
background-color: #1a73e8;
color: white;
border: none;
border-radius: 10px;
margin: 5px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.1s;
}
button:hover {
transform: scale(1.05);
}
button:active {
transform: scale(0.95);
}
button#btn-reset {
background-color: #ea4335;
}
.step-card {
background: white;
border-radius: 12px;
padding: 20px;
margin-bottom: 25px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-left: 6px solid #1a73e8;
margin: 20px;
}
.step-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.step-title {
font-weight: bold;
font-size: 1.2em;
color: #1557b0;
}
.step-desc {
font-size: 0.95em;
color: #5f6368;
margin-bottom: 15px;
line-height: 1.5;
}
.output-box {
background: #2d3436;
color: #00c900;
padding: 10px;
font-family: 'Courier New', monospace;
border-radius: 6px;
min-height: 20px;
white-space: pre-wrap;
overflow-x: auto;
position: relative;
}
.output-box.loading::after {
content: "⏳ Attesa server...";
position: absolute;
top: 5px;
right: 5px;
font-size: 0.8em;
color: #e5c07b;
}
.output-box.error {
border: 2px solid #e06c75;
color: #e06c75;
}
.output-box.success {
border-left: 4px solid #98c379;
}
.label {
font-size: 0.8em;
color: #bbbbbb;
margin-bottom: 5px;
display: block;
font-weight: bold;
letter-spacing: 0.5px;
}

View File

@@ -0,0 +1,87 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="styles.css">
<title>Manipolazione Dati</title>
</head>
<body>
<div class="controls">
<h1>Tutorial: Manipolazione Dati</h1>
<button id="btn-esegui">▶️ Esegui Codice</button>
<button id="btn-reset">🧹 Pulisci Console</button>
</div>
<script>
function mostraOutput(stepNumero, messaggio) {
const elemento = document.getElementById(`output-${stepNumero}`);
if (elemento) {
messaggio = messaggio || "❌";
let isObject = (typeof messaggio === 'object' && messaggio !== null);
elemento.textContent = isObject ? JSON.stringify(messaggio, null, 2) : String(messaggio);
elemento.classList.remove("loading");
elemento.style.transition = "";
elemento.style.backgroundColor = "#666";
setTimeout(() => {
elemento.style.transition = "background-color 1s ease";
elemento.style.backgroundColor = "#2d3436";
}, 0);
}
}
[
{
title: "1. Normalizzazione Stringhe",
description: "Pulizia spazi (trim) e gestione Maiuscole/Minuscole.",
outputLabel: "Stringa pulita:"
},
{
title: "2. Analisi ed Estrazione",
description: "Cercare parole (includes) e dividere testi (split).",
outputLabel: "Risultati Analisi:"
},
{
title: "3. Parsing Prezzi",
description: "Da stringa a numero: replace, parseFloat e toFixed.",
outputLabel: "Prezzo formattato:"
},
{
title: "4. Arrotondamenti",
description: "Gestire i decimali: round, ceil (eccesso) e floor (difetto).",
outputLabel: "Peso arrotondato:"
},
{
title: "5. Numeri Casuali",
description: "Generare numeri random e scalarli.",
outputLabel: "Numero casuale:"
}
].forEach((step, i) => {
document.write(`
<div class="step-card">
<div class="step-header">
<div class="step-title">${step.title}</div>
</div>
<div class="step-desc">${step.description}</div>
<span class="label">${step.outputLabel}</span>
<div id="output-${i + 1}" class="output-box"></div>
</div>
`);
});
</script>
<script src="tutorial_interattivo.js"></script>
<script>
document.getElementById('btn-reset').addEventListener('click', () => {
localStorage.clear();
location.reload();
});
document.getElementById('btn-esegui').addEventListener('click', () => {
const el = document.querySelectorAll('[id^="output-"]');
el.forEach(box => box.className = "output-box loading");
eseguiTutorial();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,131 @@
// TUTORIAL INTERATTIVO: Manipolazione Dati
// Funzione pricipale del tutorial
function eseguiTutorial() {
/**
* ======================================================
* LIVELLO 1: Normalizzazione (Stringhe Base)
* Spesso i dati arrivano "sporchi" o scritti male.
* Dobbiamo standardizzarli per poterli usare correttamente.
* ======================================================
*/
let nomeProdotto = " MacBook Pro M3 ";
// TODO 1: Rimuovi gli spazi iniziali e finali (trim)
let nomePulito = "";
// TODO 2: Converti tutto in MAIUSCOLO per il codice magazzino (toUpperCase)
let perMagazzino = "";
// TODO 3: Converti tutto in minuscolo per la ricerca (toLowerCase)
let perRicerca = "";
mostraOutput(1, {
originale: nomeProdotto,
trim: nomePulito,
upper: perMagazzino,
lower: perRicerca
});
/**
* ======================================================
* LIVELLO 2: Estrazione Dati (Stringhe Avanzate)
* Analizziamo una stringa complessa che contiene più informazioni.
* Stringa: "LAPTOP GAMING | 16GB RAM | SSD"
* ======================================================
*/
let descrizione = "LAPTOP GAMING | 16GB RAM | SSD";
// TODO 1: Controlla se la descrizione contiene la parola "SSD" (includes)
// Restituisce true o false
let haSSD = false;
// TODO 2: Spezza la stringa in un array usando il separatore "|" (split)
// Otterrai: ["LAPTOP GAMING ", " 16GB RAM ", " SSD"]
let caratteristiche = [];
mostraOutput(2, {
contiene_ssd: haSSD,
lista_parti: caratteristiche
});
/**
* ======================================================
* LIVELLO 3: Pulizia Prezzi (Parsing Numeri)
* Trasformiamo una stringa di valuta in un numero matematico.
* ======================================================
*/
let prezzoCartellino = "1499.95€";
// TODO 1: Rimuovi il simbolo "€" sostituendolo con niente "" (replace)
let prezzoSenzaSimbolo = prezzoCartellino;
// TODO 2: Converti la stringa rimasta in un numero decimale (parseFloat)
let prezzoNumero = 0;
// TODO 3: Formatta il numero come stringa con 1 solo decimale (toFixed)
// Nota: toFixed restituisce una STRINGA, non un numero!
let prezzoFormat = ""; // ... usa .toFixed(1)
mostraOutput(3, {
stringa_pulita: prezzoSenzaSimbolo,
numero_vero: prezzoNumero,
formattato: prezzoFormat
});
/**
* ======================================================
* LIVELLO 4: Arrotondamenti (Matematica)
* Gestiamo un peso per la spedizione. Spesso i corrieri arrotondano.
* Peso: 1.256 kg
* ======================================================
*/
let peso = 1.256;
// TODO 1: Arrotondamento classico (Math.round)
// 1.2 -> 1, 1.5 -> 2, 1.8 -> 2
let arrotondato = 0;
// TODO 2: Arrotondamento per ECCESSO (Math.ceil - "Soffitto")
// Utile per calcolare quanti pacchi servono (1.1 diventa 2)
let perEccesso = 0;
// TODO 3: Arrotondamento per DIFETTO (Math.floor - "Pavimento")
// 1.9 diventa 1
let perDifetto = 0;
mostraOutput(4, {
originale: peso,
round: arrotondato,
ceil: perEccesso,
floor: perDifetto
});
/**
* ======================================================
* LIVELLO 5: Il dado della fortuna (Random)
* Generiamo uno sconto casuale tra 0 e 100.
* ======================================================
*/
// TODO 1: Genera un numero casuale tra 0 e 1 (Math.random())
let randomBase = 0;
// TODO 2: Trasformalo in un numero tra 0 e 100
// Moltiplica randomBase * 100
let randomCento = 0;
// TODO 3: Rimuovi i decimali per avere un intero (Math.floor)
let scontoFinale = 0;
mostraOutput(5, {
random_puro: randomBase.toFixed(4), // Mostro solo 4 decimali per pulizia
scala_100: randomCento.toFixed(2),
sconto_intero: scontoFinale
});
}

View File

@@ -0,0 +1,116 @@
body {
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
background-color: #f0f2f5;
color: #333;
max-width: 900px;
margin: 0 auto;
}
h1 {
text-align: center;
color: #1a73e8;
}
.controls {
text-align: center;
margin-bottom: 30px;
position: sticky;
top: 0px;
z-index: 100;
background-color: white;
box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1);
}
button {
padding: 12px 24px;
font-size: 16px;
cursor: pointer;
background-color: #1a73e8;
color: white;
border: none;
border-radius: 10px;
margin: 5px;
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
transition: transform 0.1s;
}
button:hover {
transform: scale(1.05);
}
button:active {
transform: scale(0.95);
}
button#btn-reset {
background-color: #ea4335;
}
.step-card {
background: white;
border-radius: 12px;
padding: 20px;
margin-bottom: 25px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
border-left: 6px solid #1a73e8;
margin: 20px;
}
.step-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
}
.step-title {
font-weight: bold;
font-size: 1.2em;
color: #1557b0;
}
.step-desc {
font-size: 0.95em;
color: #5f6368;
margin-bottom: 15px;
line-height: 1.5;
}
.output-box {
background: #2d3436;
color: #00c900;
padding: 10px;
font-family: 'Courier New', monospace;
border-radius: 6px;
min-height: 20px;
white-space: pre-wrap;
overflow-x: auto;
position: relative;
}
.output-box.loading::after {
content: "⏳ Attesa server...";
position: absolute;
top: 5px;
right: 5px;
font-size: 0.8em;
color: #e5c07b;
}
.output-box.error {
border: 2px solid #e06c75;
color: #e06c75;
}
.output-box.success {
border-left: 4px solid #98c379;
}
.label {
font-size: 0.8em;
color: #bbbbbb;
margin-bottom: 5px;
display: block;
font-weight: bold;
letter-spacing: 0.5px;
}

View File

@@ -0,0 +1,92 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>JSON e LocalStorage</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<div class="controls">
<h1>Tutorial: JSON e LocalStorage</h1>
<button id="btn-esegui">▶️ Esegui Codice</button>
<button id="btn-reset">🧹 Pulisci Tutto</button>
</div>
<script>
function mostraOutput(stepNumero, messaggio) {
const elemento = document.getElementById(`output-${stepNumero}`);
if (elemento) {
messaggio = messaggio || "❌";
let isObject = (typeof messaggio === 'object' && messaggio !== null);
elemento.textContent = isObject ? JSON.stringify(messaggio, null, 2) : String(messaggio);
elemento.classList.remove("loading");
elemento.style.transition = "";
elemento.style.backgroundColor = "#666";
setTimeout(() => {
elemento.style.transition = "background-color 1s ease";
elemento.style.backgroundColor = "#2d3436";
}, 0);
}
}
[
{
title: "1. Serializzazione (Oggetto -> Stringa)",
description: "Convertiamo un oggetto JS in una stringa JSON per poterla salvare.",
outputLabel: "Risultato in pagina:"
},
{
title: "2. Deserializzazione (Stringa -> Oggetto)",
description: "Trasformiamo una stringa JSON ricevuta in un oggetto utilizzabile.",
outputLabel: "Proprietà 'utente' estratta:"
},
{
title: "3. Scrittura nel LocalStorage",
description: "Salviamo le preferenze utente nel browser.",
outputLabel: "Verifica lettura immediata:"
},
{
title: "4. Lettura dal LocalStorage",
description: "Recuperiamo e utilizziamo un dato salvato in precedenza.",
outputLabel: "Tema recuperato:"
},
{
title: "5. Gestione Array",
description: "Aggiungiamo un film alla lista e salviamo tutto.",
outputLabel: "Contenuto salvato nel Storage:"
},
{
title: "6. Pattern \"Carica o Inizializza\"",
description: "Gestiamo il caso in cui i dati non esistano ancora (evitiamo errori).",
outputLabel: "Valore della lista sicura:"
}
].forEach((step, i) => {
document.write(`
<div class="step-card">
<div class="step-header">
<div class="step-title">${step.title}</div>
</div>
<div class="step-desc">${step.description}</div>
<span class="label">${step.outputLabel}</span>
<div id="output-${i + 1}" class="output-box"></div>
</div>
`);
});
</script>
<script src="tutorial_interattivo.js"></script>
<script>
document.getElementById('btn-reset').addEventListener('click', () => {
localStorage.clear();
location.reload();
});
document.getElementById('btn-esegui').addEventListener('click', () => {
const el = document.querySelectorAll('[id^="output-"]');
el.forEach(box => box.className = "output-box loading");
eseguiTutorial();
});
</script>
</body>
</html>

View File

@@ -0,0 +1,109 @@
// TUTORIAL INTERATTIVO: JSON e LocalStorage
// Funzione pricipale del tutorial
function eseguiTutorial() {
/**
* ===========================================
* === 1. Convertire Oggetti in Stringhe (Serializzazione) ===
* Il LocalStorage può salvare SOLO stringhe.
* Per salvare un oggetto o un array, dobbiamo convertirlo usando JSON.stringify().
*/
const studente = {
nome: "Alessandro",
corso: "JavaScript",
voto: 8
};
// TODO: Converti l'oggetto 'studente' in una stringa JSON e salvala nella variabile 'studenteStringa'.
let studenteStringa = "";
// Visualizzazione Risultato
mostraOutput(1, studenteStringa);
/**
* ===========================================
* === 2. Convertire Stringhe in Oggetti (Deserializzazione) ===
* Quando leggiamo dal LocalStorage, otteniamo una stringa.
* Per riutilizzarla come codice JS, dobbiamo convertirla indietro usando JSON.parse().
*/
const datiRicevuti = '{"id": 101, "utente": "Alessandro", "attivo": true}';
// TODO: Converti la stringa 'datiRicevuti' in un vero oggetto JavaScript e salvalo in 'oggettoDati'.
// Nota: Inizializziamo a {} vuoto per evitare errori se non completi il TODO
let oggettoDati = {};
// Visualizzazione Risultato (mostriamo solo la proprietà 'utente')
mostraOutput(2, oggettoDati.utente);
/**
* ===========================================
* === 3. Salvare nel LocalStorage ===
* Usiamo localStorage.setItem('chiave', 'valore') per salvare i dati.
* Ricorda: il valore deve essere una stringa!
*/
const preferenze = {
tema: "scuro",
notifiche: true
};
// TODO: Salva l'oggetto 'preferenze' (convertito in stringa!) nel localStorage con la chiave "impostazioni_utente".
// SUGGERIMENTO: Usa JSON.stringify(preferenze) dentro il setItem.
// Visualizzazione Risultato (Leggiamo direttamente dallo storage per verificare)
const verificaStorage = localStorage.getItem("impostazioni_utente");
mostraOutput(3, verificaStorage ? "Salvato con successo: " + verificaStorage : "");
/**
* ===========================================
* === 4. Leggere dal LocalStorage ===
* Usiamo localStorage.getItem('chiave') per recuperare i dati.
*/
// TODO: Recupera la stringa salvata alla chiave "impostazioni_utente", convertila in oggetto e assegna il tema a 'temaSalvato'.
let temaSalvato = "";
// Visualizzazione Risultato
mostraOutput(4, temaSalvato);
/**
* ===========================================
* === 5. Gestire gli Array (Liste) ===
* Spesso salviamo liste di cose (es. dipendenti, libri).
* Il processo è identico: Array -> JSON.stringify -> Storage.
*/
const nuoviFilm = [
{ titolo: "Inception", anno: 2010 },
{ titolo: "Matrix", anno: 1999 }
];
// TODO: 1. Aggiungi un nuovo film all'array 'nuoviFilm' usando .push() (es. { titolo: "Interstellar", anno: 2014 }).
// TODO: 2. Salva l'intero array aggiornato nel localStorage con chiave "lista_film" (ricorda JSON.stringify).
// Visualizzazione Risultato
mostraOutput(5, localStorage.getItem("lista_film"));
/**
* ===========================================
* === 6. Il Pattern "Carica o Inizializza" ===
* Quando l'app parte, dobbiamo caricare i dati.
* Ma se è la prima volta che l'utente entra, il localStorage sarà null.
*/
// Immagina di provare a caricare una chiave che non esiste:
const chiaveInesistente = localStorage.getItem("chiave_mai_usata");
// TODO: Completa la riga sotto per assegnare a 'listaSicura' il valore parsato di 'chiaveInesistente',
// OPPURE un array vuoto [] se il dato è null.
let listaSicura = null;
// Visualizzazione Risultato
mostraOutput(6, listaSicura);
}

View File

@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html lang="it">
<head>
<meta charset="UTF-8">
<title>La Mia Watchlist</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<h1>🎬 Film da Vedere</h1>
<div class="input-group">
<input type="text" id="titolo" placeholder="Titolo film">
<input type="number" id="anno" placeholder="Anno" style="max-width: 80px;">
<button id="btn-add">Aggiungi</button>
</div>
<ul id="lista-film">
<!-- I film verranno aggiunti qui dinamicamente -->
</ul>
<script src="script.js"></script>
</body>
</html>

View File

@@ -0,0 +1,109 @@
/**
* Esercizio: Watchlist Film
*
* CONTESTO:
* Abbiamo un HTML con due input (titolo, anno) e una lista vuota.
* Vogliamo salvare la lista dei film da vedere nel browser.
*
* STRUTTURA DATI:
* Array di oggetti: [{ titolo: "Dune", anno: "2021" }, ...]
*
* ISTRUZIONI:
* 1. Completa 'caricaFilm' per leggere dal localStorage (o inizializzare array vuoto).
* 2. Completa 'aggiungiFilm' per aggiornare l'array, salvarlo e aggiornare la UI.
* 3. Usa JSON.parse e JSON.stringify.
*/
// RIFERIMENTI DOM
const inputTitolo = document.querySelector('#titolo');
const inputAnno = document.querySelector('#anno');
const listaFilm = document.querySelector('#lista-film');
const btnAdd = document.querySelector('#btn-add');
// STATO DELL'APP
let filmWatchlist = [];
/**
* STEP 1: Funzione Renderizza (visualizza) la lista
* Pulisce l'HTML e ricrea gli elementi basandosi sull'array filmWatchlist
* 1. Pulisci il contenuto di 'listaFilm'.
* 2. Per ogni film in 'filmWatchlist', crea un <li> con dentro --> <p>titolo (anno)</p>
* 3. Aggiungi l'<li> a 'listaFilm'.
*/
function visualizzaLista() {
// TODO: Scrivi qui il codice per visualizzare la lista...
}
/**
* STEP 2: Caricamento Iniziale
* Leggi la chiave "my_watchlist" dal localStorage.
* Se esiste, parsa la stringa e riempi l'array 'filmWatchlist'.
* Se non esiste, lascia l'array vuoto.
* Infine chiama visualizzaLista().
*/
function inizializzaApp() {
// TODO: Scrivi qui il codice per caricare i dati...
}
/**
* STEP 3: Aggiunta e Salvataggio
* Quando l'utente clicca "Aggiungi Film":
* 1. Cattura i valori dagli input.
* 2. Crea un oggetto film solo se entrambi i campi hanno un valore.
* 3. Crea un oggetto con i dati degli input.
* 4. Pushalo nell'array filmWatchlist.
* 5. Salva l'intero array aggiornato nel localStorage (JSON.stringify!).
* 6. Chiama visualizzaLista().
*/
// TODO: Scrivi qui il codice per aggiungere un film...
// AVVIO
inizializzaApp();
/************************************************************************/
/************************* ESERCIZI EXTRA *******************************/
/************************************************************************/
/**
* Esercizio Extra 1: Rimuovere Elementi
*
* OBIETTIVO:
* Aggiungere un bottone "Elimina" accanto a ogni film che rimuova il film
* dall'array E aggiorni il localStorage.
*
* Questo esercizio RICHIEDE di modificare la funzione 'visualizzaLista'.
*
* Possibile Implementazione:
* 1. Usare un ciclo for con la variabile indice (let i = 0; i < ...; i++).
* 2. Dentro il ciclo crea un bottone con testo "Elimina" o "X" (mettere anche la classe corretta già presente in CSS).
* 3. Aggiungi un eventListener al bottone che:
* - Usa l'indice 'i' per fare filmWatchlist.splice(i, 1) e rimuovere l'elemento.
* - Salva l'array aggiornato nel localStorage.
* 4. Richiamare visualizzaLista().
* Nota: Ricorda che ogni volta che visualizzi la lista, stai ricreando TUTTI gli elementi HTML,
* quindi i vecchi listener vengono persi. Devi rimetterli ogni volta.
*/
/**
* Esercizio Extra 2: Stato "Visto/Non Visto"
*
* OBIETTIVO:
* Aggiungi una checkbox accanto a ogni film.
* Se l'utente la spunta, lo stato "visto" del film (true/false) deve essere salvato.
*
* LOGICA:
* 1. Modifica l'oggetto iniziale del film aggiungendo la proprietà --> visto: false.
* 2. Nella render, per ogni elemento <li>, crea un <input type="checkbox">.
* 3. Imposta checkbox.checked = film.visto.
* 4. All'evento 'change' della checkbox:
* - Aggiorna filmWatchlist[index].visto = checkbox.checked
* - Salva tutto nel localStorage.
* - (Opzionale) Aggiungi una classe CSS per barrare il testo se visto --> text-decoration: line-through.
* Nota: devi aggiornare la classe del <p> dentro l'li in base a film.visto.
*/

View File

@@ -0,0 +1,54 @@
body {
font-family: sans-serif;
max-width: 600px;
margin: 2rem auto;
padding: 1rem;
}
.input-group {
background: #eee;
padding: 1rem;
border-radius: 8px;
display: flex;
gap: 10px;
}
input {
padding: 8px;
flex: 1;
}
input[type="checkbox"] {
transform: scale(1.5);
}
button {
padding: 8px 16px;
cursor: pointer;
background: #28a745;
color: white;
border: none;
border-radius: 4px;
}
ul {
list-style: none;
padding: 0;
margin-top: 2rem;
}
li {
background: white;
border: 1px solid #ddd;
padding: 10px;
margin-bottom: 5px;
display: flex;
justify-content: space-between;
align-items: center;
}
.delete-btn {
background: #dc3545;
margin-left: 10px;
font-size: 0.8rem;
}