In previous article we employed Fetch API to make AJAX calls from within Alpine.js in order to dynamically update the data table from backend database. Now let’s make life easier by introducing Livewire. In this article, we’ll incorporate simple search capability utilizing Livewire component in Laravel 9 app. So, let’s buckle up!
Laravel 9.x requires a minimum PHP version of 8.0. This tutorial assumes that you are using Linux, MacOS or WSL on Windows and Node.js, Composer and PHP 8 along with required modules i.e bcmatch, sqlite, mbstring, xml, zip, gd, mcrypt are properly installed. Also make sure that SQLite is installed as we’ll be using SQLite to keep things simple and quick; you may use MySQL or PostgreSQL as you like, however make sure the corresponding PHP module is installed too.
Using Composer, enter following command in terminal to install Laravel 9;
composer create-project laravel/laravel app 9.*
Now go inside newly created app directory by executing;
cd app
Using Composer, add default Breeze package by executing following command which will incorporate basic authentication along with User model;
composer require laravel/breeze:* --dev
Now install Breeze package by executing;
php artisan breeze:install
The above command will also install required node modules and compile the UI assets (client-side JS and CSS files) for the first time.
Next, setup database and Laravel environment file. Here, I’m configuring SQLite database for simplicity purposes.
Being in parent directory (app), execute following command in order to create new SQLite database file;
touch database/database.sqlite
Then find .env config file in the parent directory, open it and amend DB_CONNECTION line as follows;
DB_CONNECTION = sqlite
You can remove DB_HOST, DB_PORT, DB_DATABASE, DB_USERNAME, DB_PASSWORD from .env when using SQLite database.
Save and close .env file. Now enter following command in order to create database structure (this will also create users table into database);
php artisan migrate
In order to quickly populate users table in database, let’s enter following command to invoke tinker;
php artisan tinker
And then enter following command to create 100 users;
User::factory(100)->create()
The above command will utilize database\factories\UserFactory.php to generate fake data for app testing.
Note down any of the generated email addresses for logging in later. Then, type ‘quit’ and press Enter to exit tinker.
Now, let’s install Livewire by executing following command in parent directory (app) directory:
composer require livewire/livewire
Then, create a Livewire component UserSearch by executing following command:
php artisan make:livewire UserSearch
The above command will create two files i.e., app\Http\Livewire\UserSearch.php and resources\views\livewire\user-search.blade.php. The UserSearch.php file will handle the back-end part of component whereas user-search.blade.php will render the view side of the component. So, let’s define our Livewire component by changing app\Http\Livewire\UserSearch.php as follows:
<?php
namespace App\Http\Livewire;
use Livewire\Component;
use App\Models\User;
class UserSearch extends Component
{
public $search;
public function render()
{
return view('livewire.user-search', [
'users' => User::where('name','like', '%'.$this->search.'%')->get(),
]);
}
}
Then, change resources\views\livewire\user-search.blade.php as follows:
<div class="py-6">
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
<div class="p-4 bg-white border-b border-gray-200">
<input type="text" class="mb-2 p-1 border border-gray-400 rounded-md" placeholder="Search..." wire:model="search" />
<table class="shadow-lg" style="width: 100%;">
<thead>
<tr class="bg-gray-400 text-white font-extrabold">
<th class="px-4 py-1 text-center">ID</th>
<th class="px-4 py-1">Name</th>
<th class="px-4 py-1">Email</th>
</tr>
</thead>
<tbody>
@foreach ($users as $user)
<tr>
<td class="border px-4 py-1 text-center">{{ $user->id }}</td>
<td class="border px-4 py-1">{{ $user->name }}</td>
<td class="border px-4 py-1">{{ $user->email }}</td>
</tr>
@endforeach
</tbody>
</table>
</div>
</div>
</div>
</div>
The magic here is wire:model=”search” in <input> field which binds this input field to $search property at the back-end side of component – whenever there’s a change in search input field at client-side, the change will automatically impact the $search variable at the back-end and the render() function will be triggered which will send the updated data to client-side. This all mechanism happens using AJAX calls behind the scene.
Now, let’s change resources\views\layouts\app.blade.php a bit in order to incorporate Livewire in our app layout. What we’ll do here is add a couple of tags i.e., <livewire:styles /> and <livewire:scripts /> before closing tags of </head> and </body> respectively. The amended app.blade.php will look like as follows;
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.bunny.net/css2?family=Nunito:wght@400;600;700&display=swap">
<!-- Scripts -->
@vite(['resources/css/app.css', 'resources/js/app.js'])
<livewire:styles />
</head>
<body class="font-sans antialiased">
<div class="min-h-screen bg-gray-100">
@include('layouts.navigation')
<!-- Page Heading -->
@if (isset($header))
<header class="bg-white shadow">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
{{ $header }}
</div>
</header>
@endif
<!-- Page Content -->
<main>
{{ $slot }}
</main>
</div>
<livewire:scripts />
</body>
</html>
Finally, let’s put our Livewire component UserSearch somewhere to check its functionality. For that purpose, amend resources\views\dashboard.blade.php as follows:
<x-app-layout>
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Dashboard') }}
</h2>
</x-slot>
<livewire:user-search />
</x-app-layout>
Then run following command to compile UI assets:
npm run build
Finally, execute following command in parent directory to run PHP development server;
php artisan serve
Open browser and enter following URL in address bar;
http://localhost:8000
Login with the noted email address as above (just remember, the default password for all users generated through above factory is ‘password’). After logging in, you’ll be taken directly to Dashboard, where UserSearch Livewire component is embedded. So, let’s use that search field.