Md Obydullah Follow I'm Md Obydullah. I build open-source projects and write about Laravel, Linux server, modern JavaScript and web development.

Dependent Dropdown with Laravel and VueJS

Published on September 3, 2019 3 min read

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\[email protected]');
Route::get('get_states', 'API\[email protected]');

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://www.mynotepaper.com/" 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. 🙂

You're welcome to suggest any article to write!

Md Obydullah Follow I'm Md Obydullah. I build open-source projects and write about Laravel, Linux server, modern JavaScript and web development.

2 Replies to “Dependent Dropdown with Laravel and VueJS”

  1. Mr. Obydul,

    Can you help in respect of npm run watch, this gives error and make me disheart because there is no documentation to get help to resolve it.

    Today i just installed new project, install npm install vue-axios –save and then run npm run watch it giving errors detail is as under:

    Factory.js:138:29)
    at process.nextTick (F:\xampp\htdocs\guestbook\node_modules\webpack\lib\Norm
    alModuleFactory.js:346:9)
    at process._tickCallback (internal/process/next_tick.js:61:11)
    Emitted ‘error’ event at:
    at errorOrDestroy (internal/streams/destroy.js:107:12)
    at onwriteError (_stream_writable.js:430:5)
    at onwrite (_stream_writable.js:461:5)
    at doWrite (_stream_writable.js:411:11)
    at writeOrBuffer (_stream_writable.js:399:5)
    [… lines matching original stack trace …]
    at process._tickCallback (internal/process/next_tick.js:61:11)
    npm ERR! code ELIFECYCLE
    npm ERR! errno 1
    npm ERR! @ development: `cross-env NODE_ENV=development node_modules/webpack/bin
    /webpack.js –progress –hide-modules –config=node_modules/laravel-mix/setup/we
    bpack.config.js “–watch”`

    However with npm run dev Build is successful.

Leave a Reply

Your email address will not be published. Required fields are marked *