Skip to main content

Text Version of the Lesson

Looking at the previous example of country/city form, let's talk about binding the inputs to properties and saving their data.

We have three goals in this lesson:

  • Submit the form to save data to DB
  • Show the success alert
  • Clear the form inputs

All without the page refresh.


Simple Tailwind Design

To demonstrate the form refresh without the full page refresh, I've added a very simple Tailwind design (thanks ChatGPT):

Here's the updated HTML of the Blade files.

resources/views/companies/create.blade.php:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Simple Form</title>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body class="flex items-center justify-center min-h-screen bg-gray-100">
<livewire:company-create />
</body>
</html>

And then the dynamic Livewire blade:

resources/views/livewire/company-create.blade.php:

<div class="w-full max-w-md p-6 bg-white rounded-lg shadow-md">
<form>
<div class="mb-4">
<label for="name" class="block text-gray-700">Company name</label>
<input wire:model="name" type="text" required id="name" class="w-full p-2 mt-1 border rounded border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500">
</div>
<div class="mb-4">
<label for="country" class="block text-gray-700">Country</label>
<select wire:model.live="country" required id="country" class="w-full p-2 mt-1 border rounded border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500">
<option value="">-- choose country --</option>
@foreach ($countries as $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
@endforeach
</select>
</div>
<div class="mb-4">
<label for="city" class="block text-gray-700">City</label>
<select wire:model="city" required id="city" class="w-full p-2 mt-1 border rounded border-gray-300 focus:outline-none focus:ring-2 focus:ring-blue-500">
@forelse($cities as $city)
<option value="{{ $city->id }}">{{ $city->name }}</option>
@empty
<option value="">-- choose country first --</option>
@endforelse
</select>
</div>
<button type="submit" class="w-full p-2 text-white bg-blue-500 rounded hover:bg-blue-600">Submit</button>
</form>
</div>

The important bits for us are the Livewire bindings for three fields:

  • input wire:model="name"
  • select wire:model.live="country" (why ".live?" - we'll discuss in a minute)
  • select wire:model="city"

With those wire:model pieces, we bind the Blade/HTML inputs to the...

The Full Lesson is Only for Premium Members

Want to access all of our courses? (30 h 09 min)

You also get:

55 courses
Premium tutorials
Access to repositories
Private Discord
Get Premium for $129/year or $29/month

Already a member? Login here

Comments & Discussion

M
mfiazahmad ✓ Link copied!

There is another way that I found to solve the same bug:-

Instead of adding:- $this->city = $this->cities->first()->id; in the updated webhook.

What I did:-

  1. Made city field required in the validation
  2. Reset the value of city in the updated webhook like this $this->reset(['city']);
M
mewtonium ✓ Link copied!

I used a flash message instead of defining another property on the component:

public function save(): void
{
Company::create([
'name' => $this->company,
'city_id' => $this->city,
]);
 
session()->flash('success', 'Company "'.$this->company.'" saved successfully');
 
$this->reset('company', 'country', 'city', 'cities');
}
@if (session()->has('success'))
<div class="mb-4 p-4 text-green-700 bg-green-100 border border-green-400 rounded">
{{ session()->get('success') }}
</div>
@endif

We'd Love Your Feedback

Tell us what you like or what we can improve

Feel free to share anything you like or dislike about this page or the platform in general.