W3docs

JavaScript Form submit() ed Eventi

Scopri come funzionano l'evento submit, form.submit() e form.requestSubmit() in JavaScript: validazione, preventDefault(), il pulsante submitter e la lettura dei dati prima dell'invio.

La gestione degli invii dei form è uno dei compiti più comuni nel JavaScript lato client. I form sono il modo in cui gli utenti inviano dati a un server — accesso, registrazione, ricerca, checkout — quindi si vuole quasi sempre avere la possibilità di validare, trasformare o confermare quei dati prima che lascino la pagina.

Esistono due strumenti correlati ma distinti per questo:

  • L'evento submit — attivato dal browser quando l'utente tenta di inviare un form (cliccando un pulsante di invio, premendo Invio in un campo). Qui si esegue la validazione e si decide se consentire o annullare l'invio.
  • Il metodo form.submit() — invia il form programmaticamente dal proprio codice, senza alcuna azione dell'utente.

Un problema comune che sorprende molti sviluppatori: questi due strumenti non sono simmetrici. Chiamare form.submit() non attiva l'evento submit e salta completamente la validazione dei vincoli. Spieghiamo il perché, e cosa usare al suo posto.

Comprendere l'evento submit

L'evento submit si attiva quando un form sta per inviare i propri dati. È fondamentale che sia annullabile: chiamare event.preventDefault() all'interno del gestore impedisce al browser di navigare altrove, consentendo di mantenere l'utente sulla pagina per validare l'input, mostrare errori, o inviare i dati con fetch.

L'evento si attiva quando:

  • L'utente clicca su <button type="submit"> o <input type="submit"> all'interno del form.
  • L'utente preme Invio mentre è attivo in un campo di testo di un form che ha un pulsante di invio.

Non si attiva quando si chiama form.submit() da JavaScript (vedi sotto).

Esempio: Validazione del Form Prima dell'Invio

