Obsługa formularzy i walidacja w Livewire

Livewire to jedno z najpotężniejszych narzędzi w ekosystemie Laravel, umożliwiające tworzenie dynamicznych aplikacji webowych przy minimalnej ilości JavaScriptu. Jednym z najczęściej wykorzystywanych przypadków w Livewire jest obsługa formularzy oraz walidacja danych. Dzięki Livewire możemy łatwo tworzyć formularze, dynamicznie je walidować i od razu informować użytkowników o błędach, co znacząco poprawia doświadczenie użytkownika.

W tym artykule przyjrzymy się, jak wykorzystać Livewire do tworzenia formularzy, walidacji danych oraz wyświetlania komunikatów błędów. Omówimy zarówno walidację w locie, jak i walidację przy wysyłce formularza.

Artykuł jest kontynuacją poprzednich wpisów:

Tworzenie formularzy z Livewire

Livewire pozwala na łatwe tworzenie formularzy w połączeniu z modelowaniem danych za pomocą wire:model. Dzięki temu możemy związać pole formularza z odpowiednią właściwością w komponencie Livewire, a każde wprowadzone dane zostaną natychmiast zaktualizowane w komponencie.

Przykład formularza rejestracji:

				
					<div>
    <form wire:submit.prevent="submit">
        <div>
            <label for="name">Name</label>
            <input type="text" id="name" wire:model="name">
        </div>
        <div>
            <label for="email">Email</label>
            <input type="email" id="email" wire:model="email">
        </div>
        <div>
            <label for="password">Password</label>
            <input type="password" id="password" wire:model="password">
        </div>
        <button type="submit">Register</button>
    </form>
</div>

				
			

W powyższym przykładzie, każdy z formularzy jest powiązany z odpowiednią właściwością w komponencie Livewire. Oznaczenie wire:model powoduje, że każda zmiana w formularzu będzie natychmiastowo synchronizowana z danymi w komponencie.

Walidacja w locie – validateOnly()

Livewire umożliwia dynamiczną walidację w locie, co pozwala na natychmiastowe sprawdzenie poprawności danych bez konieczności wysyłania całego formularza. Dzięki metodzie validateOnly() możemy walidować pojedyncze pole formularza, gdy użytkownik zmienia jego wartość.

Przykład walidacji w locie:

				
					public $name, $email, $password;

protected $rules = [
    'name' => 'required|min:3',
    'email' => 'required|email',
    'password' => 'required|min:8',
];

public function updated($propertyName)
{
    $this->validateOnly($propertyName);
}

				
			

W tym przypadku, metoda updated() jest wywoływana, gdy zmienia się jakakolwiek wartość w komponencie. Zastosowanie metody validateOnly($propertyName) pozwala na walidację tylko tego pola, które zostało zmodyfikowane, co zapewnia dynamiczne wyświetlanie błędów walidacyjnych przy każdym wprowadzanym znaku.

Walidacja przy wysyłce formularza – validate()

W przeciwieństwie do walidacji w locie, walidacja przy wysyłce formularza jest przeprowadzana, gdy użytkownik wysyła formularz. Możemy wówczas zwalidować wszystkie pola na raz i na podstawie wyników walidacji podjąć odpowiednie działania.

				
					public function submit()
{
    $this->validate();

    // Zapis danych do bazy danych
    User::create([
        'name' => $this->name,
        'email' => $this->email,
        'password' => bcrypt($this->password),
    ]);

    session()->flash('message', 'Rejestracja zakończona sukcesem!');
}

				
			

Metoda validate() waliduje wszystkie pola w komponencie zgodnie z regułami określonymi w $rules. Jeśli wszystkie dane są poprawne, komponent może kontynuować operację, np. zapisanie danych do bazy. W przypadku błędów walidacyjnych, Livewire automatycznie wyświetli komunikaty błędów, które mogą być później użyte w widoku.

Reguły walidacji – $rules i $messages

