Como forçar uma validação de formulário html5 sem enviá-lo via jQuery

286

Eu tenho este formulário no meu aplicativo e o enviarei via AJAX, mas quero usar o HTML5 para validação do lado do cliente. Então, eu quero poder forçar a validação do formulário, talvez via jQuery.

Quero acionar a validação sem enviar o formulário. É possível?

razenha
fonte
Você pode especificar em que momento deseja validar o formulário? O que aciona a validação? Deseja validar cada campo quando o usuário digita, entra / sai do campo e altera o valor?
Peter Pajchl
6
Eu gostaria de ser possível fazer algo assim: $ ("# my_form"). TriggerHtml5Validation ()
razenha
Esta página pode ajudar a vincular
Dan Bray
Você pode conseguir isso sem o jQuery. Veja minha solução.
Dan Bray

Respostas:

444

Para verificar se um determinado campo é válido, use:

$('#myField')[0].checkValidity(); // returns true/false

Para verificar se o formulário é válido, use:

$('#myForm')[0].checkValidity(); // returns true/false

Se você deseja exibir as mensagens de erro nativas que alguns navegadores possuem (como o Chrome), infelizmente a única maneira de fazer isso é enviando o formulário da seguinte forma:

var $myForm = $('#myForm');

if(! $myForm[0].checkValidity()) {
  // If the form is invalid, submit it. The form won't actually submit;
  // this will just cause the browser to display the native HTML5 error messages.
  $myForm.find(':submit').click();
}

Espero que isto ajude. Lembre-se de que a validação HTML5 não é suportada em todos os navegadores.

Abraão
fonte
1
Tentei sua solução, mas ela ainda envia o formulário quando a linha $ myForm.submit () é executada.
Yashpal Singla
27
Tente substituir $myForm.submit()por$myForm.find(':submit').click()
Abraham
8
Abraão está correto. Você precisa realmente clicar no botão enviar (programaticamente). Chamar $ myForm.submit () não acionará a validação.
Kevin Tighe
75
Se o formulário não tem um botão de envio, você pode um falso:$('<input type="submit">').hide().appendTo($myForm).click().remove();
philfreo
15
Esta resposta é muito útil por causa da dica checkValidity(), mas também possui um erro perigoso. checkValidity()é o que aciona as mensagens de erro do navegador nativo, não o clique no botão enviar. Se você tem um ouvinte de eventos que ouve o clique do botão de envio, você o acionará quando fizer '$ myForm.find (': submit '). Click () `, que será acionado automaticamente e causará recursão infinita.
Bad Request
30

Encontrei esta solução para trabalhar para mim. Basta chamar uma função javascript como esta:

action="javascript:myFunction();"

Então você tem a validação html5 ... realmente simples :-)

Martin Christensen
fonte
3
Isso funcionou para mim também e acho que essa é a melhor resposta. Eu iniciei action="javascript:0"o evento <form>e liguei clickno <button>para MyFunction()e tudo funcionou muito bem. Eu mantenho todas as JS fora do HTML. MyFunctionpode então testar form.checkValidity()para continuar.
orad 16/10
3
O código de exemplo é sempre útil.
BJ Patel #
10
A ligação aos formulários onsubmit()é quase sempre melhor do que os de um botão onclick(), pois existem outras maneiras de enviar um formulário. (Notavelmente pressionando a returntecla.)
alttag
+1 Isso é incrível. não há mais validação de método javascript se o campo estiver vazio ou se for um email. O navegador pode fazer isso por nós! Este navegador cruzado é compatível?
Jo E.
2
Nem action="javascript:myFunction();"ou action="javascript:0"obras mais no mais recente Firefox (67). Funciona no Chrome.
Bobz 14/07/19
23
    if $("form")[0].checkValidity()
      $.ajax(
        url: "url"
        type: "post"
        data: {

        }
        dataType: "json"
        success: (data) ->

      )
    else
      #important
      $("form")[0].reportValidity()

de: validação de formulário html5

