How To Create Dependent Dropdown with Vue.js and Laravel 10

Creating a dependent dropdown has always been an effective way for me to enhance user experience in my web applications. By combining the power of Vue.js, my go-to JavaScript framework, with Laravel 10, a robust backend framework, I can easily achieve dynamic and interactive forms. In this tutorial, I will walk you through the process of creating a dependent dropdown using Vue.js and Laravel 10.

Throughout this tutorial, I will guide you step-by-step in setting up the project, creating the necessary Vue components, and integrating them with Laravel's backend API. Together, we will explore how to retrieve data from the server, handle events, and dynamically update dropdown options based on user interactions.

By the end of this tutorial, you will have a solid understanding of how Vue.js and Laravel 10 work hand-in-hand to create a seamless dependent dropdown feature. So let's dive in and empower our web applications with a user-friendly and responsive form experience.

Here's an example of how to create a dependent dropdown with Vue.js and Laravel 10:

Step 1: Set up Laravel 10 Project

Install Laravel 10 by running the following command in your terminal.

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

Navigate to your project directory.

cd project-name

 

Step 2: Set up Database
  1. Configure your database credentials in the .env file.
  2. Create three tables in your database: countries, states, and cities. Each table should have an id (primary key) and name column.
  3. Seed the tables with relevant data.

To create the migrations for the countries, states, and cities tables in Laravel, follow these steps:

Run the following command to create a migration for the countries table.

php artisan make:migration create_countries_table --create=countries

This will generate a new migration file in the database/migrations directory. Open the generated file and update it with the following code.

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCountriesTable extends Migration
{
    public function up()
    {
        Schema::create('countries', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('countries');
    }
}

Repeat the above steps to create migrations for the states and cities tables.

For the states table.

php artisan make:migration create_states_table --create=states

Update the generated migration file with the following code.

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateStatesTable extends Migration
{
    public function up()
    {
        Schema::create('states', function (Blueprint $table) {
            $table->id();
            $table->foreignId('country_id')->constrained('countries')->onDelete('cascade');
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('states');
    }
}

For the cities table.

php artisan make:migration create_cities_table --create=cities

Update the generated migration file with the following code.

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateCitiesTable extends Migration
{
    public function up()
    {
        Schema::create('cities', function (Blueprint $table) {
            $table->id();
            $table->foreignId('state_id')->constrained('states')->onDelete('cascade');
            $table->string('name');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('cities');
    }
}

Save the migration files and run the migrations again.

php artisan migrate

Now, the countries, states, and cities tables will be created in your database with the respective columns.

 

Step 3: Set up Routes and Controllers

Create routes in routes/web.php for retrieving the data for dropdowns.

use App\Http\Controllers\DropdownController;

Route::get('/countries', [DropdownController::class, 'getCountries']);
Route::get('/states/{countryId}', [DropdownController::class, 'getStates']);
Route::get('/cities/{stateId}', [DropdownController::class, 'getCities']);

Create a controller named DropdownController using the following command.

php artisan make:controller DropdownController

Open the generated DropdownController.php file and update it with the following code.

namespace App\Http\Controllers;

use App\Models\Country;
use App\Models\State;
use App\Models\City;

class DropdownController extends Controller
{
    public function getCountries()
    {
        $countries = Country::all();
        return response()->json($countries);
    }

    public function getStates($countryId)
    {
        $states = State::where('country_id', $countryId)->get();
        return response()->json($states);
    }

    public function getCities($stateId)
    {
        $cities = City::where('state_id', $stateId)->get();
        return response()->json($cities);
    }
}

 

Step 4: Set up Vue.js Components
  • Create a new Vue component called Dropdown.vue in the resources/js/components directory.
  • Update the Dropdown.vue component with the following code.
<template>
    <div>
        <select v-model="selectedCountry" @change="getStates">
            <option value="">Select Country</option>
            <option v-for="country in countries" :key="country.id" :value="country.id">{{ country.name }}</option>
        </select>

        <select v-model="selectedState" @change="getCities">
            <option value="">Select State</option>
            <option v-for="state in states" :key="state.id" :value="state.id">{{ state.name }}</option>
        </select>

        <select v-model="selectedCity">
            <option value="">Select City</option>
            <option v-for="city in cities" :key="city.id" :value="city.id">{{ city.name }}</option>
        </select>
    </div>
</template>

<script>
export default {
    data() {
        return {
            countries: [],
            states: [],
            cities: [],
            selectedCountry: '',
            selectedState: '',
            selectedCity: '',
        };
    },
    mounted() {
        this.getCountries();
    },
    methods: {
        getCountries() {
            axios.get('/countries')
                .then(response => {
                    this.countries = response.data;
                })
                .catch(error => {
                    console.log(error);
                });
        },
        getStates() {
            axios.get('/states/' + this.selectedCountry)
                .then(response => {
                    this.states = response.data;
                    this.selectedState = '';
                    this.cities = [];
                    this.selectedCity = '';
                })
                .catch(error => {
                    console.log(error);
                });
        },
        getCities() {
            axios.get('/cities/' + this.selectedState)
                .then(response => {
                    this.cities = response.data;
                    this.selectedCity = '';
                })
                .catch(error => {
                    console.log(error);
                });
        },
    },
};
</script>

 

Step 5: Update Blade Template

Open the resources/views/welcome.blade.php file and update it with the following code.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>How To Create Dependent Dropdown with Vue.js and Laravel 10 - Techsolutionstuff</title>

    <link href="{{ mix('css/app.css') }}" rel="stylesheet">
</head>
<body>
    <div id="app">
        <dropdown></dropdown>
    </div>

    <script src="{{ mix('js/app.js') }}"></script>
</body>
</html>

 

Step 6: Compile Assets

Run the following command to compile the assets.

npm install && npm run dev

 

Step 7: Start the Laravel Development Server

Start the Laravel development server by running the following command in your terminal.

php artisan serve

Now, when you visit http://localhost:8000, you should see the dependent dropdowns for country, state, and city. Selecting a country will load the relevant states, and selecting a state will load the relevant cities.

Make sure to check if the database configuration, table names, and model names are consistent with your application. You may need to adjust the code accordingly based on your specific setup.

Additionally, you may need to install Axios if it is not already included in your project by running npm install axios.

 


You might also like: 

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS