Laravel 10 Dependent Dropdown Example Tutorial

The main purpose of using dependent dropdowns is to create a dynamic user interface where the available options in a dropdown are updated based on the selection made in a preceding dropdown field. This allows users to select relevant data based on their previous selection, improving the user experience and ensuring data integrity.

Step 1: Install Laravel

This step is not required; however, if you have not created the laravel app, then you may go ahead and execute the below command: 

composer create-project laravel/laravel example-app

Step 2: Create Migration for Table

In this step, we will create migration for countries, states and cities table. So let's run below command to create tables. 

php artisan make:migration create_countries_states_cities_tables

Next, simple update below code to migration file.

database/migrations/create_countries_states_cities_tables.php

<?php
  
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
      
    return new class extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up(): void
        {
            Schema::create('countries', function (Blueprint $table) {
                $table->id();
                $table->string('name');
                $table->timestamps();
            });
      
            Schema::create('states', function (Blueprint $table) {
                $table->id();
                $table->string('name');
                $table->integer('country_id');
                $table->timestamps();
            });
      
            Schema::create('cities', function (Blueprint $table) {
                $table->id();
                $table->string('name');
                $table->integer('state_id'); 
                $table->timestamps();
            });
        }
      
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down(): void
        {
            Schema::dropIfExists('countries');
            Schema::dropIfExists('states');
            Schema::dropIfExists('cities');
        }
    };

Then run migration using below command:

php artisan migrate

Step 3: Create Models

In this step, we will create three models for tables Country.php, State.php and City.php model file.

so, let's run below command to create file and update following code:

php artisan make:model Country
    php artisan make:model State
    php artisan make:model City

app/Models/Country.php

<?php
  
    namespace App\Models;
      
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
      
    class Country extends Model
    {
        use HasFactory;
      
        /**
         * Write code on Method
         *
         * @return response()
         */
        protected $fillable = [
            'name'
        ];
    }

app/Models/State.php

<?php
  
    namespace App\Models;
      
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
      
    class State extends Model
    {
        use HasFactory;
      
        /**
         * Write code on Method
         *
         * @return response()
         */
        protected $fillable = [
            'name', 'country_id'
        ];
    }

app/Models/City.php

<?php
  
  namespace App\Models;
    
  use Illuminate\Database\Eloquent\Factories\HasFactory;
  use Illuminate\Database\Eloquent\Model;
     
  class City extends Model
  {
      use HasFactory;
    
      /**
       * Write code on Method
       *
       * @return response()
       */
      protected $fillable = [
          'name', 'state_id'
      ];
  }

Step 4: Create Route

routes/web.php 

<?php
  
  use Illuminate\Support\Facades\Route;
    
  use App\Http\Controllers\DropdownController;
     
  /*
  |--------------------------------------------------------------------------
  | Web Routes
  |--------------------------------------------------------------------------
  |
  | Here is where you can register web routes for your application. These
  | routes are loaded by the RouteServiceProvider within a group which
  | contains the "web" middleware group. Now create something great!
  |
  */
      
  Route::get('dropdown', [DropdownController::class, 'index']);
  Route::post('api/fetch-states', [DropdownController::class, 'fetchState']);
  Route::post('api/fetch-cities', [DropdownController::class, 'fetchCity']);

Step 5: Create Controller

Now, we have to create new controller as DropdownController with index(), fetchState() and fetchCity() methods. so let's update follow code:

app/Http/Controllers/DropdownController.php

<?php
  
    namespace App\Http\Controllers;
      
    use Illuminate\Http\Request;
    use App\Models\Country;
    use App\Models\State;
    use App\Models\City;
    use Illuminate\View\View;
    use Illuminate\Http\JsonResponse;
      
    class DropdownController extends Controller
    {
        /**
         * Write code on Method
         *
         * @return response()
         */
        public function index(): View
        {
            $data['countries'] = Country::get(["name", "id"]);
            return view('dropdown', $data);
        }
        /**
         * Write code on Method
         *
         * @return response()
         */
        public function fetchState(Request $request): JsonResponse
        {
            $data['states'] = State::where("country_id", $request->country_id)
                                    ->get(["name", "id"]);
      
            return response()->json($data);
        }
        /**
         * Write code on Method
         *
         * @return response()
         */
        public function fetchCity(Request $request): JsonResponse
        {
            $data['cities'] = City::where("state_id", $request->state_id)
                                        ->get(["name", "id"]);
                                          
            return response()->json($data);
        }
    }

Step 6: Create View File

resources/views/dropdown.blade.php 