user1575761
fonte
4
reportValidityé suportado apenas pelo Chrome 40.0
MM
Isso é CoffeeScript.
Amphetamachine
1
reportValidity agora é suportado pelo Firefox desde a versão 49
Justin
Eu gosto dessa parte $("form")[0].reportValidity(). Preciso que, caso a verificação de validade falhe.
Fsevenm
Ótimo! Obrigado!
stefo91
18

o código abaixo funciona para mim,

$("#btn").click(function () {

    if ($("#frm")[0].checkValidity())
        alert('sucess');
    else
        //Validate Form
        $("#frm")[0].reportValidity()

});
Boopathi.Indotnet
fonte
1
reportValidity()é a melhor função para destacar os campos obrigatórios.
Jamshad Ahmad 31/12/19
Sim, isso funciona como um encanto, mas apenas se o navegador suportar. caniuse.com/#search=reportValidity
MegaMatt
16

Aqui está uma maneira mais geral que é um pouco mais limpa:

Crie seu formulário assim (pode ser um formulário fictício que não faz nada):

<form class="validateDontSubmit">
...

Vincule todos os formulários que você realmente não deseja enviar:

$(document).on('submit','.validateDontSubmit',function (e) {
    //prevent the form from doing a submit
    e.preventDefault();
    return false;
})

Agora, digamos que você tenha <a>(dentro do <form>) que, no clique, deseja validar o formulário:

$('#myLink').click(function(e){
  //Leverage the HTML5 validation w/ ajax. Have to submit to get em. Wont actually submit cuz form
  //has .validateDontSubmit class
  var $theForm = $(this).closest('form');
  //Some browsers don't implement checkValidity
  if (( typeof($theForm[0].checkValidity) == "function" ) && !$theForm[0].checkValidity()) {
     return;
  }

  //if you've gotten here - play on playa'
});

Algumas notas aqui:

  • Percebi que você não precisa realmente enviar o formulário para que a validação ocorra - a chamada para checkValidity()é suficiente (pelo menos no chrome). Se outras pessoas puderem adicionar comentários ao testar essa teoria em outros navegadores, atualizarei esta resposta.
  • O que aciona a validação não precisa estar dentro do <form>. Esta foi apenas uma maneira limpa e flexível de ter uma solução de uso geral.
rynop
fonte
12

Pode ser tarde para a festa, mas, de alguma forma, encontrei essa pergunta ao tentar resolver um problema semelhante. Como nenhum código desta página funcionou para mim, enquanto isso, eu vim com uma solução que funciona conforme especificado.

O problema é quando o seu <form>DOM contém um único <button>elemento, uma vez acionado, que <button>substituirá automaticamente o formulário. Se você joga com AJAX, provavelmente precisará impedir a ação padrão. Mas há um problema: se você fizer isso, também impedirá a validação básica do HTML5. Portanto, é bom chamar para evitar padrões nesse botão somente se o formulário for válido. Caso contrário, a validação HTML5 o protegerá contra o envio. O jQuery checkValidity()ajudará com isso:

jQuery:

$(document).ready(function() {
  $('#buttonID').on('click', function(event) {
    var isvalidate = $("#formID")[0].checkValidity();
    if (isvalidate) {
      event.preventDefault();
      // HERE YOU CAN PUT YOUR AJAX CALL
    }
  });
});

O código descrito acima permitirá que você use a validação HTML5 básica (com correspondência de tipo e padrão) SEM enviar o formulário.

vzr
fonte
6

Você fala de duas coisas diferentes "validação HTML5" e validação do formulário HTML usando javascript / jquery.

O HTML5 "possui" opções internas para validar um formulário. Como usar o atributo "obrigatório" em um campo, que pode (com base na implementação do navegador) falhar no envio do formulário sem usar javascript / jquery.

Com javascrip / jquery, você pode fazer algo assim

