Activación de la validación de formularios HTML5


97

Tengo un formulario con varios conjuntos de campos diferentes. Tengo algo de Javascript que muestra los conjuntos de campos a los usuarios uno a la vez. Para los navegadores que admiten la validación de HTML5, me encantaría utilizarlo. Sin embargo, necesito hacerlo en mis términos. Estoy usando JQuery.

Cuando un usuario hace clic en un enlace JS para pasar al siguiente conjunto de campos, necesito que la validación se realice en el conjunto de campos actual y bloquee al usuario para que no avance si hay problemas.

Idealmente, cuando el usuario pierde el foco en un elemento, se producirá la validación.

Actualmente no se ha validado el uso de Javascript. Preferiría utilizar el método nativo. :)

Respuestas:


60

No puede activar la IU de validación nativa, pero puede aprovechar fácilmente la API de validación en elementos de entrada arbitrarios:

$('input').blur(function(event) {
    event.target.checkValidity();
}).bind('invalid', function(event) {
    setTimeout(function() { $(event.target).focus();}, 50);
});

El primer evento se dispara checkValidityen cada elemento de entrada tan pronto como pierde el foco, si el elemento es, invalidentonces el evento correspondiente será disparado y atrapado por el segundo controlador de eventos. Este vuelve a centrar la atención en el elemento, pero eso podría ser bastante molesto, supongo que tiene una mejor solución para notificar los errores. Aquí hay un ejemplo funcional de mi código anterior .


20
Oración dorada "No se puede activar la IU de validación nativa" . En mi caso (trucos JS personalizados + validación html5 del navegador + información sobre herramientas de la interfaz de usuario), no tuve más remedio que buscar el botón de envío oculto al final para obtener ambos
lukmdo

22
Si su formulario no tiene un botón de envío, puede falsificar uno:$('<input type="submit">').hide().appendTo($myForm).click().remove();
philfreo

1
@philfreo ¿No estaría bien un form.submit()trabajo? ¿O HTML5 requiere un botón de envío para la validación ahora?
Mattisdada

@Mattisdada Calling .submit()no funciona para mí. La solución de @ philfreo funciona. Hmm.
Zero3

129

TL; DR: ¿ No te preocupas por los navegadores antiguos? Utilice form.reportValidity().

¿Necesita compatibilidad con navegadores heredados? Sigue leyendo.


De hecho, es posible activar la validación manualmente.

Usaré JavaScript simple en mi respuesta para mejorar la reutilización, no se necesita jQuery.


Asuma el siguiente formulario HTML:

<form>
  <input required>
  <button type="button">Trigger validation</button>
</form>

Y tomemos nuestros elementos de la interfaz de usuario en JavaScript:

var form = document.querySelector('form')
var triggerButton = document.querySelector('button')

¿No necesita compatibilidad con navegadores heredados como Internet Explorer? Esto es para ti.

Todos los navegadores modernos admiten el reportValidity()método en formelementos.

triggerButton.onclick = function () {
    form.reportValidity()
}

Eso es todo, hemos terminado. Además, aquí hay un CodePen simple que usa este enfoque.


Enfoque para navegadores más antiguos

A continuación se muestra una explicación detallada de cómo reportValidity()se puede emular en navegadores más antiguos.

Sin embargo, no es necesario que copie y pegue esos bloques de código en su proyecto usted mismo; hay un ponyfill / polyfill disponible para usted.

Donde reportValidity()no es compatible, necesitamos engañar un poco al navegador. ¿Entonces que haremos?

  1. Compruebe la validez del formulario llamando form.checkValidity(). Esto nos dirá si el formulario es válido, pero no mostrará la IU de validación.
  2. Si el formulario no es válido, creamos un botón de envío temporal y hacemos clic en él. Dado que el formulario no es válido, sabemos que en realidad no se enviará , sin embargo, mostrará sugerencias de validación al usuario. Eliminaremos el botón de envío temporal de inmediato, por lo que nunca será visible para el usuario.
  3. Si el formulario es válido, no necesitamos interferir en absoluto y dejar que el usuario continúe.

En codigo:

triggerButton.onclick = function () {
  // Form is invalid!
  if (!form.checkValidity()) {
    // Create the temporary button, click and remove it
    var tmpSubmit = document.createElement('button')
    form.appendChild(tmpSubmit)
    tmpSubmit.click()
    form.removeChild(tmpSubmit)

  } else {
    // Form is valid, let the user proceed or do whatever we need to
  }
}

Este código funcionará en prácticamente cualquier navegador común (lo he probado con éxito hasta IE11).

Aquí hay un ejemplo de CodePen funcional.


22

¡Hasta cierto punto, PUEDE la triggervalidación de formularios HTML5 y mostrar sugerencias al usuario sin enviar el formulario!

Dos botones, uno para validar, otro para enviar

