How to Create Realtime Search in Laravel 11 Livewire

Hello, laravel web developers! In this article, we'll see how to create real-time search in laravel 11 Livewire. Here, we'll laravel 11 build live search with Livewire. Laravel Livewire is a library for building reactive and dynamic interfaces using Blade as your templating engine.

It works by making AJAX requests to the server and rendering the updated HTML sent to it by the server. we will build a live search with MySQL database.

Build a Live Search Box with Laravel Livewire and MySQL

build live search box with laravel livewire and mysql

 

Step 1: Install Laravel 11 Application

 We'll install the laravel 11 application using the following command in this step.

composer create-project laravel/laravel laravel-11-application

 

Step 2: Install Livewire

Then, we'll install Laravel Livewire using the following command.

composer require livewire/livewire

We will build it directly using npx. you can link to Tailwind CSS directly from the CDN.

npx tailwindcss-cli@latest build -o public/css/tailwind.css

 

 

Step 3: Create Database Migrate

Next, we'll create migration using the following command. Also, we'll add the FULLTEXT index.

<?php

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

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->mediumText('bio');
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });

        DB::statement(
            'ALTER TABLE users ADD FULLTEXT fulltext_index(name, email, bio)'
        );
    }

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

Now, we'll create a factory to create some dummy records using the following code.

php artisan make:migration UserFactory

database/factories/UserFactory.php

<?php

    public function definition()
    {
        return [
            'name' => $this->faker->name,
            'email' => $this->faker->unique()->safeEmail,
            'bio' => $this->faker->text(200),
            'email_verified_at' => now(),
            'password' => Hash::make("password"),
            'remember_token' => Str::random(10),
        ];
    }

Generate users based on the factory.

database/seeders/DatabaseSeeder.php

public function run()
{
    \App\Models\User::factory(100)->create();
}

Next, run the following command to migrate the table.

php artisan migrate && php artisan db:seed

 

Step 4: Create a Traits

Now, we'll create traits to search records from the MySQL database. Traits are a way to reuse code in Laravel. we will create a Search trait that we can use from any Laravel model by adding a $searchable field to the model.

app/Models/Search.php

<?php

namespace App\Models;

trait Search
{
    private function buildWildCards($term) {
        if ($term == "") {
            return $term;
        }

        // Strip MySQL reserved symbols
        $reservedSymbols = ['-', '+', '<', '>', '@', '(', ')', '~'];
        $term = str_replace($reservedSymbols, '', $term);

        $words = explode(' ', $term);
        foreach($words as $idx => $word) {
            $words[$idx] = "+" . $word . "*";
        }
        $term = implode(' ', $words);
        return $term;
    }

    protected function scopeSearch($query, $term) {
        $columns = implode(',', $this->searchable);

        $query->whereRaw(
            "MATCH ({$columns}) AGAINST (? IN BOOLEAN MODE)",
            $this->buildWildCards($term)
        );
        return $query;
    }
}

update the User.php file and add the Search Trait.

app/Models/User.php

<?php

namespace App\Models;

class User extends Authenticatable
{
    use HasFactory, Notifiable;
    use Search; // Use the search trait we created earlier        

    protected $searchable = [
        'name',
        'email',
        'bio',
    ];
}

 

 

Step 5: Create Livewire Component

Add the @livewireStyles and @livewireScripts directive within the <head> tag, and at the end of the <body> tag respectively, in your app layout.

resources/views/welcome.blade.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>How to Create Realtime Search in Laravel 11 Livewire - Techsolutionstuff</title>
    @livewireStyles
</head>
<body>

    @livewireScripts
</body>
</html>

Now, create a Search Component using the following command.

php artisan make:livewire SearchUser

It will two files with two different locations:

app/Http/Livewire/SearchUser.php
resources/views/livewire/search-user.blade.php

app/Http/Livewire/SearchUser.php

<?php

namespace App\Http\Livewire;

use App\Models\User;
use Livewire\Component;

class SearchUser extends Component
{
    public $term = "";

    public function render()
    {
        sleep(1);
        $users = User::search($this->term)->paginate(10);

        $data = [
            'users' => $users,
        ];

        return view('livewire.search-user', $data);
    }
}

resources/views/livewire/search-user.blade.php

<div>
    <div class="px-4 space-y-4 mt-8">
        <form method="get">
            <input class="border-solid border border-gray-300 p-2 w-full md:w-1/4" 
                type="text" placeholder="Search Users" wire:model="term"/>
        </form>
        <div wire:loading>Searching users...</div>
        <div wire:loading.remove>        
        @if ($term == "")
            <div class="text-gray-500 text-sm">
                Enter a term to search for users.
            </div>
        @else
            @if($users->isEmpty())
                <div class="text-gray-500 text-sm">
                    No matching result was found.
                </div>
            @else
                @foreach($users as $user)
                    <div>
                        <h3 class="text-lg text-gray-900 text-bold">{{$user->name}}</h3>
                        <p class="text-gray-500 text-sm">{{$user->email}}</p>
                        <p class="text-gray-500">{{$user->bio}}</p>
                    </div>
                @endforeach
            @endif
        @endif
        </div>
    </div>
    <div class="px-4 mt-4">
        {{$users->links()}}
    </div>
</div>

resources/views/welcome.blade.php

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Laravel 11 Build Live Search with Livewire - techsolutionstuff</title>
    <link href="/css/tailwind.css" rel="stylesheet">
    <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">
    <style>
        body {
            font-family: 'Nunito';
        }
    </style>
    @livewireStyles
</head>
<body>
<header class="bg-gray-900 text-gray-200 w-full py-4 px-4">
 Laravel 11 Build Live Search with Livewire - techsolutionstuff
</header>
<livewire:search-user/>
@livewireScripts
</body>
</html>

 

Step 6: Run the Laravel 11 Application

Now, run the laravel 11 application using the following command.

php artisan serve

 


You might also like:

techsolutionstuff

Techsolutionstuff | The Complete Guide

I'm a software engineer and the founder of techsolutionstuff.com. Hailing from India, I craft articles, tutorials, tricks, and tips to aid developers. Explore Laravel, PHP, MySQL, jQuery, Bootstrap, Node.js, Vue.js, and AngularJS in our tech stack.

RECOMMENDED POSTS

FEATURE POSTS