jQuery / Method / .submit() — Eventos de envio de formulário

Trate o envio com $(form).on("submit", handler). Para solicitá-lo com validação do navegador, use form.requestSubmit(). O atalho antigo jQuery .submit(), o disparo de evento e form.submit() nativo seguem caminhos diferentes.

Conectar ou solicitar envio

O atalho jQuery .submit() está obsoleto desde 3.3. Com função conecta; sem argumentos dispara. Ambos existem nas versões completas testadas 3.7.1 e 4.0.0. Para código novo prefira APIs explícitas; obsoleto não significa removido automaticamente.

O evento submit pertence ao formulário. Tratá-lo ali cobre clique, Enter e solicitação programada. Validar só no clique do botão pode perder outros caminhos.

Caminho Validação e evento Uso
.on("submit", handler) Conecta sem enviar Tratar evento
Botão submit / requestSubmit() Restrições e depois submit se válido Solicitação comum
jQuery .trigger("submit") Não reproduz a mesma validação nativa Disparo deliberado
form.submit() nativo Ignora restrições e evento Desvio especial intencional

Exemplo completo de comparação

Salve e abra submit-demo.html em UTF-8. A internet carrega jQuery completo 4.0.0, sem servidor ou compilação. preventDefault bloqueia todos os envios e apenas mostra resultados. Não há transmissão externa nem armazenamento. Windows Edge com 4.0.0 e 3.7.1 verificou caminhos e dados do botão.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>Inspect form submit events</title>
  <script src="https://code.jquery.com/jquery-4.0.0.min.js"></script>
  <style>
    body { font: 16px/1.6 sans-serif; max-width: 720px; margin: 20px; }
    label { display: block; margin-top: 12px; }
    input, select, button { font: inherit; max-width: 100%; margin: 5px 0; }
    pre { white-space: pre-wrap; overflow-wrap: anywhere; }
  </style>
</head>
<body>
  <form id="chooser">
    <label for="person">Name</label>
    <input id="person" name="person" required>
    <label for="fruit">Fruit</label>
    <select id="fruit" name="fruit" required>
      <option value="">Choose a fruit</option>
      <option value="apple">Apple</option><option value="banana">Banana</option>
    </select>
    <button id="inside" type="submit" name="intent" value="inside">Inspect inside</button>
  </form>
  <button id="outside" type="submit" form="chooser" name="intent" value="outside">Inspect outside</button>
  <button id="request" type="button">requestSubmit(inside)</button>
  <button id="trigger" type="button">jQuery trigger submit</button>
  <button id="restore" type="button">Reset</button>
  <label><input id="automatic" type="checkbox">Request submission when fruit changes</label>
  <pre id="result" aria-live="polite">events=0
No submission inspected.</pre>
  <script>
    jQuery(function ($) {
      const form = document.querySelector("#chooser");
      let events = 0;
      $(form).on("submit", function (event) {
        event.preventDefault(); events++;
        if (!form.reportValidity()) {
          $("#result").text("events=" + events + "\nInvalid data; not inspected."); return;
        }
        const submitter = event.originalEvent ? event.originalEvent.submitter : null;
        const data = submitter ? new FormData(form, submitter) : new FormData(form);
        $("#result").text("events=" + events + "\nsubmitter=" + (submitter ? submitter.id : "(none)") +
          "\nvalues=" + JSON.stringify(Object.fromEntries(data)));
      });
      $("#request").on("click", function () { form.requestSubmit(document.querySelector("#inside")); });
      $("#trigger").on("click", function () { $(form).trigger("submit"); });
      $("#fruit").on("change", function () {
        if (document.querySelector("#automatic").checked) form.requestSubmit();
      });
      $("#restore").on("click", function () {
        form.reset(); document.querySelector("#automatic").checked = false; events = 0;
        $("#result").text("events=0\nNo submission inspected.");
      });
    });
  </script>
</body>
</html>

Estado inicial: events conta entradas no manipulador, não gravações bem-sucedidas no servidor.

events=0
No submission inspected.
  1. Com campos vazios, inside, outside e requestSubmit(inside) são bloqueados por required: events=0.
  2. jQuery trigger submit chega a events=1, mas reportValidity mostra Invalid data; not inspected.
  3. Reset, JB e Apple, depois Inspect inside: events=1, submitter=inside e valores aparecem.
  4. Inspect outside resulta em submitter=outside e intent=outside. form="chooser" associa o botão externo.
  5. requestSubmit(inside) indica esse botão. Enter em Name também usa aqui o primeiro, inside.
  6. Disparo jQuery válido mostra submitter=(none), sem intent de botão.
  7. Ative solicitação automática e escolha Banana: requestSubmit() sem botão dá submitter=(none).
  8. Reset restaura valores, caixa automática e contador.

event.originalEvent.submitter lê o botão do SubmitEvent nativo. Um evento jQuery sintético pode não ter originalEvent. FormData(form, submitter) inclui seu name/value. Object.fromEntries mantém apenas o último valor para nomes repetidos; essa exibição não é um modelo de coleta de arrays sem adaptação.

Controles externos e prevenção

Um button type="submit" real com atributo form oferece comportamento de teclado e formulário mesmo fora. Essa posição não ignora required por si só; a API escolhida importa.

requestSubmit() valida e emite submit quando válido. Um elemento indicado deve ser botão de envio associado ao formulário. O exemplo cobre as duas variantes.

Enviar a cada mudança de select pode surpreender durante a escolha por setas. Aqui é preciso ativar a função e não ocorre navegação. Decida entre filtro imediato e confirmação. Um setter .val() sozinho não emite change.

preventDefault interrompe o envio normal. Para esperar trabalho assíncrono, impeça durante o manipulador; depois de await não se desfaz um envio iniciado. Não há transporte assíncrono neste exemplo. Uma implementação real precisa de estado em andamento, duplicatas, recuperação e validação do servidor.

Atalho antigo e método nativo

Execute esta verificação após inicializar. O formulário não anexado impede a ação padrão, sem solicitação ao servidor.

const $probe = $("<form>");
let calls = 0;
$probe.submit(function (event) {
  event.preventDefault();
  calls++;
});
$probe.submit();
console.log("legacy calls=" + calls);

Resultado Console; em código antigo distinga função e chamada sem argumentos.

legacy calls=1

.trigger("submit") executa manipuladores e pode continuar ao método nativo se não for impedido. Não simula completamente clique e restrições. reportValidity protege também o caso sintético do exemplo.

HTMLFormElement.submit() ignora restrições e manipuladores. Outro teste enviou um required vazio a um iframe com interceptação local: dados vazios e zero eventos. Não verificou gravação em servidor receptor real.

Para form.submit is not a function, procure controle com name ou id submit ocultando o método. Evite também reset. Distinga coleção jQuery e formulário DOM: requestSubmit pertence ao DOM, obtido por exemplo com [0].

Envio real exige action, method e recepção apropriados; adapte a prevenção permanente e a exibição da prática. Valid não significa salvo e required não substitui verificações do servidor.