Formularze - walidacja

Sprawdzanie danych, które wprowadza użytkownik to jedna z ważniejszych rzeczy, o jaką musimy zadbać, ale równocześnie też nie zawsze prosta do wykonania. Dane możemy sprawdzać na wiele sposobów, które często będzie uzależnione od budowy formularza i zawartych w nim mechanizmów.

Jak przeprowadzić walidację?

Przykładowa walidacja formularzy może przebiegać w kilku etapach:

  1. Pierwszy etap to dynamiczna podpowiedź w czasie wprowadzania danych przez użytkownika. Wykorzystamy tutaj zdarzenia change, focus, blur, keyup, keydown, keypress lub input - zależnie od sytuacji. Dodanie takich dynamicznych podpowiedzi znacząco może poprawić użyteczność naszego formularza, ale nie zawsze musimy je stosować
  2. Drugi etap to sprawdzenie danych w momencie, gdy użytkownik chce wysłać dany formularz. Jeżeli dane są poprawne, dany formularz wysyłamy. W przeciwnym razie pokazujemy stosowną informację.
  3. Ostatni - najważniejszy etap - to sprawdzenie przesłanych danych po stronie serwera. Jest to najważniejszy krok, ponieważ dane na nasz serwer mogą być wysłane na różne sposoby, nie tylko z naszego formularza.

Prosta walidacja

Domyślną akcją każdego formularza jest wysłanie danych na adres podany w atrybucie action. Jeżeli atrybut ten nie zostanie podany, wtedy wysyłka danych jest wykonywana na aktualny adres.


<form action="https://kursjs.pl/login">
    ...
</form>

Wraz z wysłaniem formularza strona zostanie albo przeniesiona na nowy adres, albo zostanie przeładowana.

Aby zareagować na wysyłkę formularza pierwszą czynnością jest podpiąć się pod zdarzenie submit formularza, a następnie użycie funkcji e.preventDefault(), która przerwie domyślną akcję (wysyłkę):


const form = document.querySelector("form");
const input = form.querySelector("input");

form.addEventListener("submit", e => {
    e.preventDefault();

    //jeżeli wszystko ok to wysyłamy
    if (input.value.length >= 3) {
        form.submit();
    } else {
        //jeżeli nie to pokazujemy jakieś błędy
        alert("Kolego wypełniłeś błędnie nasz super formularz");
    }
})

Przy kilku polach można zbierać wyniki w tablicę. W poniższym kodzie zbieram tam teksty, które pojawią się w komunikacie błędu.

Równocześnie posługiwanie się okienkiem alert nie jest zalecanym rozwiązaniem. Okienko takie jest zbyt "inwazyjne" dla użytkownika, a poza tym nie mamy w ogóle możliwości zmiany jego wyglądu.


<form class="form" method="post" id="form">
    <div class="form-row">
        <label for="name">Imię (min. 3 znaki)*</label>
        <input type="text" name="name" id="name">
    </div>
    <div class="form-row">
        <label for="name">Email*</label>
        <input type="email" name="email" id="email">
    </div>
    <div class="form-message"></div> <!-- tu trafią błędy -->
    <div class="form-row">
        <button type="submit" class="button submit-btn">
            Wyślij
        </button>
    </div>
</form>

const form = document.querySelector("form");
const inputName = form.querySelector("input[name=name]");
const inputEmail = form.querySelector("input[name=email]");
const formMessage = form.querySelector(".form-message");
const regEmail = /\S+@\S+\.\S+/; //wzór do sprawdzania emaili

form.addEventListener("submit", e => {
    e.preventDefault();

    //tablica z błędami
    let formErrors = [];

    if (inputName.value.length <= 3) {
        formErrors.push("Wypełnij poprawnie pole z imieniem");
    }

    //poprawność emaila sprawdzam za pomocą wyrażeń regularnych
    if (!regEmail.test(inputEmail.value)) {
        formErrors.push("Wypełnij poprawnie pole z emailem");
    }

    //jeżeli nie ma błędów wysyłamy formularz
    if (!formErrors.length) {
        form.submit();
        //...lub dynamicznie wysyłamy dane za pomocą Ajax
        //równocześnie reagując na odpowiedź z serwera
    } else {
        //jeżeli jednak są jakieś błędy...
        formMessage.innerHTML = `
            <h3 class="form-error-title">Przed wysłaniem proszę poprawić błędy:</h3>
            <ul class="form-error-list">
                ${formErrors.map(el => `<li>${el}</li>`).join("")}
            </ul>
        `;
    }
});

