You are currently viewing Laravel Livewire3 Dependent Dropdown Tutorial
Dependent Dropdown using Laravel Livewire v3

Laravel Livewire3 Dependent Dropdown Tutorial

Welcome to our tutorial on “Laravel Livewire3 Dependent Dropdown .” In this tutorial , we’ll explore how to create dynamic dependent dropdown using Laravel Livewire v3. Dependent dropdowns are a powerful tool for improving user experience and data selection in web applications. Follow along as we dive into this practical tutorial, equipping you with the skills to build dependent dropdown.

Install Laravel

First we wiill install Laravel .Use the below command to install Laravel

laravel new dependent-dropdown

Install Livewire v3

Now lets install Livewire, Livewire 3 stable version has been just released so use the below command to install Livewire v3.

composer require livewire/livewire

Create a template Layout

Now enter the below command to create a template layout for our app.

php artisan livewire:layout

The above command will generate a file called app.blade.php file inside resources/layouts/views/components folder. Add tailwind css cdn after the <title> tag.

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
    <head>
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">

        <title>{{ $title ?? 'Page Title' }}</title>
        <script src="https://cdn.tailwindcss.com"></script>

    </head>
    <body>
        {{ $slot }}
    </body>
</html>

Creating Database

Now we need to create a database for our app. So open phpMyAdmin and create a database called dependent_dropdown

Now open .env file in our App and add the database name inside it.

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=dependent_dropdown
DB_USERNAME=root
DB_PASSWORD=

Creating Models & Migrating Databases

Now we will create three Models & migrations for our Dependent Dropdown App. First Category, second is Subcategory & third is Product. Now open your terminal & enter below commands one bye one :

php artisan make:model Category -m

The above command will create Category model and categories migration file

Open categories migration file & add the below code :

$table->id();
$table->string('name');
$table->timestamps();

Now enter below code into your terminal to migrate the database

php artisan migrate

Now we will create Subcategory model, open your terminal and enter below code to create Subcategory Model with subcategories migration file.

php artisan make:model Subcategory -m

Now open subcategories migration file & enter below code inside it

  $table->id();
   $table->string('name');
   $table->foreignId('category_id')->constrained('categories');
   $table->timestamps();

We have added ‘category _id’ as a foreign key inside the subcategories table. Now to migrate the database enter below command in your terminal.

php artisan migrate

Now we will create Product model, open your terminal and enter below code to create Product Model with products migration file.

php artisan make:model Product -m

Now open products migration file & add below code inside it.

  $table->id();
  $table->string('name');
  $table->foreignId('subcategory_id')->constrained('subcategories');
  $table->timestamps();

We have added ‘subcategory_id’ as a foreign key inside the subcategories table. Now to migrate the database enter below command in your terminal.

php artisan migrate

Now open phpMyAdmin & check your database. You will see that three  tables categories, subcategories & products are created.

Adding Fillable Properties & relationships

Now we need to add fillable properties & define relationships inside both the models. First open Category Model and enter below code inside it.

 protected $fillable = ['name'];
 public function subcategories()
 {
    return $this->hasMany(Subcategory::class, 'category_id');
  }

Now open Subcategory Model and enter below code inside it :

 protected $fillable = ['category_id', 'name'];
    public function category()
    {
        return $this->belongsTo(Category::class, 'category_id');
    }

Now open Product Model & add below code inside it.

protected $fillable = ['name', 'subcategory_id'];
  public function subcategory()
    {
      return $this->belongsTo(Subcategory::class);
  }

Creating Livewire Component

Now we need to create Livewire component for our app. Open your terminal and enter below code to create Livewire Component :

php artisan make:livewire CategorySubcategory

The above command will create two files : CategorySubcategory.php component inside app/Livewire folder & category-subcategory.blade.php file inside resources/views/livewire folder.

LIVEWIRE 3 CRUD TUTORIAL USING BOOTSTRAP 5

Now open CategorySubcategory.php file and add below code inside it, before render() method:

public $categories;
    #[Rule('required|min:3')]
    public $name;
    #[Rule('required')]
    public $category;
    #[Rule('required')]
    public $subcategory;
    public $subcategories = [];
    public function mount()
    {
        $this->categories = Category::all();
        $this->subcategories = collect();
    }
    public function updatedCategory($value)
    {
        $this->subcategories = Subcategory::where('category_id', $value)->get();
    }

Do not forget to import Category & Subcategory Models & Rule.

use App\Models\Category;
use App\Models\Subcategory;
use Livewire\Attributes\Rule;

Adding view

Now open category-subcategory.blade.php file and add below code inside it :

