Dependent dropdown using Livewire in Laravel 9

In last couple of posts we used pure JS and Vue respectively in order to create dependent dropdown (dynamic select menu) in a Laravel 9 app. Now, let’s employ Livewire in Laravel 9 in order to achieve the similar results.

For this article we’ll utilize the models and data created in a previous article. So, first follow the steps given there for creating models, migrations, and relationship and then continue from here.

By following the above-mentioned article, we now have a couple of tables (customers and invoices) having one-to-many relationship along with test data; so, let’s continue and add Livewire package by executing following command in project’s parent folder;

composer require livewire/livewire

Then, execute the following command to generate a new Livewire component called dropdown.

php artisan make:livewire dropdown

Running the above command will generate the following two files:

  • app/Http/Livewire/Dropdown.php
  • resources/views/livewire/dropdown.blade.php

Now, insert following code inside app/Http/Livewire/Dropdown.php;

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Customer;
use App\Models\Invoice;

class Dropdown extends Component
{
    public $customers;
    public $invoices;
    public $selectedCustomer = null;
    public $selectedInvoice = null;
    public $invoice = null;

    public function mount()
    {
        $this->customers = Customer::all();
    }
    
    public function render()
    {
        return view('livewire.dropdown');
    }

    public function updatedSelectedCustomer($customer)
    {
        if ($this->selectedCustomer) {
            $this->invoices = Invoice::where('customer_id', $customer)->get();
            if ($this->invoice) {
                $this->invoice = null;
            }
        }
    }

    public function updatedSelectedInvoice($inv)
    {
        $this->invoice = Invoice::where('id', $inv)->first();
    }
}

Then, insert following code in resources/views/livewire/dropdown.blade.php;

<div>
    <div>
        <label>Customer:</label>
        <div>
            <select wire:model="selectedCustomer">
                <option value="" selected>Choose customer</option>
                @foreach($customers as $customer)
                    <option value="{{ $customer->id }}">{{ $customer->name }}</option>
                @endforeach
            </select>
        </div>
    </div>
    @if ($selectedCustomer)
        <div>
            <label>Invoices:</label>
            <div>
                <select wire:model="selectedInvoice">
                    <option value="" selected>Choose invoice</option>
                    @foreach($invoices as $inv)
                        <option value="{{ $inv->id }}">{{ $inv->invoice_number }}</option>
                    @endforeach
                </select>
            </div>
        </div>
    @endif
    @if ($selectedInvoice && $invoice)
        <table style="border: 1px solid black; border-collapse: collapse; margin: 10px;">
            <tr><td>Invoice Ref:</td><td> {{$invoice->invoice_number}} </td></tr>
            <tr><td>Invoice Date:</td><td> {{$invoice->invoice_date}} </td></tr>
            <tr><td>Customer Name:</td><td> {{$invoice->customer->name}} </td></tr>
            <tr><td>Customer Address:</td><td> {{$invoice->customer->address}} </td></tr>
            <tr><td>Description:</td><td> {{$invoice->description}} </td></tr>
            <tr><td>Amount:</td><td> {{$invoice->amount}} </td></tr>
        </table>
    @endif
</div>

In order to test this dropdown Livewire component, let’s execute following command to create resources/views/home.blade.php;

touch resources/views/home.blade.php

And then, insert following code inside resources/views/home.blade.php;

<!DOCTYPE html>
<html>
    <head>
        <title>Livewire dropdown</title>
    	<livewire:styles />
    </head>
    <body>
        <div>
            <livewire:dropdown />
        </div>
	<livewire:scripts />
    </body>
</html>

Finally, open routes/web.php and enter following new route into it;

Route::get('/home', function () {
    return view('home');
});

Run PHP development server by executing following command;

php artisan serv

Then, enter following URL into the browser;

http://localhost:8000/home

Leave a Comment