Validation Laravel Livewire - CRUDPRO

Validation Laravel Livewire

Verifikasi dengan Livewire seharusnya terasa sama dengan verifikasi dengan form standar di Laravel. Artinya, Livewire menyediakan properti $rules untuk menetapkan aturan validasi untuk setiap component dan metode $this->validation() untuk menggunakan aturan tersebut guna memvalidasi properti component, berikut ini adalah contoh sederhana dari form Livewire yang sedang divalidasi.

class ContactForm extends Component
{
    public $name;
    public $email;
 
    protected $rules = [
        'name' => 'required|min:6',
        'email' => 'required|email',
    ];
 
    public function submit()
    {
        $this->validate();
 
        // Execution doesn't reach here if validation fails.
 
        Contact::create([
            'name' => $this->name,
            'email' => $this->email,
        ]);
    }
}
<form wire:submit.prevent="submit">
    <input type="text" wire:model="name">
    @error('name') <span class="error">{{ $message }}</span> @enderror
 
    <input type="text" wire:model="email">
    @error('email') <span class="error">{{ $message }}</span> @enderror
 
    <button type="submit">Save Contact</button>
</form>

Jika validasi gagal, ValidationException standar dilempar (dan ditangkap oleh Livewire) dan objek $error standar tersedia di tampilan component. Oleh karena itu, kode yang ada yang mungkin disertakan dalam Blade untuk menangani validasi untuk aplikasi lainnya juga diterapkan di sini. Anda juga dapat menambahkan key/message pasang ke tas kesalahan.

$this->addError('key', 'message')

Jika Anda perlu mendefinisikan aturan secara dinamis, Anda dapat mengganti properti $rules dengan metode rules() pada component:

class ContactForm extends Component
{
    public $name;
    public $email;
 
    protected function rules()
    {
        return [
            'name' => 'required|min:6',
            'email' => ['required', 'email', 'not_in:' . auth()->user()->email],
        ];
    }
}

Real-time Validation

Terkadang berguna untuk memvalidasi form field saat pengguna mengetik ke dalamnya. Livewire membuat validasi "real-time" menjadi sederhana dengan metode $this->validationOnly().

Untuk memvalidasi field input setiap ada pembaharuan, kita dapat menggunakan Livewire's update hook:

class ContactForm extends Component
{
    public $name;
    public $email;
 
    protected $rules = [
        'name' => 'required|min:6',
        'email' => 'required|email',
    ];
 
    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
    }
 
    public function saveContact()
    {
        $validatedData = $this->validate();
 
        Contact::create($validatedData);
    }
}
<form wire:submit.prevent="saveContact">
    <input type="text" wire:model="name">
    @error('name') <span class="error">{{ $message }}</span> @enderror
 
    <input type="text" wire:model="email">
    @error('email') <span class="error">{{ $message }}</span> @enderror
 
    <button type="submit">Save Contact</button>
</form>

Mari kita menganalisis dengan tepat apa yang terjadi dalam contoh ini:

Pengguna mengisi field Nama

Saat pengguna memasukkan nama, pesan validasi ditampilkan jika kurang dari 6 karakter Pengguna dapat beralih ke input email, tetapi pesan konfirmasi nama akan tetap ditampilkan saat pengguna mengirimkan form, pemeriksaan validasi akhir dilakukan dan data disimpan.

“Mengapa saya perlu memvalidasiOnly? Tidak bisakah saya menggunakan validasi?” Alasannya adalah karena jika tidak, setiap bidang divalidasi setiap kali Anda memperbarui bidang apa pun. Ini bisa menjadi pengalaman pengguna yang tidak menyenangkan. Misalkan Anda mengetik satu karakter di field pertama form dan tiba-tiba semua field menampilkan pesan validasi. validasiOnly mencegah itu dan hanya memvalidasi bidang saat ini yang diperbarui.

Memvalidasi dengan aturan di luar properti $rules

Jika karena alasan tertentu Anda ingin memvalidasi menggunakan aturan selain yang ditentukan dalam properti $rules, Anda selalu dapat melakukannya dengan meneruskan aturan secara langsung ke metode validasi() dan validasiOnly().

class ContactForm extends Component
{
    public $name;
    public $email;
 
    public function updated($propertyName)
    {
        $this->validateOnly($propertyName, [
            'name' => 'min:6',
            'email' => 'email',
        ]);
    }
 
    public function saveContact()
    {
        $validatedData = $this->validate([
            'name' => 'required|min:6',
            'email' => 'required|email',
        ]);
 
        Contact::create($validatedData);
    }
}

Sesuaikan Error Message & Atribut

Jika Anda ingin menyesuaikan pesan validasi yang digunakan oleh komponen Livewire, Anda dapat menyesuaikannya menggunakan properti $messages.

Jika Anda ingin menyimpan pesan validasi Laravel default, tetapi hanya menyesuaikan bagian :atribute pesan, Anda dapat menentukan nama atribut khusus menggunakan properti $validasiAttributes.

class ContactForm extends Component
{
    public $email;
 
    protected $rules = [
        'email' => 'required|email',
    ];
 