<div>
    <div class="min-h-screen flex items-center justify-center">
        <div class="bg-gray-200 dark:bg-slate-800 p-6 rounded-lg shadow-md w-1/2 mt-5">
    <form class="border-b-2 pb-10">
        <div>
            <label class="block font-medium text-sm text-gray-700 dark:text-gray-200" for="name">
                Product Name
            </label>
            <input wire:model="name" type="text"
                   class="mt-2 text-sm sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400" />
        </div>
        <div class="mt-4">
            <label class="block font-medium text-sm text-gray-700 dark:text-gray-200" for="category">
                Category
            </label>
            <select wire:model.live="category" name="category"
                    class="mt-2 text-sm sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400" required>
                <option value="">Select Category</option>
                @foreach ($categories as $category)
                    <option value="{{ $category->id }}">{{ $category->name }}</option>
                @endforeach
            </select>
        </div>
        <div class="mt-4">
            <label class="block font-medium text-sm text-gray-700 dark:text-gray-200" for="subcategory">
                Subcategory
            </label>
            <select name="subcategory" wire:model="subcategory"
                    class="mt-2 text-sm sm:text-base pl-2 pr-4 rounded-lg border border-gray-400 w-full py-2 focus:outline-none focus:border-blue-400">
                    <option value="">Select Subcategory</option>
                @foreach ($subcategories as $subcategory)
                    <option value="{{ $subcategory->id }}">{{ $subcategory->name }}</option>
                @endforeach
            </select>
        </div>
        <div class="flex items-center mt-4">
            <button type="submit"
    class="inline-flex items-center px-4 py-2 bg-gray-800  dark:bg-green-500 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 dark:hover:bg-green-600 active:bg-gray-900  dark:active:bg-green-700 focus:outline-none focus:border-gray-900 focus:shadow-outline-gray disabled:opacity-25 transition ease-in-out duration-150">
    Add Product
</button>
        </div>
    </form>
        </div>
    </div>
</div>

Seeding Data

Now we need to add some dummy data inside it. To add dummy data we need to create Seeder files. We will create two Seeder files : CategorySeeder & Subcategory Seeder.

Open your terminal & enter below code one by one :

php artisan make:seeder CategorySeeder
php artisan make:seeder SubcategorySeeder

The above commands will generate two seeder files called CategorySeeder & SubcategorySeeder inside database/seeders folder.

Now open CategorySeeder.php file and add below code inside it :

public function run(): void
    {
        DB::table('categories')->insert([
            ['name' => 'Electronics'],
            ['name' => 'Clothing'],
            ['name' => 'Home & Kitchen'],
            ['name' => 'Sports & Outdoors'],
        ]);
    }

Now open SubcategorySeeder.php file & enter below code inside it :

public function run()
{
    DB::table('subcategories')->insert([
        ['name' => 'Phones', 'category_id' => 1],     // Electronics
        ['name' => 'Laptops', 'category_id' => 1],    // Electronics
        ['name' => 'Cameras', 'category_id' => 1],    // Electronics
        ['name' => "Men's Clothing", 'category_id' => 2],   // Clothing
        ['name' => "Women's Clothing", 'category_id' => 2], // Clothing
        ['name' => "Kids' Clothing", 'category_id' => 2],   // Clothing
        ['name' => 'Cookware', 'category_id' => 3],   // Home & Kitchen
        ['name' => 'Furniture', 'category_id' => 3],  // Home & Kitchen
        ['name' => 'Appliances', 'category_id' => 3], // Home & Kitchen
        ['name' => 'Outdoor Gear', 'category_id' => 4],     // Sports & Outdoors
        ['name' => 'Fitness Equipment', 'category_id' => 4], // Sports & Outdoors
        ['name' => 'Sports Apparel', 'category_id' => 4],    // Sports & Outdoors
    ]);
}

You will need to import DB façade in both the seeder files, else you will get an error :

use Illuminate\Support\Facades\DB;

Run the seeders

Finally, run the seeders to insert the data into the database:

Open your terminal and run below code one by one :

php artisan db:seed --class=CategorySeeder
php artisan db:seed --class=SubcategorySeeder

This will add some dummy categories & subcategories inside categories & subcategories tables.

Adding Route

Now open web.php file & add below code to add the route for CategorySubcategory dropdown.

Route::get('/category-dropdown', CategorySubcategory::class)->name('category.dropdown');

Do not forget to import CategorysubCategory class in the web.php file.

use App\Livewire\CategorySubcategory;

Now open your terminal & enter below code to run our app :

php artisan serve

Now open your browser & type localhost:8000/category-dropdown

You will see that Now the Categories are populated & when you select a category, only then the subcategories are visible.

Adding Product

Now to add a product with subcategory_id we will add storeProduct() method ,

Copy below code and add it before render method in CategorySubcategory.php file.

public function storeProduct()
    {
        $this->validate([
            'name' => 'required',
            'subcategory' => 'required',
        ]);
        Product::create([
            'name' => $this->name,
            'subcategory_id' => $this->subcategory,
        ]);
    }

You will need to import Product model,

use App\Models\Product;

Now open category-subcategpry.blade.php file and replace form tag with below code :

<form wire:submit="storeProduct" class="border-b-2 pb-10">

Now enter Product name, select category & select a subcategory then click on Add Product.

