Search

Laravel 8 Dependent Country State City Dropdown using Ajax

post-title

Dependent dropdowns are interconnected by its parent values. Changing values in parent dropdown will change options into child dropdown. For example, Change in countries dropdown will change state dropdown options with only selected countries states only. This can be implemented in relational dropdowns.

In this article, we will implement dependent dropdowns for countries states and cities. We use Ajax method to fetch child dropdown options. This way, we can provide user smoother experience and form values remain filled.

We will go through step by step from the scratch. These are the steps we will follow to create dependent dropdowns.

  • Step 1: Create Laravel application
  • Step 2: Database configuration
  • Step 3: Dump data into database
  • Step 4: Create controller class
  • Step 5: Create routes
  • Step 6: Create blade file
  • Step 7: Test dropdowns

So let's get started from creating new Laravel application.

Step 1: Create Laravel application

In the first step, we will create new Laravel project using composer command into Terminal. Open Terminal and run below command into it.

composer create-project laravel/laravel dropdown --prefer-dist

This will create fresh Laravel project at the directory. After the project is created, change Terminal directory to project root.

cd dropdown

Step 2: Database configuration

Now open the project into your favourite IDE. Setup database credentials into .env file from root directory.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dropdown
DB_USERNAME=root
DB_PASSWORD=secret

Step 3: Dump data into database

To test application, we need countries, states and city data. I have downloaded MySQL data from GitHub. You will need to import countries.sql, states.sql and cities.sql file into your database from this repository. These files will create each table from the each file.

After importing data from the GitHub, now we have three tables, countries, states and cities with parent table's id into child table. For example, states table will have country_id and cities table will have state_id.

Step 4: Create controller class

We will need controller which will serve blade file and receive Ajax request from view and send it to database server. So, create controller class using Artisan command.

php artisan make:controller DropdownController

This will create DropdownController class at app/Http/Controllers/DropdownController.php file. We will create one method for view and two methods for getting states data and cities data. So open controller class and add below methods.

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class DropdownController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function view()
    {
        $countries = \DB::table('countries')
            ->get();
        
        return view('dropdown', compact('countries'));
    }

    /**
     * return states list.
     *
     * @return json
     */
    public function getStates(Request $request)
    {
        $states = \DB::table('states')
            ->where('country_id', $request->country_id)
            ->get();
        
        if (count($states) > 0) {
            return response()->json($states);
        }
    }

    /**
     * return cities list
     *
     * @return json
     */
    public function getCities(Request $request)
    {
        $cities = \DB::table('cities')
            ->where('state_id', $request->state_id)
            ->get();
        
        if (count($cities) > 0) {
            return response()->json($cities);
        }
    }
}

Note: In this controller, we have used DB facade to communicate with MySQL server to make tutorial simple and easy. To may want to use Model class to get data from database server. For that, you need to create each model for table.

Step 5: Create routes

After we have created controller class, we also need routes which will handle controller methods. Laravel's all rotues are located at routes directory. Open routes/web.php file and add three route into it.

<?php

use Illuminate\Support\Facades\Route;
use App\Http\Controllers\DropdownController;

Route::get('dropdown', [DropdownController::class, 'view'])->name('dropdownView');
Route::get('get-states', [DropdownController::class, 'getStates'])->name('getStates');
Route::get('get-cities', [DropdownController::class, 'getCities'])->name('getCities');

Step 6: Create blade file

In the last step of coding, we need to create blade file which will show dropdown lists. We will also add Ajax request when user select or changes dropdown option.

Laravel's all blade views are located at resources/views directory. Create dropdown.blade.php file and create dropdown HTML code.

<!DOCTYPE html>
<html>
<head>
    <title>Dependent dropdown example</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.2/dist/js/bootstrap.bundle.min.js"></script>
</head>
<body>
    <div class="m-5 w-50">
        <h1 class="lead">Dependent dropdown example</h1>
        <div class="mb-3">
            <select class="form-select form-select-lg mb-3" id="country">
                <option selected disabled>Select country</option>
                @foreach ($countries as $country)
                <option value="{{ $country->id }}">{{ $country->name }}</option>
                @endforeach
            </select>
        </div>
        <div class="mb-3">
            <select class="form-select form-select-lg mb-3" id="state"></select>
        </div>
        <div class="mb-3">
            <select class="form-select form-select-lg mb-3" id="city"></select>
        </div>
    </div>
    <script type="text/javascript">
        $(document).ready(function () {
            $('#country').on('change', function () {
                var countryId = this.value;
                $('#state').html('');
                $.ajax({
                    url: '{{ route('getStates') }}?country_id='+countryId,
                    type: 'get',
                    success: function (res) {
                        $('#state').html('<option value="">Select State</option>');
                        $.each(res, function (key, value) {
                            $('#state').append('<option value="' + value
                                .id + '">' + value.name + '</option>');
                        });
                        $('#city').html('<option value="">Select City</option>');
                    }
                });
            });
            $('#state').on('change', function () {
                var stateId = this.value;
                $('#city').html('');
                $.ajax({
                    url: '{{ route('getCities') }}?state_id='+stateId,
                    type: 'get',
                    success: function (res) {
                        $('#city').html('<option value="">Select City</option>');
                        $.each(res, function (key, value) {
                            $('#city').append('<option value="' + value
                                .id + '">' + value.name + '</option>');
                        });
                    }
                });
            });
        });
    </script>
</body>
</html>

On the above HTML code, we create Ajax request when user select or change country or state and send json response. In the success Ajax request, we loop through json and append options html in select dropdown.

Step 7: Test dropdowns

Now our coding part is complete, We need to test application. First run the Laravel server using following Artisan command.

php artisan serve

In your browser, go to http://localhost:8000/dropdown and try co select country and state dropdown. You will see child dropdown will get all child data into dropdown.

Conclusion

In this tutorial, we learned, Laravel setup and create Ajax request which will return all child data from parent id. I hope you enjoyed the tutorial and it will help in your development.