Laravel Search Autocomplete with Images

Posted on

This tutorial will guide you through creating a Laravel search autocomplete feature in an application. This feature will search for items by name and display their images. When an item is clicked, a detailed view of the item will be shown.

Laravel Search Autocomplete with Images
Laravel Search Autocomplete with Image

Install Laravel Search Autocomplete

First, ensure you have Composer installed. Then, create a new Laravel project:

composer create-project --prefer-dist laravel/laravel search-autocomplete

Navigate to your project directory:

cd search-autocomplete
code .

Create the Database

Create a new database for your Laravel project and update the .env file with your database details:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=your_username
DB_PASSWORD=your_password

Create the Item Model and Migration

Run the following Artisan command to create a model and migration for items:

php artisan make:model Item -m

Update the generated migration file to include item_name and image_url columns:

// database/migrations/xxxx_xx_xx_create_items_table.php

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

class CreateItemsTable extends Migration
{
    public function up()
    {
        Schema::create('items', function (Blueprint $table) {
            $table->id();
            $table->string('item_name');
            $table->string('image_url');
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('items');
    }
}

Run the migration to create the items table:

php artisan migrate

Create the Item Seeder

Generate a seeder for the items table:

php artisan make:seeder ItemSeeder

Update the seeder file to insert sample items with names and image URLs:

// database/seeders/ItemSeeder.php

use Illuminate\Database\Seeder;
use App\Models\Item;

class ItemSeeder extends Seeder
{
    public function run()
    {
        $items = [
            ['item_name' => 'Asus AIO Type A5402WVA', 'image_url' => 'https://dlcdnwebimgs.asus.com/files/media/d96b66e9-4b63-4a31-b51a-bc3e2f51e499/v1/features/images/medium/2x/kv/main.webp'],
            ['item_name' => 'Acer Laptop Aspire 5', 'image_url' => 'https://images.acer.com/is/image/acer/Aspire5_KSP_03-1:Static-KSP-Image-Right-Left-L'],
            ['item_name' => 'Apple MacBook Pro', 'image_url' => 'https://bb-scm-prod-pim.oss-ap-southeast-5.aliyuncs.com/products/84d62c4bf14ffc55749cc0254d754a91/helix/01-APPLE-8DVLPAPP0-APPMNEJ3ID-A-SpaceGrayRevSS.jpg?x-oss-process=image/format,webp'],
            ['item_name' => 'Dell XPS 13', 'image_url' => 'https://p-id.ipricegroup.com/uploaded_9d47fb1ec9272186637a73afb9a31000.jpg'],
            ['item_name' => 'HP Spectre x360', 'image_url' => 'https://id-media.apjonlinecdn.com/catalog/product/cache/b3b166914d87ce343d4dc5ec5117b502/c/0/c08743973-ultraevo.png'],
            // Add more items as needed
        ];

        Item::insert($items);
    }
}

Register the seeder in DatabaseSeeder:

// database/seeders/DatabaseSeeder.php

use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    public function run()
    {
        $this->call([
            ItemSeeder::class,
        ]);
    }
}

Run the seeder:

php artisan db:seed

Create the Controller

Generate a controller for handling the search functionality:

php artisan make:controller SearchController

Update the SearchController to include methods for displaying the search view, handling AJAX requests, and showing item details:

// app/Http/Controllers/SearchController.php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Item;

class SearchController extends Controller
{
    public function index()
    {
        return view('search');
    }

    public function search(Request $request)
    {
        if ($request->get('query')) {
            $query = $request->get('query');
            $data = DB::table('items')
                ->where('item_name', 'LIKE', "%{$query}%")
                ->get();

            $output = '<ul class="dropdown-menu" style="display:block; position:relative">';
            foreach ($data as $row) {
                $output .= '<li><a href="/item/' . $row->id . '"><img src="' . $row->image_url . '" alt="' . $row->item_name . '" style="width:50px;height:50px;margin-right:10px;">' . $row->item_name . '</a></li>';
            }
            $output .= '</ul>';

            echo $output;
        }
    }

    public function show($id)
    {
        $item = Item::findOrFail($id);
        return view('item_detail', compact('item'));
    }
}

Create the Routes

Add routes for displaying the search view, handling AJAX requests, and showing item details:

// routes/web.php

use App\Http\Controllers\SearchController;

Route::get('/', [SearchController::class, 'index']);
Route::get('/ajax-autocomplete', [SearchController::class, 'search']);
Route::get('/item/{id}', [SearchController::class, 'show']);

Create the Views

Create the search.blade.php view:

<!-- resources/views/search.blade.php -->

<!DOCTYPE html>
<html>
<head>
    <title>Laravel Search Autocomplete</title>
    <meta name="csrf-token" content="{{ csrf_token() }}">
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
    <div class="px-4 py-5 my-5 text-center">
        <img class="d-block mx-auto mb-4" src="https://laravel.com/img/logotype.min.svg" alt="" height="70">
        <h3 class="fw-bold mb-3">Laravel Ajax Search Autocomplete</h3>
        <div class="col-lg-6 mx-auto">
            <div class="bg-white p-4 shadow border-0 rounded-4 mb-3">
                <input type="text" name="item_name" id="item_name" class="form-control" placeholder="Type product name" required>
                <div id="itemList"></div>
            </div>
        </div>
    </div>
</div>

<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $('#item_name').keyup(function() {
            var query = $(this).val();
            var _token = $('meta[name="csrf-token"]').attr('content');
            if (query != '') {
                $.ajax({
                    url: '/ajax-autocomplete',
                    method: "GET",
                    data: { query: query, _token: _token },
                    success: function(data) {
                        $('#itemList').fadeIn();
                        $('#itemList').html(data);
                    }
                });
            } else {
                $('#itemList').fadeOut();
            }
        });

        $(document).on('click', 'li', function() {
            $('#item_name').val($(this).text());
            $('#itemList').fadeOut();
        });
    });
</script>
</body>
</html>

Create the item_detail.blade.php view:

<!-- resources/views/item_detail.blade.php -->

<!DOCTYPE html>
<html>
<head>
    <title>Item Detail</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<div class="container mt-5">
    <div class="card">
        <img src="{{ $item->image_url }}" class="card-img-top" alt="{{ $item->item_name }}">
        <div class="card-body">
            <h5 class="card-title">{{ $item->item_name }}</h5>
            <p class="card-text">More details about the item can be displayed here.</p>
            <a href="/" class="btn btn-primary">Go back</a>
        </div>
    </div>
</div>
</body>
</html>

Read more: Getting the Current URL in Blade Laravel

Run the Application

Start the Laravel development server:

php artisan serve

Visit http://127.0.0.1:8000 in your browser to see the search autocomplete feature in action. Type a product name in the search box to see matching items with images. Clicking on an item will take you to its detail page.

Source: ZcodeID