    protected $messages = [
        'email.required' => 'The Email Address cannot be empty.',
        'email.email' => 'The Email Address format is not valid.',
    ];
 
    protected $validationAttributes = [
        'email' => 'email address'
    ];
 
    public function updated($propertyName)
    {
        $this->validateOnly($propertyName);
    }
 
    public function saveContact()
    {
        $validatedData = $this->validate();
 
        Contact::create($validatedData);
    }
}

Jika Anda tidak menggunakan properti validasi aturan $global, Anda dapat meneruskan pesan dan atribut khusus secara langsung ke validasi().

class ContactForm extends Component
{
    public $email;
 
    public function saveContact()
    {
        $validatedData = $this->validate(
            ['email' => 'required|email'],
            [
                'email.required' => 'The :attribute cannot be empty.',
                'email.email' => 'The :attribute format is not valid.',
            ],
            ['email' => 'Email Address']
        );
 
        Contact::create($validatedData);
    }
}

Manipulasi Pesan Kesalahan Langsung

Metode validasi() dan ValidasiOnly() perlu menangani sebagian besar waktu, tetapi Anda mungkin ingin mengontrol ErrorBag internal Livewire secara langsung. Livewire menyediakan beberapa metode untuk bekerja secara langsung dengan ErrorBag. Anda dapat memanggil metode berikut dari mana saja di kelas komponen Livewire:

// Quickly add a validation message to the error bag.
$this->addError('email', 'The email field is invalid.');
 
// These two methods do the same thing, they clear the error bag.
$this->resetErrorBag();
$this->resetValidation();
 
// If you only want to clear errors for one key, you can use:
$this->resetValidation('email');
$this->resetErrorBag('email');
 
// This will give you full access to the error bag.
$errors = $this->getErrorBag();
// With this error bag instance, you can do things like this:
$errors->add('some-key', 'Some message');

Access Validator instance

Anda mungkin ingin mengakses instans Validator yang digunakan Livewire dengan metode validasi() dan validasiOnly(). Ini dimungkinkan menggunakan metode withValidator. Penutupan yang ditentukan mengambil validator yang dibangun sepenuhnya sebagai argumen dan dapat memanggil salah satu metodenya sebelum aturan validasi benar-benar dievaluasi.

use Illuminate\Validation\Validator;
 
class ContactForm extends Component
{
    public function save()
    {
        $this->withValidator(function (Validator $validator) {
            $validator->after(function ($validator) {
                if ($this->somethingElseIsInvalid()) {
                    $validator->errors()->add('field', 'Something is wrong with this field!');
                }
            });
        })->validate();
    }
}

Testing Validation

Livewire menyediakan utilitas pengujian untuk membantu Anda dalam skenario validasi. Mari kita tulis tes sederhana dari komponen "form Kontak" asli.

/** @test  */
public function name_and_email_fields_are_required_for_saving_a_contact()
{
    Livewire::test('contact-form')
        ->set('name', '')
        ->set('email', '')
        ->assertHasErrors(['name', 'email']);
}

Ini nyaman, tetapi Anda dapat melangkah lebih jauh dan benar-benar menguji terhadap aturan validasi tertentu.

/** @test  */
public function name_and_email_fields_are_required_for_saving_a_contact()
{
    Livewire::test('contact-form')
        ->set('name', '')
        ->set('email', '')
        ->assertHasErrors([
            'name' => 'required',
            'email' => 'required',
        ]);
}

Livewire juga menyediakan kebalikan dari assertHasErrors->assertHasNoErrors().

/** @test  */
public function name_field_is_required_for_saving_a_contact()
{
    Livewire::test('contact-form')
        ->set('name', '')
        ->set('email', 'foo')
        ->assertHasErrors(['name' => 'required'])
        ->assertHasNoErrors(['email' => 'required']);
}

Lihat dokumentasi pengujian untuk lebih banyak contoh sintaks yang didukung oleh kedua metode ini.

Custom validators

Jika Anda ingin menggunakan sistem verifikasi Anda sendiri dengan Livewire, itu tidak masalah. Livewire menangkap ValidationException dan memberikan kesalahan pada tampilan dengan cara yang sama seperti menggunakan $this->validasi().

Misalnya:
use Illuminate\Support\Facades\Validator;
 
class ContactForm extends Component
{
    public $email;
 
    public function saveContact()
    {
        $validatedData = Validator::make(
            ['email' => $this->email],
            ['email' => 'required|email'],
            ['required' => 'The :attribute field is required'],
        )->validate();
 
        Contact::create($validatedData);
    }
}
<div>
    Email: <input wire:model.lazy="email">
 
    @if($errors->has('email'))
        <span>{{ $errors->first('email') }}</span>
    @endif
 
    <button wire:click="saveContact">Save Contact</button>
</div>

Anda mungkin bertanya-tanya apakah Anda dapat menggunakan "Permintaan form" Laravel. Karena sifat Livewire, tidak masuk akal untuk menghubungkan ke permintaan http. Saat ini, fitur ini tidak tersedia atau tidak digunakan lagi.