Reguły walidacji w Livewire są definiowane w zmiennej $rules. Są one takie same jak w tradycyjnym Laravelu, a Livewire korzysta z wbudowanej funkcji walidacji Laravel. Dodatkowo możemy dostarczyć własne komunikaty błędów, które będą wyświetlane, gdy walidacja nie powiedzie się.

				
					protected $rules = [
    'name' => 'required|min:3',
    'email' => 'required|email|unique:users,email',
    'password' => 'required|min:8|confirmed',
];

protected $messages = [
    'name.required' => 'Pole imienia jest wymagane.',
    'email.required' => 'Pole email jest wymagane.',
    'email.email' => 'Proszę podać poprawny adres email.',
    'password.required' => 'Hasło jest wymagane.',
    'password.confirmed' => 'Hasła muszą się zgadzać.',
];

				
			

Dzięki zmiennej $messages, możemy dostarczyć bardziej przyjazne dla użytkownika komunikaty błędów. Warto zauważyć, że metoda confirmed dla hasła sprawdza, czy pole password_confirmation jest zgodne z polem password, co jest typowe w przypadku rejestracji.

Obsługa komunikatów błędów w widoku Blade

Aby wyświetlić komunikaty błędów w formularzu, możemy użyć dyrektywy @error. Jest to proste w użyciu i pozwala na dynamiczne wyświetlanie błędów pod odpowiednimi polami formularza.

				
					<form wire:submit.prevent="submit">
    <div>
        <label for="name">Name</label>
        <input type="text" id="name" wire:model="name">
        @error('name') <span class="error">{{ $message }}</span> @enderror
    </div>
    <div>
        <label for="email">Email</label>
        <input type="email" id="email" wire:model="email">
        @error('email') <span class="error">{{ $message }}</span> @enderror
    </div>
    <div>
        <label for="password">Password</label>
        <input type="password" id="password" wire:model="password">
        @error('password') <span class="error">{{ $message }}</span> @enderror
    </div>
    <button type="submit">Register</button>
</form>

				
			

Jeśli pole formularza ma błąd, komunikat zostanie wyświetlony bezpośrednio pod odpowiednim polem. Dyrektywa @error sprawdza, czy dla danego pola istnieją błędy, a jeśli tak, to wyświetla komunikat błędu.

Ćwiczenia

  1. Prosty formularz rejestracji – Stwórzmy formularz z polami name, email, password i zaimplementujmy walidację:

				
					public $name, $email, $password;

protected $rules = [
    'name' => 'required|min:3',
    'email' => 'required|email|unique:users,email',
    'password' => 'required|min:8|confirmed',
];

public function submit()
{
    $this->validate();

    User::create([
        'name' => $this->name,
        'email' => $this->email,
        'password' => bcrypt($this->password),
    ]);

    session()->flash('message', 'Rejestracja zakończona sukcesem!');
}

				
			
  1. Dynamiczne wyświetlanie błędów – Dodajmy walidację w locie za pomocą validateOnly():
				
					public function updated($propertyName)
{
    $this->validateOnly($propertyName);
}

				
			
  1. Rozszerzenie formularza – Dodajmy pole password_confirmation oraz walidację unikalności adresu e-mail w bazie:
				
					public $password_confirmation;

protected $rules = [
    'name' => 'required|min:3',
    'email' => 'required|email|unique:users,email',
    'password' => 'required|min:8|confirmed',
    'password_confirmation' => 'required|same:password',
];

				
			

Podsumowanie

Livewire daje ogromne możliwości w zakresie obsługi formularzy i walidacji, umożliwiając tworzenie dynamicznych, interaktywnych formularzy bez konieczności używania JavaScriptu. Dzięki metodzie validate() i validateOnly() możemy zarówno walidować dane przy wysyłce formularza, jak i na bieżąco w trakcie jego wypełniania. Odpowiednia konfiguracja $rules i $messages pozwala na łatwą walidację oraz dostosowanie komunikatów błędów, co znacząco poprawia doświadczenie użytkownika.