Questo script impedisce l'invio del form se i campi non sono compilati correttamente, fornendo un messaggio di errore all'utente. Si basa sulla validazione dei vincoli integrata nel browser (l'attributo required e type="email") tramite checkValidity().

<div>
  <form style="display: flex; justify-content: center; gap: 2px; align-items: center; flex-direction: column;" id="registrationForm">
    Username: <input type="text" name="username" required />
    Email: <input type="email" name="email" required />
    <button type="submit">Register</button>
  </form>
  <div id="message" style="margin-top: 10px; text-align:center;"></div> <!-- Message container for feedback -->
  <script>
    const form = document.getElementById('registrationForm');
    form.addEventListener('submit', function(event) {
      event.preventDefault(); // Prevent actual form submission to a server
      const messageDiv = document.getElementById('message');
      if (!this.checkValidity()) {
        messageDiv.textContent = 'Please fill all required fields correctly.';
        messageDiv.style.color = 'red'; // Display the message in red for errors
      } else {
        messageDiv.textContent = 'The form was successfully submitted.';
        messageDiv.style.color = 'green'; // Display the message in green for success
        form.reset(); // Reset the form fields after successful submission
      }
    });
  </script>
</div>

Funzionalità JavaScript:

  • Event Listener: Al form viene associato un event listener che si attiva quando si tenta di inviare il form.
  • Controllo di Validazione: Viene usata qui la funzione checkValidity(). È un metodo HTML nativo dei form che controlla tutti gli input del form rispetto alle loro regole di validazione (come l'attributo required in questo caso). Se un campo non soddisfa la sua regola di validazione, la funzione restituisce false.
  • Prevenire l'Invio: Se checkValidity() restituisce false (ovvero il form ha campi obbligatori non validi o vuoti), lo script impedisce l'invio del form al server. Mostra invece un messaggio che chiede all'utente di compilare correttamente tutti i campi richiesti.
  • Gestione dell'Invio: Se tutti i campi sono validi, il form visualizza un messaggio di successo anziché mostrare una pagina vuota o inviare i dati al server. In un'applicazione reale, qui si chiamerebbe fetch() per inviare i dati.

Lettura dei dati inviati

All'interno del gestore di solito si vogliono i valori inseriti dall'utente. Il modo più pulito è l'object FormData, che raccoglie tutti i controlli con nome in un solo passaggio:

const form = document.getElementById("registrationForm");
form.addEventListener("submit", (event) => {
  event.preventDefault();
  const data = Object.fromEntries(new FormData(form));
  console.log(data.username, data.email);
  // data is a plain object: { username: "...", email: "..." }
});

Sapere quale pulsante è stato cliccato

Quando un form ha più pulsanti di invio (ad esempio "Salva" contro "Elimina"), l'evento submit indica quale ha avviato l'invio tramite event.submitter:

form.addEventListener("submit", (event) => {
  event.preventDefault();
  // event.submitter is the button element that caused submission
  console.log("Submitted via:", event.submitter?.value);
});

Utilizzo del Metodo .submit()

Il metodo .submit() avvia l'invio del form programmaticamente — direttamente dal codice, senza alcun clic dell'utente. È utile quando un form deve essere inviato dopo che una certa condizione è soddisfatta (un timer, un controllo automatico superato, un valore calcolato in JavaScript).

Due avvertenze rendono .submit() diverso da un invio guidato dall'utente:

  • Non attiva l'evento submit, quindi qualsiasi validazione o logica collegata a quell'evento viene saltata.
  • Non esegue la validazione dei vincoli del browser, quindi le regole required e type vengono ignorate.

Questo è intenzionale — storicamente .submit() era pensato per inviare senza rieseguire il gestore che lo aveva chiamato (che altrimenti avrebbe creato un loop). Nella maggior parte dei casi è preferibile usare form.requestSubmit() (trattato di seguito), che si comporta come un vero invio da parte dell'utente.

Esempio: Invio Programmatico del Form

L'esempio seguente invia un form dal codice non appena la pagina viene caricata. Poiché il form non ha l'attributo action, invia alla pagina corrente; l'avviso mostra il valore del campo nascosto in modo da vedere cosa verrebbe inviato:

<!DOCTYPE html>
<html>
<head>
  <title>Auto Submit Form Demo</title>
</head>
<body>
  <form id="autoSubmitForm">
    <input type="hidden" name="data" value="Automatic Submission" />
  </form>
  <script>
    function submitFormAutomatically() {
      document.getElementById('autoSubmitForm').submit();
      alert("Form submitted with data: " + document.getElementById('autoSubmitForm').data.value);
    }
    document.addEventListener('DOMContentLoaded', submitFormAutomatically); // Call the function when the DOM is ready
  </script>
</body>
</html>

Si noti che document.getElementById('autoSubmitForm').data funziona perché i controlli del form con nome sono esposti come proprietà sull'elemento form — form.data restituisce l'elemento <input name="data">, e .value ne legge il valore.

Preferire requestSubmit() a submit()

form.requestSubmit() è la controparte moderna e più sicura di form.submit(). A differenza di .submit():

  • attiva l'evento submit, quindi i gestori di validazione vengono eseguiti;
  • esegue la validazione dei vincoli del browser e mostra i messaggi di errore nativi se un campo non è valido;
  • accetta facoltativamente un pulsante in modo che event.submitter sia impostato, ad es. form.requestSubmit(saveButton).
const form = document.getElementById("registrationForm");
// Behaves exactly like a real user click on the submit button:
form.requestSubmit();

Se si ha davvero bisogno del comportamento bypass di .submit() ma si vuole comunque che il gestore venga eseguito, si può inviare l'evento manualmente con form.dispatchEvent(new Event('submit', { cancelable: true })) — ma in quasi tutti i casi requestSubmit() è la scelta giusta.

Combinare .submit() con gli Event Listener

Si può anche condizionare l'invio a criteri specifici: inviare il form solo quando determinate condizioni sono soddisfatte. L'esempio seguente usa un pulsante normale (non di invio) in modo che non accada nulla finché JavaScript non decide di chiamare submit().

Esempio: Invio Condizionale del Form

<form id="conditionalForm">
  Accept Terms: <input type="checkbox" id="acceptTerms">
  <button type="button" onclick="checkAndSubmit()">Submit</button>
</form>
<script>
  function checkAndSubmit() {
    var form = document.getElementById('conditionalForm');
    var termsCheckbox = document.getElementById('acceptTerms');
    if (termsCheckbox.checked) {
      form.submit();
    } else {
      alert('You must accept the terms and conditions to proceed.');
    }
  }
</script>

Questo codice fornisce un pulsante che, quando cliccato, verifica se una casella di controllo è selezionata prima di inviare il form. Se i termini non vengono accettati, viene avvisato l'utente. Si noti che poiché si usa form.submit(), l'evento submit non si attiverà — sostituirlo con form.requestSubmit() se si ha anche un listener submit che si vuole eseguire.

submit event vs. submit() vs. requestSubmit()

ComportamentoEvento submitform.submit()form.requestSubmit()
Attivato da azione dell'utenteNo (solo codice)No (solo codice)
Attiva l'evento submitNo
Esegue la validazione dei vincolin/aNo
Può essere annullato (preventDefault)NoSì (tramite l'evento)
Imposta event.submitterNoSì (passare un pulsante)

Regola pratica: ascoltare l'evento submit per validare e intercettare; chiamare requestSubmit() per avviare un invio dal codice; ricorrere a .submit() solo quando si ha specificamente bisogno di bypassare i propri gestori.

Conclusione

L'evento submit consente di intercettare e validare un form prima che lasci la pagina, mentre .submit() e requestSubmit() permettono di inviarlo dal codice. Il punto chiave è che .submit() salta silenziosamente sia l'evento submit che la validazione — quindi è preferibile usare requestSubmit() a meno che non si voglia deliberatamente quel bypass. Combinati con event.preventDefault() e FormData, questi strumenti offrono il pieno controllo su come l'input dell'utente viene raccolto e inviato.

Per approfondire, consulta proprietà e metodi del form, l'API di validazione dei vincoli, gli eventi change e input per le reazioni in tempo reale ai campi, e focus e blur per l'interazione a livello di campo.

Esercitazione

Pratica
Quali delle seguenti affermazioni sono vere riguardo all'evento submit e al metodo submit() di JavaScript per i form?
Quali delle seguenti affermazioni sono vere riguardo all'evento submit e al metodo submit() di JavaScript per i form?
Was this page helpful?