Establezca un onclickoyente en el botón de validación para establecer una bandera global (por ejemplo justValidate) para indicar que este clic está destinado a verificar la validación del formulario.

Y establezca un onclickoyente en el botón enviar para establecer la justValidatebandera en falso.

Luego, en el onsubmitcontrolador del formulario, verifica la bandera justValidatepara decidir el valor devuelto e invoca el preventDefault()para detener el envío del formulario. Como sabe, la validación del formulario HTML5 (y la sugerencia de la GUI para el usuario) se realiza antes del onsubmitevento, e incluso si el formulario es VÁLIDO, puede detener el envío del formulario devolviendo falso o invocando preventDefault().

Y, en HTML5 tienes un método para verificar la validación del formulario: el form.checkValidity(), luego puedes saber si el formulario está validado o no en tu código.

Bien, aquí está la demostración: http://jsbin.com/buvuku/2/edit



2

Algo fácil de hacer para agregar o eliminar la validación HTML5 a los conjuntos de campos.

 $('form').each(function(){

    // CLEAR OUT ALL THE HTML5 REQUIRED ATTRS
    $(this).find('.required').attr('required', false);

    // ADD THEM BACK TO THE CURRENT FIELDSET
    // I'M JUST USING A CLASS TO IDENTIFY REQUIRED FIELDS
    $(this).find('fieldset.current .required').attr('required', true);

    $(this).submit(function(){

        var current     = $(this).find('fieldset.current')
        var next        = $(current).next()

        // MOVE THE CURRENT MARKER
        $(current).removeClass('current');
        $(next).addClass('current');

        // ADD THE REQUIRED TAGS TO THE NEXT PART
        // NO NEED TO REMOVE THE OLD ONES
        // SINCE THEY SHOULD BE FILLED OUT CORRECTLY
        $(next).find('.required').attr('required', true);

    });

});

2

Parece que encuentro el truco: simplemente elimine el targetatributo de formulario , luego use un botón de envío para validar el formulario y mostrar sugerencias, verifique si el formulario es válido a través de JavaScript y luego publique lo que sea. El siguiente código funciona para mí:

<form>
  <input name="foo" required>
  <button id="submit">Submit</button>
</form>

<script>
$('#submit').click( function(e){
  var isValid = true;
  $('form input').map(function() {
    isValid &= this.validity['valid'] ;
  }) ;
  if (isValid) {
    console.log('valid!');
    // post something..
  } else
    console.log('not valid!');
});
</script>

¡Gracias! Es la verdadera solución para jQuery.
Vuong

1

Código HTML:

<form class="validateDontSubmit">
....
<button style="dislay:none">submit</button>
</form>
<button class="outside"></button>

javascript (usando Jquery):

<script type="text/javascript">

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

$(document).ready(function(){
// using button outside trigger click
    $('.outside').click(function() {
        $('.validateDontSubmit button').trigger('click');
    });
});
</script>

Espero que esto te ayudará


¿Por qué responde la pregunta?
ejecutable el

Validar utilizando HTML5 sin enviar. y use los datos del formulario para su propósito: form_data = $ ('. validateDontSubmit'). serializeArray ();
Hưng Trịnh

1

var field = $("#field")
field.keyup(function(ev){
    if(field[0].value.length < 10) {
        field[0].setCustomValidity("characters less than 10")
        
    }else if (field[0].value.length === 10) {
        field[0].setCustomValidity("characters equal to 10")
        
    }else if (field[0].value.length > 10 && field[0].value.length < 20) {
        field[0].setCustomValidity("characters greater than 10 and less than 20")
        
    }else if(field[0].validity.typeMismatch) {
    	field[0].setCustomValidity("wrong email message")
        
    }else {
    	field[0].setCustomValidity("") // no more errors
        
    }
    field[0].reportValidity()
    
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input type="email" id="field">


1
¿Agregarías más explicación?
zmag

-1

Cuando hay un proceso de validación muy complejo (especialmente asincrónico), existe una solución simple:

<form id="form1">
<input type="button" onclick="javascript:submitIfVeryComplexValidationIsOk()" />
<input type="submit" id="form1_submit_hidden" style="display:none" />
</form>
...
<script>
function submitIfVeryComplexValidationIsOk() {
    var form1 = document.forms['form1']
    if (!form1.checkValidity()) {
        $("#form1_submit_hidden").click()
        return
    }

    if (checkForVeryComplexValidation() === 'Ok') {
         form1.submit()
    } else {
         alert('form is invalid')
    }
}
</script>

-2

Otra forma de resolver este problema:

$('input').oninvalid(function (event, errorMessage) {
    event.target.focus();
});

No funciona para mí, obtengo: Uncaught TypeError: $(...).oninvalid is not a functiony no lo veo en los documentos de jQuery.
MECU

Creo que debería decir "no válido" y no "oninvalid" ya que está usando jQuery aquí.
Aenadon
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.