Dynamic drop down with laravel and jquery

"Displaying dynamic options in the drop down based on value selected in another drop down" is one of the most commonly used functionality in form handling. Sometime, we want to display a list of products based on category, a list of subjects based on faculty, a list of cities based on country and many more. This might look quite difficult but we can achieve easily with few lines of java script and laravel code.

We will take and example of category and products. This is quite easy to understand. Here, one category can have multiple products and one product is associated with only one category.

Part I ( Back End)

Let’s start with database schema for category and product,

We will use artisan commands to create schema. Just run following artisan command,

php artisan make:migration create_categories_table --create=categories

Now, make category schema like following.

<?php

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

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

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

Again run following artisan command,

php artisan make:migration create_products_table –create=products

Now, make product schema like following.

<?php 

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

class CreateProductsTable extends Migration
{
    /** * Run the migrations. * * @return void */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->increments('id');
            $table->integer('category_id')->unsigned();
            $table->string('name');
            $table->timestamps();
            $table->foreign('category_id')->references('id')->on('categories');
        });
    }

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

Now, we will create model for each of these database table and then we will define one to

many relationship,

Artisan Command:

php artisan make:model Category
Category Model:
<?php 

namespace App;

use Illuminate\Database\Eloquent\Model;

class Category extends Model
{
    public function products()
    {
        return $this->hasMany('App\Product');
    }
}

Artisan Command:

php artisan make:model Product
Product Model:
<?php 

namespace App;

use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    public function category()
    {
        return $this->belongsTo('App\Category');
    }
}

Here, one category can have multiple products and one product is associated with only one category.

We have to display all products by default. After selecting certain category, we need to display products associated with the category only.

We can add data to the database directly but proper way is the use of seeder for this thing. Now, Lets add some categories and products to the database using seeder.

We will use following artisan command to create database seeder,

php artisan make:seeder CategoryProductSeeder

Now, add some products and categories.

<?php 

use Illuminate\Database\Seeder;
use App\Product;
use App\Category;

class CategoryProductSeeder extends Seeder
{
    /** * Run the database seeds. * * @return void */
    public function run()
    {
        $category = new Category();
        $category->name = "Food";
        $category->save();
        $product = new Product();
        $product->category_id = $category->id;
        $product->name = "Rice";
        $product->save();
        $product = new Product();
        $product->category_id = $category->id;
        $product->name = "Meat";
        $product->save();
        $product = new Product();
        $product->category_id = $category->id;
        $product->name = "Apple";
        $product->save();
        $category = new Category();
        $category->name = "Sport";
        $category->save();
        $product = new Product();
        $product->category_id = $category->id;
        $product->name = "Football";
        $product->save();
        $product = new Product();
        $product->category_id = $category->id;
        $product->name = "Cricket";
        $product->save();
        $category = new Category();
        $category->name = "Instruments";
        $category->save();
        $product = new Product();
        $product->category_id = $category->id;
        $product->name = "Guitar";
        $product->save();
        $product = new Product();
        $product->category_id = $category->id;
        $product->name = "Piano";
        $product->save();
    }
}

Lets register this seeder to Database Seeder,

$this->call(CategoryProductSeeder::class);

Now, run following artisan commands.

php artisan migrate
php artisan db:seed

Lets add some code to our controller,

<?php 

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Category;
use App\Product;

class DropDownController extends Controller
{
    public function index()
    {
        $categories = Category::all();
        $products = Product::all();
        return view('dropdown.dropdown', compact('categories', 'products'));
    }

    public function getProducts($id)
    {
        if ($id != 0) {
            $products = Category::find($id)->products()->select('id', 'name')->get()->toArray();
        } else {
            $products = Product::all()->toArray();
        }
        return response()->json($products);
    }
}

In order to return all products and categories, we will use index method and to return products of a category we will use the second function.

In order to register these controller functions to the route, we need to add following lines of code to our route file web.php

Route::get('/dropdown','DropDownController@index'); 
Route::get('category/{id}/products', 'DropDownController@getProducts');

Part II ( Front End )

Now, we will see what our html code should be,

HTML
<div class="container">
    <div class="row">
        <div class="col-md-12">
            <div class="col-md-6"><label>Category</label> <select class="form-control" name="category">
                    <option value="0">Please Select Category</option>
                    @foreach($categories as $category)
                    <option value="{{$category->id}}">{{$category->name}}</option>
                    @endforeach </select></div>
            <div class="col-md-6"><label>Products</label> <select class="form-control" name="product">
                    <option value="0">Please Select Product</option>
                    @foreach($products as $product)
                    <option value="{{$product->id}}">{{$product->name}}</option>
                    @endforeach </select></div>
        </div>
    </div>
</div>

Now, we will use Ajax call to add products dynamically based on category.

Javascript

<script> 
    jQuery(document).ready(function ($) {
        $('select[name=category]').on('change', function () {
            var selected = $(this).find(":selected").attr('value');
            $.ajax({
                url: base_url + '/category/' + selected + '/products/',
                type: 'GET',
                dataType: 'json',
            }).done(function (data) {
                var select = $('select[name=product]');
                select.empty();
                select.append('<option value="0" >Please Select Product</option>');
                $.each(data, function (key, value) {
                    select.append('<option value=' + key.id + '>' + value.name + '</option>');
                });
                console.log("success");
            })
        });
    }); 
</script>

Here, we can send a get request and then on successful call json array of products data will be received.

And here we finished. Now, You can just use it and enjoy.


share :

Sagar Gautam

A Computer Engineer from Nepal.


Leave your Feedback