If you are using Laravel for your web development, then you may have come across a requirement to auto-populate a dropdown with the database data.
For example, you may have a form with a country field and you want to auto-populate the states field on the form based on the country selected by the user.
In this article, I show how to auto-populate a dropdown using Livewire in Laravel 9.
I am hoping you have already installed Livewire on your project if not then you can view my previous post for installation.

Contents
- Add Database configuration
- Create Tables
- Create Models
- Create Controller
- Create Route
- Create Livewire Component
- Create View
- Output
- Conclusion
1. Add Database configuration
Open .env file to update the database connection.
Specify the host, database name, username, and password.
DB_CONNECTION=mysql DB_HOST=127.0.0.1 DB_PORT=3306 DB_DATABASE=tutorial DB_USERNAME=root DB_PASSWORD=
2. Create Tables
Create countries, states, and cities tables using migration.
I am adding foreign key on states and cities tables.
statestable is linked tocountriestable, andcitiestable is linked tostatestable.
You can learn foreign key implementation in detail from here.
- Create
Countriestable –
php artisan make:migration create_countries_table
- Now, navigate to
database/migrations/folder from the project root. - Find a PHP file that ends with
create_countries_tableand open it. - Define the table structure in the
up()method.
public function up()
{
Schema::create('countries', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->timestamps();
});
}
- Create
Statestable –
php artisan make:migration create_states_table
- Similarly, find a PHP file that ends with
create_states_tableindatabase/migrations/folder and open it. - Define the table structure in the
up()method. - Adding foreign key to
country_idfield.
public function up()
{
Schema::create('states', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('country_id');
$table->string('name');
$table->timestamps();
$table->foreign('country_id')
->references('id')->on('countries')->onDelete('cascade');
});
}
- Create
Citiestable –
php artisan make:migration create_cities_table
- Similarly, find a PHP file that ends with
create_cities_tableindatabase/migrations/folder and open it. - Define the table structure in the
up()method. - Adding foreign key to
states_idfield.
public function up()
{
Schema::create('cities', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('state_id');
$table->string('name');
$table->foreign('state_id')
->references('id')->on('states')->onDelete('cascade');
$table->timestamps();
});
}
- Run the migration to create tables –
php artisan migrate
3. Create Models
Create Countries, States, and Cities models.
- Create
CountriesModel.
php artisan make:model Countries
- Open
app/Models/Countries.phpfile. - Specify mass assignable Model attributes –
nameusing the$fillableproperty.
Completed Code
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Countries extends Model
{
use HasFactory;
protected $fillable = [
'name'
];
}
- Create
StatesModel.
php artisan make:model States
- Open
app/Models/States.phpfile. - Specify mass assignable Model attributes –
country_id, andnameusing the$fillableproperty.
Completed Code
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class States extends Model
{
use HasFactory;
protected $fillable = [
'country_id','name'
];
}
- Create
CitiesModel.
php artisan make:model Cities
- Open
app/Models/Cities.phpfile. - Specify mass assignable Model attributes –
state_id, andnameusing the$fillableproperty.
Completed Code
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Cities extends Model
{
use HasFactory;
protected $fillable = [
'state_id','name'
];
}
4. Create Controller
- Create
PagesControllercontroller.
php artisan make:controller PagesController
- Open
app\Http\Controllers\PagesController.phpfile. - Create 1 method –
- index() – Load
indexview.
- index() – Load
Completed Code
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class PagesController extends Controller
{
public function index(){
return view('index');
}
}
5. Create Route
- Open
routes/web.phpfile. - Define 1 route –
- / – Load index view.
<?php
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\PagesController;
Route::get('/', [PagesController::class, 'index']);
6. Create Livewire Component
Create autopopulate-dropdown component –
php artisan make:livewire autopopulate-dropdown
This will create 2 files –
- app/Http/Livewire/AutopopulateDropdown.php
- resources/views/livewire/autopopulate-dropdown.blade.php
AutopopulateDropdown.php
- Include Countries, States, and Cities Models.
- In the component class create 6 property variables –
- $countries – Store countries list.
- $states – Store selected country states list.
- $cities – Store selected state cities list.
- $country_id – Use for data binding in country dropdown
- $state_id – Use for data binding in state dropdown.
- $city_id – Use for data binding in city dropdown.
- Create 3 methods –
- mount() – It is inbuilt method to load initial data. Fetch all
countriestable records and assign to$this->countries. - getCountryStates() – This method is called when
changeevent trigger in the country dropdown. Fetch records from thestatestable wherecountry_idis equals to$this->country_id. Assign fetched records to$this->states.
- mount() – It is inbuilt method to load initial data. Fetch all
Remove data of $this->cities and assign 0 to $this->state_id and $this->city_id.
-
- getStateCities() – This method is called when
changeevent trigger in the state dropdown. Fetch records from thecitiestable wherestate_idis equals to$this->state_id. Assign fetched records to$this->cities.
- getStateCities() – This method is called when
Assign 0 to $this->city_id.
Completed Code
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\Countries;
use App\Models\States;
use App\Models\Cities;
class AutopopulateDropdown extends Component
{
public $countries, $states, $cities;
public $country_id = 0;
public $state_id = 0;
public $city_id = 0;
public function mount(){
$this->countries = Countries::orderby('name','asc')
->select('*')
->get();
}
// Fetch states of a country
public function getCountryStates(){
$this->states = States::orderby('name','asc')
->select('*')
->where('country_id',$this->country_id)
->get();
// Reset values
unset($this->cities);
$this->state_id = 0;
$this->city_id = 0;
}
// Fetch cities of a state
public function getStateCities(){
$this->cities = Cities::orderby('name','asc')
->select('*')
->where('state_id',$this->state_id)
->get();
// Reset value
$this->city_id = 0;
}
public function render(){
return view('livewire.autopopulate-dropdown');
}
}
autopopulate-dropdown.blade.php
- Create 3
<select >elements –- 1st is for country selection. Add country list by looping on
$countries. Addingcountry_idmodel andchangeevent that callsgetCountryStates. - 2nd is for state selection. Add state list if
$statesis not empty. Addingstate_idmodel andchangeevent that callsgetStateCities. - 3rd is for city selection. Add city list if
$citiesis not empty. Addingcity_idmodel.
- 1st is for country selection. Add country list by looping on
Completed Code
<div>
<style type="text/css">
table select{
padding: 5px;
min-width: 200px;
}
</style>
<table>
<tr>
<td>Country</td>
<td>
<select wire:model="country_id" wire:change="getCountryStates">
<option value="0">-- Select Country --</option>
@foreach($countries as $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
@endforeach
</select>
</td>
</tr>
<tr>
<td>State</td>
<td>
<select wire:model="state_id" wire:change="getStateCities">
<option value="0">-- Select State --</option>
@if(!empty($states))
@foreach($states as $state)
<option value="{{ $state->id }}">{{ $state->name }}</option>
@endforeach
@endif
</select>
</td>
</tr>
<tr>
<td>City</td>
<td>
<select wire:model="city_id">
<option value="0">-- Select City --</option>
@if(!empty($cities))
@foreach($cities as $city)
<option value="{{ $city->id }}">{{ $city->name }}</option>
@endforeach
@endif
</select>
</td>
</tr>
</table>
</div>
7. Create View
Create index.blade.php file in resources/views/ folder.
Add autopopulate-dropdown component and livewire style and script.
Completed Code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>How to Auto populate dropdown using Livewire - Laravel</title>
@livewireStyles
</head>
<body>
<livewire:autopopulate-dropdown />
@livewireScripts
</body>
</html>
8. Output
9. Conclusion
Following the tutorial, you can control multiple dropdown data based on parent dropdown selection using Livewire.
If you found this tutorial helpful then don't forget to share.