<!DOCTYPE html>
    <html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="csrf-token" content="content">
        <meta name="csrf-token" content="{{ csrf_token() }}">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <title>Laravel AJAX Dependent Country State City Dropdown Example - webthestuff.com</title>
        <!-- CSS only -->
        <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet">
    </head>
    <body>
        <div class="container mt-4" >
            <div class="row justify-content-center">
                <div class="col-md-8">
                    <div class="alert alert-primary mb-4 text-center">
                       <h4 >Laravel AJAX Dependent Country State City Dropdown Example  webthestuff.com</h4>
                    </div> 
                    <form>
                        <div class="form-group mb-3">
                            <select  id="country-dropdown" class="form-control">
                                <option value="">-- Select Country --</option>
                                @foreach ($countries as $data)
                                <option value="{{$data->id}}">
                                    {{$data->name}}
                                </option>
                                @endforeach
                            </select>
                        </div>
                        <div class="form-group mb-3">
                            <select id="state-dropdown" class="form-control">
                            </select>
                        </div>
                        <div class="form-group">
                            <select id="city-dropdown" class="form-control">
                            </select>
                        </div>
                    </form>
                </div>
            </div>
        </div>
      
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script>
            $(document).ready(function () {
      
                /*------------------------------------------
                --------------------------------------------
                Country Dropdown Change Event
                --------------------------------------------
                --------------------------------------------*/
                $('#country-dropdown').on('change', function () {
                    var idCountry = this.value;
                    $("#state-dropdown").html('');
                    $.ajax({
                        url: "{{url('api/fetch-states')}}",
                        type: "POST",
                        data: {
                            country_id: idCountry,
                            _token: '{{csrf_token()}}'
                        },
                        dataType: 'json',
                        success: function (result) {
                            $('#state-dropdown').html('<option value="">-- Select State --</option>');
                            $.each(result.states, function (key, value) {
                                $("#state-dropdown").append('<option value="' + value
                                    .id + '">' + value.name + '</option>');
                            });
                            $('#city-dropdown').html('<option value="">-- Select City --</option>');
                        }
                    });
                });
      
                /*------------------------------------------
                --------------------------------------------
                State Dropdown Change Event
                --------------------------------------------
                --------------------------------------------*/
                $('#state-dropdown').on('change', function () {
                    var idState = this.value;
                    $("#city-dropdown").html('');
                    $.ajax({
                        url: "{{url('api/fetch-cities')}}",
                        type: "POST",
                        data: {
                            state_id: idState,
                            _token: '{{csrf_token()}}'
                        },
                        dataType: 'json',
                        success: function (res) {
                            $('#city-dropdown').html('<option value="">-- Select City --</option>');
                            $.each(res.cities, function (key, value) {
                                $("#city-dropdown").append('<option value="' + value
                                    .id + '">' + value.name + '</option>');
                            });
                        }
                    });
                });
      
            });
        </script>
    </body>
    </html>

Step 7: Create Seeder

In this step, we will create "CountrySateCitySeeder" file to create dummy records. so let's create seeder and run it. 

Create Seeder file using below command:

php artisan make:seeder CountrySateCitySeeder

database/seeders/CountrySateCitySeeder.php

<?php
  
    namespace Database\Seeders;
      
    use Illuminate\Database\Console\Seeds\WithoutModelEvents;
    use Illuminate\Database\Seeder;
    use App\Models\Country;
    use App\Models\State;
    use App\Models\City;
      
    class CountrySateCitySeeder extends Seeder
    {
        /**
         * Run the database seeds.
         *
         * @return void
         */
        public function run(): void
        {
            /*------------------------------------------
            --------------------------------------------
            US Country Data
            --------------------------------------------
            --------------------------------------------*/
            $country = Country::create(['name' => 'United State']);
      
            $state = State::create(['country_id' => $country->id, 'name' => 'Florida']);
      
            City::create(['state_id' => $state->id, 'name' => 'Miami']);
            City::create(['state_id' => $state->id, 'name' => 'Tampa']);
      
            /*------------------------------------------
            --------------------------------------------
            India Country Data
            --------------------------------------------
            --------------------------------------------*/
            $country = Country::create(['name' => 'India']);
      
            $state = State::create(['country_id' => $country->id, 'name' => 'Gujarat']);
      
            City::create(['state_id' => $state->id, 'name' => 'Rajkot']);
            City::create(['state_id' => $state->id, 'name' => 'Surat']);
      
        }
    }

Next, run seeder with below command:

php artisan db:seed --class=CountrySateCitySeeder

Run Laravel App:

php artisan serve

Now, Go to web browser, type  URL and view output:

http://localhost:8000/dropdown