Courses

Livewire 3 for Beginners with Laravel 12 Starter Kit

Livewire Demo: Country/City Dropdowns

Summary of this lesson:
- Demo of dynamic country/city dropdown form example
- Showing Livewire installation and component creation process
- Comparing code before and after Livewire implementation
- Explaining Livewire component structure and `wire:model` binding

In this first lesson, I want to demonstrate Livewire in action, explaining the installation and syntax along the way.


Intro: The Project

Imagine you have a form with country/city dropdown fields:

You want the form to be dynamic, so whenever a country is chosen, the city list will auto-reload with cities from that specific country.

Notice: I intentionally left out any CSS or design so we could focus on the functionality.

A typical way to do it would be with JavaScript and frameworks like Vue or React.

But Livewire allows you to achieve it without writing any line of JavaScript.

Let me show you.

If you want to follow along with the repository, the link to GitHub will be at the end of this lesson.


Code BEFORE Livewire

So, this is the initial code of Controller + Blade, without Livewire:

app/Http/Controllers/CompanyController.php:

namespace App\Http\Controllers;
 
use App\Models\Country;
 
class CompanyController extends Controller
{
public function create()
{
$countries = Country::all();
 
return view('companies.create', compact('countries'));
}
}

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

<html>
<body>
<form>
<label for="name">Company name</label>
<br />
<input name="name" required />
 
<br /><br />
<label for="country_id">Country</label>
<br />
<select name="country_id" required>
<option value="">-- choose country --</option>
@foreach ($countries as $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
@endforeach
</select>
 
<br /><br />
<label for="city_id">City</label>
<br />
<select name="city_id">
<option value="">-- choose country first --</option>
</select>
 
<br /><br />
<button type="submit">Save data</button>
</form>
 
</body>
</html>

Now, look at the code of dynamic dependent dropdowns with Livewire below.


Code WITH Livewire

First, we install Livewire. It's just one Composer command:

composer require livewire/livewire

Then, we turn our form into a Livewire component that would be included in the regular Blade.

php artisan make:livewire CompanyCreate

It will generate two files:

  • Livewire Component class: app/Livewire/CompanyCreate.php
  • Livewire Blade file: resources/views/livewire/company-create.blade.php

Then, the main Laravel Blade turns into this, just loading the Livewire component for the form:

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

<html>
<body>
<livewire:company-create />
</body>
</html>

And this is what the Livewire Component looks like.

app/Livewire/CompanyCreate.php

namespace App\Livewire;
 
use App\Models\City;
use App\Models\Country;
use Livewire\Component;
 
class CompanyCreate extends Component
{
public $countries;
public $country;
public $cities = [];
 
public function mount()
{
$this->countries = Country::all();
}
 
public function render()
{
return view('livewire.company-create');
}
 
public function updated($property)
{
if ($property == 'country') {
$this->cities = City::where('country_id', $this->country)->get();
}
}
 
}

This Component class above looks similar to a Laravel Controller, doesn't it?

Quick explanation:

  • Method mount() is like PHP constructor
  • Method render() defines which Blade file to load
  • Method updated() is fired whenever some input field changes the value

Then, Livewire Blade:

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

<div>
<form>
<label for="name">Company name</label>
<br />
<input name="name" required />
 
<br /><br />
<label for="country_id">Country</label>
<br />
<select wire:model.live="country" required>
<option value="">-- choose country --</option>
@foreach ($countries as $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
@endforeach
</select>
 
<br /><br />
<label for="city_id">City</label>
<br />
<select name="city_id">
@forelse($cities as $city)
<option value="{{ $city->id }}">{{ $city->name }}</option>
@empty
<option value="">-- choose country first --</option>
@endforelse
</select>
 
<br /><br />
<button type="submit">Save data</button>
</form>
</div>

It looks similar to a regular Laravel Blade, doesn't it?

As you can see, we have variables like $countries and $cities in the Blade, which are automatically passed from the properties of the Livewire Component class. We don't need to pass them.

Also, that wire:model means binding to the component property $country_id. We'll talk about that in the next lesson.

And that's it. The dynamic behavior works!


Main Points: Purpose of Livewire

With this demonstration, I wanted to show three main points:

  1. Livewire allows you to achieve dynamic pages without JavaScript
  2. Structurally, it looks similar to regular Laravel with PHP and Blade, so back-end developers stay productive in their "comfort zone".
  3. You can code your full page with regular Blade/MVC and use Livewire only for some page parts that you want to be dynamic, like a form in the example above

If you want to try this example yourself, here's a link to the GitHub repository.


In the next lesson, we will talk about submitting the form, which will happen without refreshing the full page.

avatar

slightly off topic but I've found MingleJS which appears to let you use React or Vue in a Livewire app.. will test it out this weekend and report back

avatar
You can use Markdown
avatar

thank you

avatar
You can use Markdown
avatar
You can use Markdown