Powyższy kod moglibyśmy też rozbudować dodając dynamiczne reagowanie pól na stan wypełnienia za pomocą dodawania dodatkowej klasy is-invalid w momencie, gdy pole jest błędnie wypełnione.


const inputName = form.querySelector("input[name=name]");
const inputEmail = form.querySelector("input[name=email]");
const formMessage = form.querySelector(".form-message");
const regEmail = /\S+@\S+\.\S+/;

//dynamiczne podpowiedzi na pól
inputName.addEventListener("input", () => {
    inputName.classList.toggle("is-error", inputName.value.length <= 3);
});

inputEmail.addEventListener("input", () => {
    inputEmail.classList.toggle("is-error", !regEmail.test(inputEmail.value));
});

form.addEventListener("submit", e => {
    e.preventDefault();

    let formErrors = [];

    //usuwam domyślnie wszystkie zaznaczenia błędów
    for (let el of [inputName, inputEmail]) {
        el.classList.remove("is-invalid");
    }

    if (inputName.value.length <= 3) {
        formErrors.push("Wypełnij poprawnie pole z imieniem");
        inputName.classList.add("is-invalid");
    }

    if (!regEmail.test(inputEmail.value)) {
        formErrors.push("Wypełnij poprawnie pole z emailem");
        inputEmail.classList.add("is-invalid");
    }

    if (!formErrors.length) { //jeżeli nie ma błędów wysyłamy formularz
        e.target.submit();
        //...lub dynamicznie wysyłamy dane za pomocą Ajax
        //równocześnie reagując na odpowiedź z serwera
    } else {
        //jeżeli jednak są jakieś błędy...
        formMessage.innerHTML = `
            <h3 class="form-error-title">Proszę poprawić błędy:</h3>
            <ul class="form-error-list">
                ${formErrors.map(el => `<li>${el}</li>`).join("")}
            </ul>
        `;
    }
});

W naszym kodzie testy powtarzają się w kilku miejscach. Warto tutaj dodać odpowiednie funkcje sprawdzające:


const inputName = form.querySelector("input[name=name]");
const inputEmail = form.querySelector("input[name=email]");
const formMessage = form.querySelector(".form-message");

function testFieldName() {
    return inputName.value.length >= 3
}

function testFieldEmail() {
    const regEmail = /\S+@\S+\.\S+/;
    return regEmail.test(inputEmail.value);
}

//dynamiczne podpowiedzi na pól
inputName.addEventListener("input", () => {
    inputName.classList.toggle("is-invalid", !testFieldName());
});

inputEmail.addEventListener("input", () => {
    inputEmail.classList.toggle("is-invalid", !testFieldEmail());
});

form.addEventListener("submit", e => {
    e.preventDefault();

    let formErrors = [];

    //usuwam domyślnie wszystkie zaznaczenia błędów
    for (let field of [inputName, inputEmail]) {
        field.classList.remove("is-invalid");
    }

    if (!testFieldName()) {
        formErrors.push("Wypełnij poprawnie pole z imieniem");
        inputName.classList.add("is-invalid");
    }

    if (!testFieldEmail()) {
        formErrors.push("Wypełnij poprawnie pole z emailem");
        inputEmail.classList.add("is-invalid");
    }

    if (!formErrors.length) {
        form.submit();
    } else {
        formMessage.innerHTML = `
            <h3 class="form-error-title">Proszę poprawić błędy:</h3>
            <ul class="form-error-list">
                ${formErrors.map(el => `<li>${el}</li>`).join("")}
            </ul>
        `;
    }
});

Wszelkie prawa zastrzeżone. Jeżeli chcesz używać jakiejś części tego kursu, skontaktuj się z autorem.
Aha - i ta strona korzysta z ciasteczek.
This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.