Attivazione della convalida del modulo HTML5


97

Ho un modulo con diversi campi diversi. Ho alcuni Javascript che mostrano i set di campi agli utenti uno alla volta. Per i browser che supportano la convalida HTML5, mi piacerebbe utilizzarlo. Tuttavia, devo farlo alle mie condizioni. Sto usando JQuery.

Quando un utente fa clic su un collegamento JS per passare al fieldset successivo, è necessario che la convalida avvenga sul fieldset corrente e impedisca all'utente di andare avanti in caso di problemi.

Idealmente, quando l'utente perde la concentrazione su un elemento, verrà eseguita la convalida.

Attualmente hanno novalidate in corso e utilizzando Javascript. Preferirei utilizzare il metodo nativo. :)

Risposte:


60

Non è possibile attivare l'interfaccia utente di convalida nativa, ma è possibile sfruttare facilmente l'API di convalida su elementi di input arbitrari:

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

Il primo evento si checkValidityattiva su ogni elemento di input non appena perde il focus, se l'elemento è, invalidl'evento corrispondente verrà attivato e intercettato dal secondo gestore di eventi. Questo riporta il focus sull'elemento, ma potrebbe essere abbastanza fastidioso, presumo che tu abbia una soluzione migliore per notificare gli errori. Ecco un esempio funzionante del mio codice sopra .


20
Frase d'oro "Non puoi attivare l'interfaccia utente di convalida nativa" . Nel mio caso (trucchi JS personalizzati + convalida html5 del browser + tooltip dell'interfaccia utente) non ho avuto altra scelta che utilizzare il pulsante di invio nascosto alla fine per ottenere entrambi
lukmdo

22
Se il tuo modulo non ha un pulsante di invio, puoi falsificarne uno:$('<input type="submit">').hide().appendTo($myForm).click().remove();
philfreo

1
@philfreo Non form.submit()funzionerebbe bene? Oppure HTML5 richiede un pulsante di invio per la convalida ora?
Mattisdada

@ Mattisdada Calling .submit()non funziona per me. La soluzione di @ philfreo funziona. Hmm.
Zero3

129

TL; DR: Non ti interessa i vecchi browser? Usa form.reportValidity().

Hai bisogno del supporto del browser legacy? Continuare a leggere.


In realtà è possibile attivare manualmente la convalida.

Userò JavaScript normale nella mia risposta per migliorare la riusabilità, non è necessario jQuery.


Supponi il seguente modulo HTML:

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

E prendiamo i nostri elementi dell'interfaccia utente in JavaScript:

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

Non hai bisogno del supporto per i browser legacy come Internet Explorer? Questo è per te.

Tutti i browser moderni supportano il reportValidity()metodo sugli formelementi.

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

Ecco fatto, abbiamo finito. Inoltre, ecco un semplice CodePen che utilizza questo approccio.


Approccio per i browser meno recenti

Di seguito è riportata una spiegazione dettagliata di come reportValidity()può essere emulato nei browser meno recenti.

Tuttavia, non è necessario copiare e incollare questi blocchi di codice nel progetto da soli: è disponibile un ponyfill / polyfill prontamente disponibile per te.

Dove reportValidity()non è supportato, dobbiamo ingannare un po 'il browser. Allora, cosa faremo?

  1. Verificare la validità del modulo chiamando form.checkValidity(). Questo ci dirà se il modulo è valido, ma non mostrerà l'interfaccia utente di convalida.
  2. Se il modulo non è valido, creiamo un pulsante di invio temporaneo e attiviamo un clic su di esso. Poiché il modulo non è valido, sappiamo che non verrà effettivamente inviato, tuttavia mostrerà suggerimenti di convalida all'utente. Rimuoveremo immediatamente il pulsante di invio temporaneo, quindi non sarà mai visibile all'utente.
  3. Se il modulo è valido, non è necessario interferire affatto e lasciare che l'utente proceda.

In codice:

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
  }
}

Questo codice funzionerà praticamente in qualsiasi browser comune (l'ho testato con successo fino a IE11).

Ecco un esempio di CodePen funzionante.


22

In una certa misura, PUOI triggerconvalidare il modulo HTML5 e mostrare suggerimenti all'utente senza inviare il modulo!

Due pulsanti, uno per la convalida, uno per l'invio

Imposta un onclicklistener sul pulsante di convalida per impostare un flag globale (diciamo justValidate) per indicare che questo clic è destinato a verificare la convalida del modulo.

E imposta un onclicklistener sul pulsante di invio per impostare il justValidateflag su false.

Quindi nel onsubmitgestore del modulo, controlli il flag justValidateper decidere il valore restituito e invoca il preventDefault()per interrompere il modulo da inviare. Come sai, la convalida del modulo HTML5 (e il suggerimento della GUI per l'utente) viene eseguita prima onsubmitdell'evento, e anche se il modulo è VALIDO puoi interrompere l'invio del modulo restituendo false o invoke preventDefault().

Inoltre, in HTML5 hai un metodo per verificare la convalida del modulo: il form.checkValidity(), quindi puoi sapere se il modulo è convalidato o meno nel tuo codice.

OK, ecco la demo: http://jsbin.com/buvuku/2/edit



2

Abbastanza facile aggiungere o rimuovere la convalida HTML5 ai fieldset.

 $('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

Mi sembra di trovare il trucco: basta rimuovere l' targetattributo del modulo , quindi utilizzare un pulsante di invio per convalidare il modulo e mostrare i suggerimenti, controllare se il modulo è valido tramite JavaScript, quindi pubblicare qualsiasi cosa. Il codice seguente funziona per me:

<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>

Grazie! È la vera soluzione per jQuery.
Vuong

1

Codice HTML:

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

javascript (utilizzando 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>

Spero che questo ti possa aiutare


Perché sta rispondendo alla domanda?
eseguibile

utilizzando HTML5 convalidare senza inviare. e usa i dati del modulo per il tuo scopo: 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
Aggiungeresti altre spiegazioni?
zmag

-1

Quando è presente un processo di convalida molto complesso (soprattutto asincrono), è disponibile una soluzione semplice:

<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

Un altro modo per risolvere questo problema:

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

Non funziona per me, ottengo: Uncaught TypeError: $(...).oninvalid is not a functione non lo vedo nei documenti jQuery.
MECU

Penso che dovrebbe dire "non valido" e non "oninvalid" poiché stai usando jQuery qui.
Aenadon
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.