Wyzwalanie weryfikacji formularza HTML5

103

Mam formularz z kilkoma różnymi zestawami pól. Mam skrypt Javascript, który wyświetla użytkownikom zestawy pól pojedynczo. W przypadku przeglądarek obsługujących walidację HTML5 chciałbym z tego skorzystać. Jednak muszę to zrobić na moich warunkach. Używam JQuery.

Kiedy użytkownik kliknie łącze JS, aby przejść do następnego zestawu pól, potrzebuję, aby walidacja odbyła się na bieżącym zestawie pól i zablokować użytkownikowi przejście do przodu, jeśli wystąpią problemy.

W idealnym przypadku, gdy użytkownik traci koncentrację na elemencie, nastąpi walidacja.

Obecnie novalidate przechodzi i używa Javascript. Wolałby użyć metody natywnej. :)

Rysował
źródło

Odpowiedzi:

60

Nie możesz wyzwolić natywnego interfejsu walidacji, ale możesz łatwo skorzystać z walidacyjnego interfejsu API na dowolnych elementach wejściowych:

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

Pierwsze zdarzenie jest wyzwalane checkValidityna każdym elemencie wejściowym, gdy tylko straci fokus. Jeśli element jest, invalidto odpowiednie zdarzenie zostanie wyzwolone i przechwycone przez drugą procedurę obsługi zdarzenia. Ten ustawia fokus z powrotem na element, ale to może być dość denerwujące, zakładam, że masz lepsze rozwiązanie do powiadamiania o błędach. Oto działający przykład mojego kodu powyżej .

robertc
źródło
20
Złote zdanie „Nie możesz uruchomić natywnego interfejsu walidacji” . W moim przypadku (niestandardowe sztuczki JS + walidacja html5 w przeglądarce + podpowiedzi interfejsu użytkownika) nie miałem innego wyjścia, jak przejść do ukrytego przycisku przesyłania na końcu, aby uzyskać oba
lukmdo
23
Jeśli Twój formularz nie ma przycisku przesyłania, możesz go sfałszować:$('<input type="submit">').hide().appendTo($myForm).click().remove();
philfreo
1
@philfreo Czy form.submit()praca nie byłaby dobra? A może HTML5 wymaga teraz przycisku przesyłania do walidacji?
Mattisdada
@Mattisdada Calling .submit()nie działa dla mnie. Rozwiązanie @ philfreo działa. Hmm.
Zero3
5
To tylko przypomnienie, które checkValiditytylko to sprawdza, ale nie wyświetla standardowej podpowiedzi przeglądarki . Jeśli chcesz też wyskakującego okienka - użyjelement.reportValidity()
Alex
143

TL; DR: Nie przejmujesz się starymi przeglądarkami? Użyj form.reportValidity().

Potrzebujesz obsługi starszych przeglądarek? Czytaj.


W rzeczywistości możliwe jest ręczne uruchomienie walidacji.

W mojej odpowiedzi użyję zwykłego JavaScript, aby poprawić możliwość ponownego użycia, nie jest potrzebne żadne jQuery.


Załóżmy następujący formularz HTML:

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

Chwyćmy nasze elementy UI w JavaScript:

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

Nie potrzebujesz obsługi starszych przeglądarek, takich jak Internet Explorer? To jest dla ciebie.

Wszystkie nowoczesne przeglądarki obsługują ten reportValidity()sposób na formelementy.

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

To wszystko, skończyliśmy. Również tutaj jest prosty CodePen użyciu tego podejścia.


Podejście dla starszych przeglądarek

Poniżej znajduje się szczegółowe wyjaśnienie, w jaki sposób reportValidity()można emulować w starszych przeglądarkach.

Jednak nie musisz samodzielnie kopiować i wklejać tych bloków kodu do swojego projektu - jest łatwo dostępny ponyfill / polyfill .

Tam, gdzie reportValidity()nie jest obsługiwany, musimy trochę oszukać przeglądarkę. Więc co zrobimy?

  1. Sprawdź ważność formularza dzwoniąc form.checkValidity(). To powie nam, czy formularz jest prawidłowy, ale nie pokaże interfejsu użytkownika weryfikacji.
  2. Jeśli formularz jest nieprawidłowy, tworzymy tymczasowy przycisk przesyłania i uruchamiamy jego kliknięcie. Ponieważ formularz jest nieprawidłowy, wiemy, że w rzeczywistości nie zostanie przesłany, jednak wyświetli wskazówki dotyczące weryfikacji użytkownikowi. Natychmiast usuniemy tymczasowy przycisk przesyłania, aby nigdy nie był widoczny dla użytkownika.
  3. Jeśli formularz jest ważny, nie musimy w ogóle ingerować i pozwolić użytkownikowi kontynuować.

