In this article, we'll take the example of validating a username in real-time to check it's taken, giving us instant feedback before the user hits submit.
Livewire has great support for real-time validation, making it easy to validate either as the user types or as they move away from each input. Depending on the type of data you're validating (and how quickly you need to provide feedback), I'll show you a couple of methods you can use.
Let's start with some basic validation in a form. I'm using Laravel Breeze here, but if you're not, all of this applied to plain old input fields, too.
Here's the Livewire component template:
<form class="space-y-6" wire:submit="createUser">
<div>
<x-input-label for="username" :value="__('Username')" />
<x-text-input
wire:model="username"
id="username"
class="block mt-1 w-full"
type="text"
name="username"
autofocus
/>
<x-input-error :messages="$errors->get('username')" class="mt-2" />
</div>
<x-primary-button>
{{ __('Create user') }}
</x-primary-button>
</form>
And here's the Livewire class:
class UserCreate extends Component
{
#[Validate('required|unique:users,username')]
public string $username = '';
public function createUser()
{
$this->validate();
//
}
public function render()
{
return view('livewire.user-create');
}
}
If you're already familiar with Livewire and validation, this shouldn't be too difficult to understand. When we submit the form, we validate
the $username
(with the Validate
PHP attribute provided by Livewire) and then perform some action, which I've left out.
Here's what the form looks like with a validation error:
Now, let's add some real-time validation.
The first approach we'll look at is on blur
of an input. This basically means as the user moves away from the input.
I'd recommend this approach with standard forms where instant feedback isn't critical. In our case, a username validation check must be snappy so the user can continue modifying their selection. Let's roll with this first.
Here's what our updated input looks like:
<x-text-input
wire:model.blur="username"
id="username"
class="block mt-1 w-full"
type="text"
name="username"
autofocus
/>
Using the blur
modifier will instruct Livewire to make a network request as the user leaves the input with their cursor. When this happens, validation will be triggered automatically and displayed to the user.
Here's what it looks like:
The next step up (although we have to be careful) is making the input live
.
Adding the live
modifier instructs Livewire to send a network request down for every single change to the value of the input, meaning we get instant validation as the user types — perfect for our username example.
Let's try this out, and then we look at debouncing to avoid too many network requests.
Update the input once again:
<x-text-input
wire:model.live="username"
id="username"
class="block mt-1 w-full"
type="text"
name="username"
autofocus
/>
Here's what the result looks like like:
It's a good idea to debounce
the input here, which allows us to delay when a network request should be made from when the user finishes typing. For example, if we provide a debounce
value of 300ms
, we'll send the request once the user stops typing for 300ms.
Here's the updated input with the debounce
modifier:
<x-text-input
wire:model.live.debounce.300ms="username"
id="username"
class="block mt-1 w-full"
type="text"
name="username"
autofocus
/>
Feel free to tweak this value, but as you can see, we get pretty much the same result — just with fewer network requests.
Hopefully, this article has helped you understand real-time validation in Livewire, and with the couple of options we've looked at, you'll be able to choose what makes sense for your own application.