$('your_form_id').bind('submit', function() {
   // validate your form here
   return (valid) ? true : false;
});
Peter Pajchl
fonte
2
Quero acionar a validação sem enviar o formulário.
razenha
Conforme sua atualização - ainda acho que essa é a solução correta. Você não especificou como deseja acionar a triggerHtml5Validation()função. O código acima anexará o evento de envio ao seu formulário; ao enviar, você intercepta o evento e valida o formulário. Se você nunca quiser enviar o formulário, simplesmente return false;e o envio nunca ocorrerá.
Peter Pajchl
7
return (valid) ? true : false=== return valid. :)
Davi Koscianski Vidal
1
Ops, marquei +1 com @davi porque estava pensando exatamente a mesma coisa no início. Mas não é realmente o mesmo, pois simplesmente return validnão retorna false para valores nulos / indefinidos. Mas isso realmente não importa, a resposta foi pseudo-código de qualquer maneira, o ponto é: false uso retorno ao não enviar o formulário ^^
T_d
5
var $myForm = $('#myForm ');
if (!$myForm[0].checkValidity()) {
  $('<input type="submit">').hide().appendTo($myForm).click().remove();
}
Rafik malek
fonte
não funciona no chrome 74. Posso lançar luz sobre ele?
Codexplorer 03/06/19
3

Para verificar todos os campos obrigatórios do formulário sem usar o botão enviar, você pode usar a função abaixo.

Você deve atribuir o atributo necessário aos controles.

  $("#btnSave").click(function () {
    $(":input[required]").each(function () {                     
        var myForm = $('#form1');
        if (!$myForm[0].checkValidity()) 
          {                
            $(myForm).submit();              
          }
        });
  });
Trusha Soni
fonte
3

Você não precisa do jQuery para conseguir isso. No seu formulário, adicione:

onsubmit="return buttonSubmit(this)

ou em JavaScript:

myform.setAttribute("onsubmit", "return buttonSubmit(this)");

Na sua buttonSubmitfunção (ou como você chama), você pode enviar o formulário usando o AJAX. buttonSubmitsó será chamado se seu formulário for validado em HTML5.

Caso isso ajude alguém, aqui está minha buttonSubmitfunção:

function buttonSubmit(e)
{
    var ajax;
    var formData = new FormData();
    for (i = 0; i < e.elements.length; i++)
    {
        if (e.elements[i].type == "submit")
        {
            if (submitvalue == e.elements[i].value)
            {
                submit = e.elements[i];
                submit.disabled = true;
            }
        }
        else if (e.elements[i].type == "radio")
        {
            if (e.elements[i].checked)
                formData.append(e.elements[i].name, e.elements[i].value);
        }
        else
            formData.append(e.elements[i].name, e.elements[i].value);
    }
    formData.append("javascript", "javascript");
    var action = e.action;
    status = action.split('/').reverse()[0] + "-status";
    ajax = new XMLHttpRequest();
    ajax.addEventListener("load", manageLoad, false);
    ajax.addEventListener("error", manageError, false);
    ajax.open("POST", action);
    ajax.send(formData);
    return false;
}

Alguns dos meus formulários contêm vários botões de envio, portanto, esta linha if (submitvalue == e.elements[i].value) . Defino o valor do submitvalueuso de um evento click.

Dan Bray
fonte
2

Eu tive uma situação bastante complexa, onde eu precisava de vários botões de envio para processar coisas diferentes. Por exemplo, Salvar e excluir.

A base era que também era discreto, então eu não podia simplesmente torná-lo um botão normal. Mas também queria utilizar a validação html5.

O evento de envio também foi substituído caso o usuário pressionasse enter para acionar o envio padrão esperado; neste exemplo, salve.

Aqui estão os esforços do processamento do formulário para continuar trabalhando com / sem javascript e com a validação html5, com eventos de envio e clique.

Demonstração do jsFiddle - validação HTML5 com substituições de envio e clique

xHTML

<form>
    <input type="text" required="required" value="" placeholder="test" />
    <button type="submit" name="save">Save</button>
    <button type="submit" name="delete">Delete</button>
</form>

Javascript