You will see that the product has been inserted inside the product table with subcategory_id.

Adding success message & clearing inputs

To display success message & clearing inputs add below code inside storeProduct() method :

session()->flash('success', 'Product created successfully.');
$this->reset('name', 'selectedSubCategory', 'category_id');

Your storeProduct() method should look like this :

public function storeProduct()
    {
        $this->validate([
            'name' => 'required',
            'subcategory' => 'required',
        ]);
        Product::create([
            'name' => $this->name,
            'subcategory_id' => $this->subcategory,
        ]);
        session()->flash('success', 'Product created successfully.');
        $this->reset('name', 'subcategory', 'category');
    }

Now open category-subcategory.blade.php file an add below code before the <form> tag :

   @if (session()->has('success'))
    <span class="text-green-500 my-3">{{ session('success') }}</span>
    @endif

Now if you add a Product then you will see a success message and the inputs are cleared.

Display Error Messages

Now to display error messages , open category-subcategory.blade.php file & add below code after input tag :

<span class="text-red-500">@error('name') {{ $message }} @enderror</span>

Add below code after category select tag :

<span class="text-red-500">@error('category') {{ $message }} @enderror</span>

Add below code after subcategory select tag :

<span class="text-red-500">@error('subcategory') {{ $message }} @enderror</span>

Now if you try to add a Product without entering name & selecting category/subcategory you will see error messages:

Display Products with pagination

Now to display products with pagination open CategorySucbategory.php file and add the below code before public $categories :

Use WithPagination;

You will need to import it using below command :

use Livewire\WithPagination;

Now replace render() method with below code :

 public function render()
    {
        return view('livewire.category-subcategory',[
            'products' => Product::with('subcategory.category')->latest()->paginate(5)
        ]);
    }

Now open category-saubcategory.blade.php file & add below code after </form> tag

   <h3 class="font-bold text-xl mt-10 mb-5 dark:text-gray-100">Latest Products</h3>
    <table class="min-w-full bg-gray-300 dark:bg-slate-700">
        <thead>
        <tr>
            <th class="px-6 py-3 border-b-2 border-gray-300 text-left text-sm leading-4 tracking-wider dark:text-gray-100">Product Name</th>
            <th class="px-6 py-3 border-b-2 border-gray-300 text-left text-sm leading-4 tracking-wider dark:text-gray-100">Subcategory</th>
            <th class="px-6 py-3 border-b-2 border-gray-300 text-left text-sm leading-4 tracking-wider dark:text-gray-100">Category</th>
        </tr>
        </thead>
        <tbody class="bg-white">
        @foreach ($products as $product)
            <tr>
                <td class="px-6 py-4 whitespace-no-wrap border-b border-gray-500 text-sm leading-5">{{ $product->name }}</td>
                <td class="px-6 py-4 whitespace-no-wrap border-b border-gray-500 text-sm leading-5">{{ $product->subcategory->name }}</td>
                <td class="px-6 py-4 whitespace-no-wrap border-b border-gray-500 text-sm leading-5">{{ $product->subcategory->category->name }}</td>
            </tr>
        @endforeach
        </tbody>
    </table>
    <div class="mt-5">
        {{ $products->links() }}
    </div>

Now add 5-10 records and you will see pagination links.

Conclusion

In this tutorial, you’ve unlocked the power of Laravel Livewire v3 for creating dependent dropdowns. With these skills, you can build dynamic and responsive user interfaces that enhance the user experience. Now, go forth and apply this knowledge to create user-friendly web applications. Happy coding!

Video Tutorial

This Post Has 10 Comments

  1. Roms

    Wow, i love your tutorials. iv’e always checked your website and youtube account if theres is new content. this is very helful for me.

    i just have request, maybe you can create a tutorial, i think an additional codes/modification for this tuts.
    something like add to cart feature.

    Ideas: All added records will be place for a while in the cart., and records added in the lists have remove or edit option then there is submit button to save all added records in the cart into the database.

    1. Admin

      Thanks 🙂

      Ok I will try.

      1. Roms

        Thank you so much Admin!

  2. Roms

    Hi Admin, can you help me with Add to cart feature? Thank you

  3. Albert

    Hi Admin, good tutorial, but I have one problem. If I add a product and press a pagination link I get the error “The GET method is not supported for route livewire/update. Supported methods: POST.” I googled, it’s a known error but I didn’t found a solution.
    Any idea? Gr. Albert

    1. Admin

      Hello Albert,

      The code is working fine on my end.

      Please check your code.

      1. Albert

        Hello admin,
        It’s also working fine on my site. I didn’t change anything (as programmers say …). First I thought it was the mixture of GET’s and POST’s. Maybe the clear cache/reload made the difference. Thanks for the reaction.

        1. Admin

          Hello Albert,

          If you have a GitHub account, please create a repository and add your project on GitHub.

          Share the link, and I will check your code.

  4. Thakchand Thombre

    Nice Tutorial !

Leave a Reply