W kodzie:

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

Ten kod będzie działał w prawie każdej popularnej przeglądarce (przetestowałem go pomyślnie aż do IE11).

Oto działający przykład CodePen.

Loilo
źródło
To powinna być teraz akceptowana odpowiedź
Maxim Mazurok
22

W pewnym stopniu MOŻESZ triggerwalidować formularz HTML5 i pokazywać wskazówki użytkownikowi bez wysyłania formularza!

Dwa przyciski, jeden do weryfikacji, drugi do przesłania

Ustaw onclickodbiornik na przycisku walidacji, aby ustawić flagę globalną (powiedzmy justValidate), aby wskazać, że to kliknięcie ma na celu sprawdzenie walidacji formularza.

I ustaw onclickodbiornik na przycisku przesyłania, aby ustawić justValidateflagę na fałsz.

Następnie w onsubmitmodule obsługi formularza sprawdzasz flagę, justValidateaby zdecydować o zwracanej wartości i wywołujesz, preventDefault()aby zatrzymać wysyłanie formularza. Jak wiesz, walidacja formularza HTML5 (i wskazówka GUI dla użytkownika) jest wykonywana przed onsubmitzdarzeniem, a nawet jeśli formularz jest PRAWIDŁOWY, możesz zatrzymać przesyłanie formularza, zwracając false lub invoke preventDefault().

A w HTML5 masz metodę sprawdzania walidacji formularza: the form.checkValidity(), wtedy możesz wiedzieć, czy formularz jest poprawny, czy nie w Twoim kodzie.

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

Xieranmaya
źródło
2

Dość łatwo dodać lub usunąć walidację HTML5 do zestawów pól.

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

    });

});
Wreleven
źródło
2

Wydaje mi się, że znalazłem sztuczkę: po prostu usuń targetatrybut formularza , a następnie użyj przycisku przesyłania, aby zatwierdzić formularz i wyświetlić wskazówki, sprawdzić, czy formularz jest prawidłowy za pomocą JavaScript, a następnie opublikować cokolwiek. U mnie działa następujący kod:

<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>
chenxin
źródło
Dzięki! To prawdziwe rozwiązanie dla jQuery.
Vuong
1

Kod HTML:

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

javascript (przy użyciu 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>

Mam nadzieję, że to ci pomoże

Hưng Trịnh
źródło
Dlaczego odpowiada na pytanie?
plik wykonywalny
używając walidacji HTML5 bez przesyłania. i używaj danych formularza do swoich celów: 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">

Ilya webdev
źródło
1
Czy dodałbyś więcej wyjaśnień?
zmag
0

Dla pola wprowadzania

<input id="PrimaryPhNumber" type="text" name="mobile"  required
                                       pattern="^[789]\d{9}$" minlenght="10" maxLength="10" placeholder="Eg: 9444400000"
                                       class="inputBoxCss"/>
$('#PrimaryPhNumber').keyup(function (e) {
        console.log(e)
        let field=$(this)
        if(Number(field.val()).toString()=="NaN"){
            field.val('');
            field.focus();
            field[0].setCustomValidity('Please enter a valid phone number');
            field[0].reportValidity()
            $(":focus").css("border", "2px solid red");
        }
    })
lokesh
źródło
-1

W przypadku bardzo złożonego (zwłaszcza asynchronicznego) procesu walidacji istnieje proste obejście:

<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>
Nadi h
źródło
-2

Inny sposób rozwiązania tego problemu:

$('input').oninvalid(function (event, errorMessage) {
    event.target.focus();
});
Wasyl Bojko
źródło
Nie działa dla mnie, rozumiem: Uncaught TypeError: $(...).oninvalid is not a functioni nie widzę tego w dokumentacji jQuery.
MECU
Myślę, że powinno to mówić „nieprawidłowy”, a nie „oninvalid”, ponieważ używasz tutaj jQuery.
Aenadon