Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

JS: Form e validazione lato client

Abbiamo visto nei form HTML come si possa usare l’attributo required per una validazione minima, gestita interamente dal browser. Ora vediamo come intercettare l’invio di un form con JavaScript, per controlli più precisi e messaggi d’errore personalizzati.

Intercettare l’invio di un form

form.html
<form id="form-contatto">
    <label for="nome">Nome:</label>
    <input type="text" id="nome" name="nome">

    <label for="email">Email:</label>
    <input type="email" id="email" name="email">

    <button type="submit">Invia</button>
</form>

<p id="errore"></p>
script.js
const form = document.getElementById("form-contatto");

form.addEventListener("submit", (evento) => {
    evento.preventDefault();
    console.log("Invio intercettato!");
});

evento.preventDefault() è la riga chiave: senza di essa, il browser invierebbe comunque il form e ricaricherebbe la pagina, come da comportamento predefinito. Chiamandola, prendiamo il controllo: decidiamo noi cosa succede, prima di lasciare che il form venga davvero inviato (o bloccarlo del tutto, se i dati non sono validi).

Leggere i valori dei campi

const form = document.getElementById("form-contatto");

form.addEventListener("submit", (evento) => {
    evento.preventDefault();

    const nome = document.getElementById("nome").value;
    const email = document.getElementById("email").value;

    console.log(`Nome: ${nome}, Email: ${email}`);
});

.value legge il contenuto attuale di un <input> — non .textContent (quello serve per il testo dentro un tag, mentre .value legge cosa l’utente ha scritto in un campo di input).

Validare e mostrare un errore

script.js
const form = document.getElementById("form-contatto");
const errore = document.getElementById("errore");

form.addEventListener("submit", (evento) => {
    evento.preventDefault();

    const nome = document.getElementById("nome").value;
    const email = document.getElementById("email").value;

    if (nome === "") {
        errore.textContent = "Il nome è obbligatorio";
        return;
    }

    if (!email.includes("@")) {
        errore.textContent = "Email non valida";
        return;
    }

    errore.textContent = "";
    console.log("Form valido, invio in corso...");
    form.submit(); // ora invia davvero, dopo aver superato i controlli
});

Punti da notare:

  • return dentro la callback dell’evento interrompe la funzione, esattamente come in una funzione qualsiasi: se il nome è vuoto, il codice si ferma lì e non arriva mai a controllare l’email.
  • email.includes("@") è una verifica volutamente semplice (una vera validazione email è più complessa) — sufficiente per capire il meccanismo.
  • Se tutti i controlli passano, si azzera il messaggio d’errore (errore.textContent = "") e si procede con form.submit(), che invia il form per davvero, come se preventDefault() non ci fosse mai stato.

Validare più campi con un ciclo

Se i campi obbligatori sono tanti, si può evitare di ripetere lo stesso controllo copiato e incollato:

form.addEventListener("submit", (evento) => {
    evento.preventDefault();

    const campiObbligatori = document.querySelectorAll("[required]");
    let tuttoValido = true;

    for (const campo of campiObbligatori) {
        if (campo.value === "") {
            campo.style.borderColor = "red";
            tuttoValido = false;
        } else {
            campo.style.borderColor = "";
        }
    }

    if (tuttoValido) {
        console.log("Tutti i campi obbligatori sono compilati");
    }
});

Qui document.querySelectorAll("[required]") seleziona tutti gli elementi che hanno l’attributo required nell’HTML (un selettore CSS “per attributo”, stessa famiglia vista nei capitoli sul CSS) — e il ciclo for...of controlla ognuno con la stessa logica, senza ripetere codice per ogni singolo campo.

Riepilogo: dove sta cosa

CompitoChi se ne occupa
Bloccare l’invio finché non si è prontievento.preventDefault()
Leggere cosa ha scritto l’utente.value
Decidere se un valore è validoif (la tua logica)
Mostrare un messaggio d’erroretextContent su un elemento dedicato
Evidenziare visivamente un campo errato.style o classList

Esercizi

Esercizio w341

Crea un form con un solo campo di testo (nome) e un bottone di invio. Intercetta il submit, usa preventDefault(), e stampa in console il valore scritto dall’utente.


Esercizio w342

Aggiungi al form dell’esercizio precedente un controllo: se il campo nome è vuoto, mostra il messaggio "Il nome è obbligatorio" in un <p id="errore">, senza inviare il form.


Esercizio w343

Crea un form con 3 campi di testo, tutti con l’attributo required. Usando querySelectorAll("[required]") e un ciclo, controlla che siano tutti compilati, colorando di rosso il bordo (style.borderColor) di quelli vuoti.


Esercizio w344

Nel seguente codice il form viene sempre inviato, anche se il campo è vuoto: manca il controllo prima di procedere. Correggi il problema aggiungendo la validazione:

da_correggere.js
const form = document.getElementById("form-contatto");

form.addEventListener("submit", (evento) => {
    evento.preventDefault();

    const nome = document.getElementById("nome").value;

    console.log("Invio in corso...");
    form.submit();
});