//wrap our script in an annonymous function so that it can not be affected by other scripts and does not interact with other scripts
//ensures jQuery is the only thing declared as $
(function($){
    var isValid = null;
    var form = $('form');
    var submitButton = form.find('button[type="submit"]')
    var saveButton = submitButton.filter('[name="save"]');
    var deleteButton = submitButton.filter('[name="delete"]');

    //submit form behavior
    var submitForm = function(e){
        console.log('form submit');
        //prevent form from submitting valid or invalid
        e.preventDefault();
        //user clicked and the form was not valid
        if(isValid === false){
            isValid = null;
            return false;
        }
        //user pressed enter, process as if they clicked save instead
        saveButton.trigger('click');
    };

    //override submit button behavior
    var submitClick = function(e){
        //Test form validitiy (HTML5) and store it in a global variable so both functions can use it
        isValid = form[0].checkValidity();
        if(false === isValid){
            //allow the browser's default submit event behavior 
            return true;
        }
        //prevent default behavior
        e.preventDefault();
        //additional processing - $.ajax() etc
        //.........
        alert('Success');
    };

    //override submit form event
    form.submit(submitForm);

    //override submit button click event
    submitButton.click(submitClick);
})(jQuery);

A ressalva de usar o Javascript é que o onclick padrão do navegador deve se propagar para o evento de envio DEVE ocorrer para exibir as mensagens de erro sem oferecer suporte a cada navegador no seu código. Caso contrário, se o evento click for substituído por event.preventDefault () ou retornar false, ele nunca será propagado para o evento de envio do navegador.

O ponto a ser destacado é que em alguns navegadores não acionará o envio do formulário quando o usuário pressionar enter, em vez disso, acionará o primeiro botão de envio no formulário. Portanto, existe um console.log ('envio de formulário') para mostrar que ele não é acionado.

fyrye
fonte
Temos muita consciência de que isso pode ser feito sem o jQuery, mas o OP criou o título deste tópico: "Como forçar uma validação de formulário html5 sem enviá-lo pelo jQuery", sugerindo explicitamente que o jQuery deve ser usado.
precisa saber é
@vzr Minha resposta usa jQueryexplicitamente. Difere no fato de lidar com o processamento da validação HTML5 com vários botões de envio e impede o envio do formulário AJAX quando inválido. O padrão é a saveação quando o usuário pressiona a entertecla no teclado. Que, no momento da postagem, nenhuma das respostas fornecidas era uma solução para vários botões de envio ou a captura da tecla Enter para impedir o envio do ajax.
Fyrye
2

Você pode fazer isso sem enviar o formulário.

Por exemplo, se o botão de envio do formulário com o ID "pesquisa" estiver no outro formulário. Você pode chamar o evento click nesse botão de envio e chamar ev.preventDefault depois disso. Para o meu caso, valido o formulário B a partir do envio do formulário A. Como isso

function validateFormB(ev){ // DOM Event object
  //search is in Form A
  $("#search").click();
  ev.preventDefault();
  //Form B validation from here on
}
zawhtut
fonte
2

Dessa forma, funciona bem para mim:

  1. Adicione onSubmitatributo no seu form, não se esqueça de incluir returnno valor.

    <form id='frm-contact' method='POST' action='' onSubmit="return contact()">
  2. Defina a função.

    function contact(params) {
        $.ajax({
            url: 'sendmail.php',
            type: "POST",
            dataType: "json",
            timeout: 5000,
            data: { params:params },
            success: function (data, textStatus, jqXHR) {
                // callback
            },
            error: function(jqXHR, textStatus, errorThrown) {
                console.log(jqXHR.responseText);
            }
        });
    
        return false;
    }
Jeaf Gilbert
fonte
1
$("#form").submit(function() { $("#saveButton").attr("disabled", true); });

Não é a melhor resposta, mas funciona para mim.

Keyrr Perino
fonte
1

Sei que isso já foi respondido, mas tenho outra solução possível.

Se estiver usando jquery, você pode fazer isso.

Primeiro, crie algumas extensões no jquery para poder reutilizá-las conforme necessário.

