DEV Community

Madin Bloch
Madin Bloch

Posted on

Step-by-Step Guide to Building a Dynamic Search Filter in Laravel with jQuery & AJAX

Image description

Introduction

While working on a recent project, I came across a requirement where users needed to filter a list of suppliers dynamically based on either the business name or the business type. Initially, all suppliers were shown in a dropdown, but once a filter and keyword were selected, the list had to update instantly without reloading the page.

In this blog post, I’ll walk you through how I solved this by implementing a dynamic supplier search filter using Laravel, jQuery, and AJAX. Whether you’re new to Laravel or just want to improve your UI interactivity with AJAX, this guide is for you.

You’ll learn how to:

  • Build a simple and intuitive search UI
  • Make AJAX requests using jQuery
  • Filter and return JSON responses from Laravel
  • Dynamically update a dropdown based on user input
  • Let’s jump right into it!

Prerequisites

  • A Laravel 10 or 11 project
  • jQuery included (via CDN or Laravel Mix/Vite)
  • Familiarity with routes, controllers, and Blade views

Step 1: Create the Suppliers Table

Let’s start by defining a basic suppliers table. Here’s the migration example:

Schema::create('suppliers', function (Blueprint $table) {
    $table->id('supplier_id');
    $table->string('business_name');
    $table->string('business_type');
    $table->boolean('status')->default(1);
    $table->timestamps();
});
Enter fullscreen mode Exit fullscreen mode

Seed your database with sample values like:

Business Names: “PaperCorp Ltd”, “InkWell Inc”, “Stationery Hub”, “Printify”
Business Types: “Printing”, “Packaging”, “Wholesale”, “Stationery”

Step 2: Create the Blade View with Filter UI

Here’s how the filter and dropdown UI looks in Blade:

<div class="d-flex align-items-center mb-3">
    <div class="col-mg-3 mr-2">
        <label for="filterCriteria" class="form-label mb-0">Filter By:</label>
        <select id="filterCriteria" class="form-control">
            <option value="all">Select filter</option>
            <option value="business_type">Business Type</option>
            <option value="business_name">Business Name</option>
        </select>
    </div>
    <div class="col-mg-2 mr-2">
            <label for="search_suppliar_value" class="form-label mb-0">Search:</label>
            <input type="text" id="search_suppliar_value" class="form-control searchInput" placeholder="">
        </div>
        <button class="btn btn-primary search_suppliar mt-4">Search</button>
    </div>
    <select class="form-control selectpicker" id="paper_supplier" name="paper_supplier" data-live-search="true">
        <option value="">Choose supplier</option>
    </select>

 <div class="form-group row align-items-center">
      <label class="col-lg-2 col-form-label text-right">Supplier:</label>
          <div class="col-lg-5 selectOption">
               <input class="form-control input optionInput" type="text" style="display: none" />
     <select class="form-control selectpicker selectedOption" id="paper_supplier" name="paper_supplier" data-live-search="true">
          <option value="">Choose supplier</option>
   @if(isset($suppliers))
        @foreach($suppliers as $supplier)
        <option value="{{ $supplier->supplier_id }}">{{ $supplier->business_type 
        @endforeach
   @elseif(isset($suppliersData) && $suppliersData->supplier_id != null)
         <option selected="selected" value="{{ $suppliersData->supplier_id }}">{{ $suppliersData->business_name }}</option>
        @foreach($allsuppliers as $supplier)
     <option value="{{ $supplier->supplier_id }}">{{ $supplier->business_name }}</option>
        @endforeach
   @else
    @foreach($allsuppliers as $supplier)
       <option value="{{ $supplier->supplier_id }}">{{ $supplier->business_name }}</option>
   @endforeach
   @endif
</select>
</div>
Enter fullscreen mode Exit fullscreen mode

Step 3: jQuery + AJAX Logic

Now add the script to handle the dynamic search:

$('.search_suppliar').on('click', function (e) {
            e.preventDefault(); // Prevent the default form submission

            // Get filter criteria and search value
            var filterCriteria = $('#filterCriteria').val();
            var searchValue = $('#search_suppliar_value').val();

            // Perform an AJAX request to the server
            $.ajax({
                url: "{{route('search.supplier')}}", // Laravel route
                method: 'GET',
                data: {
                    filter: filterCriteria,
                    search: searchValue
                },
                    success: function (response) {
                    $('#paper_supplier').find('option').not(':first').remove(); // Clear old options

                    if (response.suppliers.length === 0) {
                        $('#paper_supplier').append('<option value="">No suppliers found</option>');
                    } else {
                        $.each(response.suppliers, function (key, supplier) {
                            let optionLabel = '';

                            if (filterCriteria === 'business_name') {
                                optionLabel = supplier.business_name;
                            } else if (filterCriteria === 'business_type') {
                                // You can either show type, or name + type
                                optionLabel = supplier.business_name + ' (' + supplier.business_type + ')';
                            } else {
                                optionLabel = supplier.business_name;
                            }

                            $('#paper_supplier').append('<option value="' + supplier.supplier_id + '">' + optionLabel + '</option>');
                        });
                    }

                    $('#paper_supplier').selectpicker('refresh');
                },

                error: function (xhr, status, error) {
                    console.    or('Error fetching data:', error);
                }
            });
        });
Enter fullscreen mode Exit fullscreen mode

Step 4: Define the Route

In your routes\web.php:

Route::get('/search-supplier', [SupplierController::class, 'searchSupplier'])->name('search.supplier');
Enter fullscreen mode Exit fullscreen mode

Step 5: Controller Logic

In your Controller\SupplierController:


public function searchSupplier(Request $request)
{
    $filter = $request->input('filter');
    $search = $request->input('search');

    // Simple Logic

    $query = DB::table('suppliers')->where('status', 1);
        if ($filter == 'business_type') {
            $query->where('business_type', 'LIKE', '%' . $search . '%');
        } elseif ($filter == 'business_name') {
            $query->where('business_name', 'LIKE', '%' . $search . '%');
        }
        $suppliers = $query->orderBy('supplier_id', 'desc')->get();
        return response()->json(['suppliers' => $suppliers]);
}
Enter fullscreen mode Exit fullscreen mode

Tips for Real-World Usage

  • Use Form Request validation if needed
  • Structure controller logic using Repository and Service layers for maintainability
  • Limit or paginate results to handle large datasets
  • Apply middleware if route protection is needed

Final Output

Your UI now allows users to select a filter criteria, type a search value, and see a dynamically updated list of suppliers without reloading the page. Super smooth and efficient!

Conclusion

This solution is ideal for enterprise applications such as inventory systems, vendor management, and custom CRMs. With Laravel’s backend power and jQuery’s frontend responsiveness, you can deliver a seamless UX.

Now that you’ve seen how to build this from scratch, try extending it to more complex filtering, chained dropdowns, or even Vue or React-based dynamic interfaces.

Happy coding! 🚀

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.