Dependent Dropdown with Laravel and VueJS

Hi, today I’m going to show how to make dependent dropdown with Laravel 6 and VueJS. Let’s see the preview first:

Dependent Dropdown with Laravel and VueJS

We’ve seen the output. Now let’s start:

Table of Contents

  1. Install Laravel and NPM Dependencies
  2. Create Country and State Table
  3. Create Country and State Model
  4. Create API Controller
  5. Define API Routes
  6. Create Vue App
  7. Create Vue Component

Step 1 : Install Laravel and NPM Dependencies

Each Laravel project needs this thing. That’s why I have written an article on this topic. Please see this part from here: Install Laravel and Basic Configurations.

After installing Laravel, run this command to install frontend dependencies:

npm install

We need to install vue-axios. vue-axios will be used for calling Laravel API routes. Let’s install these:

npm install vue-axios --save

After installing all dependencies run this command:

npm run watch

This npm run watch command will listen for file changes and will compile assets instantly.

Step 2 : Create Country and State Table

Let’s create a migration file to create countries and states table. Run this artisan command to create a migration file:

php artisan make:migration create_countries_states_table

Open the newly created migration file from database/migrations folder and paste this code:

create_countries_states_table.php
<?php

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

class CreateCountriesStatesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('countries', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->timestamps();
        });

        Schema::create('states', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->integer('country_id');
            $table->string('name');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('countries');
        Schema::dropIfExists('states');
    }
}

After doing this, migrate the migration file:

php artisan migrate

Step 3 : Create Country and State Model

Let’s create two models called Country and State to do the database query faster.

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

Step 4 : Create API Controller

We are going to create an API controller named CountryStateController. We will call this controller from VueJS using Axios. Let’s create the controller:

php artisan make:controller API\CountryStateController

Now open the controller from app/Http/Controllers. I’ve written two methods to get data from the database. One function to retrieve countries and another to get states.

CountryStateController.php
<?php

namespace App\Http\Controllers\API;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Country;
use App\State;

class CountryStateController extends Controller
{
    /**
     * Retrieve countries data
     *
     * @return void
     */
    public function getCountries()
    {
        $data = Country::get();

        return response()->json($data);
    }

    /**
     * Retrieve states data
     *
     */
    public function getStates(Request $request)
    {
        $data = State::where('country_id', $request->country_id)->get();

        return response()->json($data);
    }
}

Step 5 : Define API Routes

We are at the end of the Laravel part. Open api.php from routes folder and create two API routes like these:

api.php
Route::get('get_countries', 'API\CountryStateController@getCountries');
Route::get('get_states', 'API\CountryStateController@getStates');

Step 6 : Create Vue App

To declaratively render data to the DOM using Vue.js we need to declare Vue app. Navigate to resources>views folder and create a file called app.blade.php. Then paste this code:

app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta name="csrf-token" value="{{ csrf_token() }}"/>
    <title>Dependent Dropdown with Laravel and VueJS - MyNotePaper</title>
    <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet" type="text/css">
    <link href="{{ mix('css/app.css') }}" type="text/css" rel="stylesheet"/>
</head>
<body>
<div id="app">
    <dropdown-component></dropdown-component>
</div>
<script src="{{ mix('js/app.js') }}" type="text/javascript"></script>
</body>
</html>

Step 7 : Create Vue Component

Go to resources/js/components folder and make a filed called DropdownComponent.vue. Then open the vue file and paste this code:

DropdownComponent.vue
<template>
    <div class="container">
        <div class="text-center" style="margin: 20px 0px 20px 0px;">
            <a href="https://shouts.dev/" target="_blank"><img src="https://i.imgur.com/hHZjfUq.png"></a><br>
            <span class="text-secondary">Dependent Dropdown with Laravel and VueJS</span>
        </div>
        <div class="row justify-content-center" style="margin: 20px 0px 20px 0px;">
            <div class="col-md-8">
                <div class="card">

                    <div class="card-body">
                        <div class="form-group">
                            <label>Select Country:</label>
                            <select class='form-control' v-model='country' @change='getStates()'>
                                <option value='0' >Select Country</option>
                                <option v-for='data in countries' :value='data.id'>{{ data.name }}</option>
                            </select>
                        </div>

                        <div class="form-group">
                            <label>Select State:</label>
                            <select class='form-control' v-model='state'>
                                <option value='0' >Select State</option>
                                <option v-for='data in states' :value='data.id'>{{ data.name }}</option>
                            </select>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script>
    export default {
        data(){
            return {
                country: 0,
                countries: [],
                state: 0,
                states: []
            }
        },
        methods:{
            getCountries: function(){
                axios.get('/api/get_countries')
                    .then(function (response) {
                        this.countries = response.data;
                    }.bind(this));

            },
            getStates: function() {
                axios.get('/api/get_states',{
                    params: {
                        country_id: this.country
                    }
                }).then(function(response){
                    this.states = response.data;
                }.bind(this));
            }
        },
        created: function(){
            this.getCountries()
        }
    }
</script>

We have to include DropdownComponent in app.js. Open app.js from resources/js directory and include the DropdownComponent like this:

app.js
require('./bootstrap');

window.Vue = require('vue');

Vue.component('dropdown-component', require('./components/DropdownComponent.vue').default);

const app = new Vue({
    el: '#app',
});

If you didn’t run npm run watch from the beginning of the article, now run npm run watch or npm run dev to see the output of the project.

The tutorial is over. You can download this project from GitHub. Thank you.