$.extend({
    bypassDefaultSubmit: function (formName, newSubmitMethod) {
        $('#'+formName).submit(function (event) {
            newSubmitMethod();
            event.preventDefault();
        }
    }
});

Em seguida, faça algo assim onde você deseja usá-lo.

<script type="text/javascript">
    /*if you want to validate the form on a submit call, 
      and you never want the form to be submitted via
      a normal submit operation, or maybe you want handle it.
    */
    $(function () {
        $.bypassDefaultSubmit('form1', submit);
    });
    function submit(){ 
        //do something, or nothing if you just want the validation
    }

</script>
David Thompson
fonte
1
$(document).on("submit", false);

submitButton.click(function(e) {
    if (form.checkValidity()) {
        form.submit();
    }
});
Matias Elorriaga
fonte
$ (documento) .on ("enviar", false); // este funcionou perfeitamente, isso é o que eu estava procurando :)
Akshay Shrivastav
1

Isso funcionou comigo para exibir as mensagens de erro HTML 5 nativas com validação de formulário.

<button id="btnRegister" class="btn btn-success btn btn-lg" type="submit"> Register </button>



$('#RegForm').on('submit', function () 
{

if (this.checkValidity() == false) 
{

 // if form is not valid show native error messages 

return false;

}
else
{

 // if form is valid , show please wait message and disable the button

 $("#btnRegister").html("<i class='fa fa-spinner fa-spin'></i> Please Wait...");

 $(this).find(':submit').attr('disabled', 'disabled');

}


});

Nota: RegForm é oform id .

Referência

A esperança ajuda alguém.

shaijut
fonte
você tem que adicionar evento para permitir que as pessoas com deficiência botão enviar
talsibony
1

Essa é uma maneira bastante direta de o HTML5 executar a validação para qualquer formulário, enquanto ainda possui controle JS moderno sobre o formulário. A única ressalva é que o botão enviar deve estar dentro do <form>.

html

<form id="newUserForm" name="create">
Email<input type="email" name="username" id="username" size="25" required>
Phone<input type="tel" id="phone" name="phone" pattern="(?:\(\d{3}\)|\d{3})[- ]?\d{3}[- ]?\d{4}" size="12" maxlength="12" required>
<input id="submit" type="submit" value="Create Account" >
</form>

js

// bind in ready() function
jQuery( "#submit" ).click( newAcctSubmit );

function newAcctSubmit()
{
  var myForm = jQuery( "#newUserForm" );

  // html 5 is doing the form validation for us,
  // so no need here (but backend will need to still for security)
  if ( ! myForm[0].checkValidity() )
  {
    // bonk! failed to validate, so return true which lets the
    // browser show native validation messages to the user
    return true;
  }

  // post form with jQuery or whatever you want to do with a valid form!
  var formVars = myForm.serialize();
  etc...
}
Aaron
fonte
0

Eu acho que a melhor abordagem

estará usando a validação jQuery plugin que utiliza as melhores práticas para validação de formulários e também possui um bom suporte ao navegador. Portanto, você não precisa se preocupar com problemas de compatibilidade do navegador.

E podemos usar a função validation () da validação do jQuery, que verifica se o formulário selecionado é válido ou se todos os elementos selecionados são válidos sem enviar o formulário.

<form id="myform">
   <input type="text" name="name" required>
   <br>
   <button type="button">Validate!</button>
</form>
<script>
  var form = $( "#myform" );
  form.validate();
  $( "button" ).click(function() {
    console.log( "Valid: " + form.valid() );
  });
</script>
طلحة
fonte
0

De acordo com a pergunta, a validade do html5 deve ser validada usando o jQuery no início e na maioria das respostas isso não está acontecendo e a razão para isso é a seguinte:

ao validar usando a função padrão do formulário html5

checkValidity();// returns true/false

precisamos entender que o jQuery retorna a matriz de objetos, enquanto seleciona assim

$("#myForm")

portanto, você precisa especificar o primeiro índice para que a função checkValidity () funcione

$('#myForm')[0].checkValidity()

aqui está a solução completa:

<button type="button" name="button" onclick="saveData()">Save</button>

function saveData()
{
    if($('#myForm')[0].checkValidity()){
        $.ajax({
          type: "POST",
          url: "save.php",
          data: data,
          success: function(resp){console.log("Response: "+resp);}
        });
    }
}
justnajm
fonte