Laravel 7.x Livewire search

In this tutorial we are building a search app with Livewire. Laravel Livewire is a tool that makes building dynamic interfaces simple. You don’t need tools like Vue and React for this. All the code is written in php.

To show the strengths of Laravel Livewire, we are going to build a simple search app. In the app we can filter a list of contacts. At the end of the tutorial we have built the following app:

The result

Let’s dive in and discover the possibilities of Laravel Livewire!

Install Tailwindcss

We are going to use Tailwindcss for our styling. I will not cover all the steps that are involved in installing Tailwindcss. You can check out this tutorial for installing Tailwindcss to your Laravel application.

Setup database

The next step is to setup the database structure for this project. First update the .env file with your own database credentials, in my case:

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel7-livewire-search
DB_USERNAME=root
DB_PASSWORD=*******

Open the terminal and run the php artisan make:model Contact -m command. This command will create a model named Contact and a database migration for this model.

Open the freshly made migration and add the fields that we need in the up function.

public function up()
{
    Schema::create('contacts', function (Blueprint $table) {
        $table->id();
        $table->char('name', 75);
        $table->char('phone_number', 75);
        $table->timestamps();
    });
}

To fill the database with data we generate a database seeder and a factory. php artisan make:seeder ContactSeeder && php artisan make:factory ContactFactory --model=Contact. When you make a database seeder you always must run composer dump-autoload.

Open DatabaseSeeder.php and call the ContactSeeder.

public function run()
{
    $this->call(ContactSeeder::class);
}

Update the ContactFactory.php file located in the database\factories folder.

$factory->define(Contact::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'phone_number' => $faker->phoneNumber,
    ];
});

If we run the php artisan migrate --seed command, we have a database table filled with contacts.

Install Laravel Livewire

Now it is time to install Laravel Livewire and implement search functionality!

First, we add the package by running composer require livewire/livewire.

Next, we need to include the JavaScript on every page we are going to use livewire. Create a new folder inside the view directory called layouts. In that folder we are going to create a file called app.blade.php. Add the following code to that file.

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

        <!-- CSRF Token -->
        <meta name="csrf-token" content="{{ csrf_token() }}">

        <title>{{ config('app.name', 'Laravel') }}</title>

        <!-- Scripts -->
        <script src="{{ asset('js/app.js') }}" defer></script>

        <!-- Fonts -->
        <link rel="dns-prefetch" href="//fonts.gstatic.com">
        <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">

        <!-- Styles -->
        <link href="{{ asset('css/app.css') }}" rel="stylesheet">

        @livewireStyles
    </head>
    <body>
        <div id="app" class="flex min-h-screen bg-gray-200">
            @yield('content')
        </div>

        @livewireScripts
    </body>
</html>

Make a component

Next, we need to make a livewire component. Run php artisan make:livewire search-contacts. This will create two new files in your project:

app/http/Livewire/SearchContacts.php

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

We can render a Livewire component as a component on a page. But since we only have the search component on the page, we are going to use Livewire routing.

Replace the code in the routes\web.php file with the following code.

<?php

use Illuminate\Support\Facades\Route;

Route::livewire('/', 'search-contacts');

The logic

Now it’s time to implement the logic for the search component. Replace the App\Http\Livewire\SearchContacts.php with the following code:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Contact;

class SearchContacts extends Component
{
    public $search;

    protected $updatesQueryString = [
        'search' => ['except' => '']
    ];

    public function mount()
    {
        $this->search = request()->query('search', $this->search);
    }

    public function render()
    {
        return view('livewire.search-contacts', [
            'contacts' => Contact::where('name', 'like', '%'.$this->search.'%')->get(),
        ]);
    }
}

First, we create a public search variable. Then we make a call that will update the query string with the value from the search variable.

In the mount() function we set the search variable to the value of the search box.

Then we render the page. We select contacts with a name like typed in the search box.

The design

Now the las step is to make the frontend for our component.

<div class="container mx-auto mt-12">
    <h1 class="mb-12 text-center text-gray-900 text-4xl font-semibold">Laravel 7.x Laravel Livewire search</h1>

    <!-- Searchbox -->
    <div class="w-full p-6 mb-6 bg-white border rounded shadow-xl">
        <input
            wire:model="search"
            type="text"
            placeholder="Search..."
            class="w-full px-4 py-2 bg-gray-100 border"
        >
    </div>
    <!-- // Searchbox -->

    <!-- Search Results -->
    <div class="w-full p-6 divide-y bg-white border rounded shadow-xl">
        @foreach($contacts as $contact)
            <div class="p-2">
                <h2 class="text-md font-semibold text-gray-900">{{ $contact->name }}</h2>
                <p class="text-gray-900">
                    {{ $contact->phone_number }}
                </p>
            </div>
        @endforeach

        @if($contacts == '[]')
            <p class="text-gray-900">No contacts found...</p>
        @endif
    </div>
    <!-- // Search Results -->
</div>

This code is straight forward. First, we will create a search form. We use wire:model="search" to pass the value from the input to the Livewire Controller.

Then, we render the render the search results just like we normally would do with the blade foreach syntax.

It’s ready!

That’s it! Now we can search dynamically for contacts.

The result

GitHub

As always you can find the source code for this tutorial on GitHub. If you have any questions, let me know in the comments!

Leave a comment

Your email address will not be published. Required fields are marked *