Search with Laravel Livewire

Branick Weix
Aug 7 · 6 min read
End Result — Fully interactive search and pagination with no Javascript

For those of you following Laracon 2019, you may have seen the amazing new package from Caleb Porzio called Livewire. As described on his site:

Livewire is a full-stack framework for Laravel that makes building dynamic front-ends as simple as writing vanilla PHP (literally).

I started with Laravel two years ago and one of my biggest challenges has been building interactive pages. Laravel made it easy for me to jump into web development, but I found the jump to using Vue.js or React too confusing and always resulted in another layer of complexity. When Caleb demonstrated his simple counter, I immediately thought Livewire would be ideal for search. I have outlined below how to use Livewire to interactively search through Eloquent records with pagination.


Set up Livewire (docs)

composer require calebporzio/livewire

Include it on all pages you’d like to search on, before the closing body tag:

@livewireAssets </body> 
</html>

Livewire works by connecting data from Livewire components on your front end directly to your backend Livewire controller. These controllers are then able to re-render the component without re-rendering the entire page. Our goal is to pass the search query from an input form to the backend end and use that to search our Eloquent model. This will update the data displayed on the page every time a user searches!

Seed Database (optional)

I’m using a fresh Laravel app for this example. If you’re using an existing app you can skip this step, but otherwise in order to have some data to search you can seed the users table with Laravel’s default user factory. Add this to to your DatabaseSeeder.php file:

Then call php artisan db:seed and you’ll have 500 users to search through!

Create a Search Component

First off, let’s create the search controller and Livewire view:

php artisan make:livewire search

This will create a new “controller” in App\Http\Livewire, called Search.php. It will also make a view called search.blade.php inside of the Livewire views folder.

Create Search Box + Public Variable

Let’s start withsearch.blade.php by adding an input form and bind it to Livewire:

<input type="text" wire:model="searchTerm" />

By setting wire:model="searchTerm"Livewire will automatically update a public variable in our Search.php controller called $searchTerm . Let’s add that now:

I’m including this on the default Laravel home page, but you can add this to any page you’d like. Just add @livewire(‘search’) in your blade file where you want it added. Here’s what I have now:

Display Eloquent Records

Let’s begin by passing all of the users to the component and displaying them in a simple list (no searching yet). Because we’re going to make this interactive, we need to do this all in the search.blade.php file. Simply make another public variable called $users and set that User::all() .

Now when the page renders, it will pass a variable called $users to the search view. We can use Blade like normal and loop through all of the users:

And now we see all of our Users:

Searching Eloquent

To get the results we want, we want to filter our listings by whatever the user searches for. Instead of returning User::all() to the page, we will use SQL’s built in ilike clause to search the database for matching records. Because some users may search for just a last or middle name, we can surround our search term with % signs denoting any number of characters on either side of our term. All together this looks like:

That’s it! If we go to our page we’ll now be able to instantly search through all of the results. We didn’t write a single line of Javascript!

Fully interactive search component using Livewire

What about Pagination?

Some of our users have hundreds of pages of content, we needed an easy way to both interactively search and paginate through all of the results. The steps below will walk through using Laravel’s default pagination with Livewire.

Paginate + Display

Start by paginating the results and displaying the default pagination links in your search.blade.php with {{$users->onEachSide(1)->links()}} . To paginate using Eloquent, update the render query to: $this->users = User::where(‘name’, ‘ilike’, $searchTerm)->paginate(10);

The pagination links will now appear, and they will actually work! However, you may notice that each click is reloading the entire page, and that it throws an error when you try to both search and switch pages. We will need to update the default pagination view to work with Livewire, instead of changing the entire page.

Create Custom Pagination

Instead of building an entirely new pagination system, let’s use the default Laravel one and modify it with new Livewire functions. You can find the default Bootstrap pagination in resources/views/vendor/pagination/ as bootstrap-4.blade.php . Looking into this, we can see that each button and page number is a link set to the previous or next url:

Let’s copy this entire file and create a new custom pagination view called livewire-pagination.blade.php. I then removed all of the href=”url” links throughout the document (there should be three) and set them to href=”#” so that the page doesn’t reload. Finally I added a Livewire click method to each link:

wire:click="setPage('{{$paginator->previousPageURL()}}')"

The updated pagination now looks like:

We also need to update our controller with a new method setPage(url) :

To display this custom pagination, you can link to it directly in your blade view by passing the path in the links function:

{{$users->onEachSide(1)->links('livewire-pagination')}}

Updating Pagination in Controller

Now we need a way to update the pagination results and component based on the current page that is selected. Thankfully Laravel’s Paginator comes with a method currentPageResolver() that lets us preset the page being displayed. We can pass the current page number to this method and it will update the results automatically.

In order to get the selected page number we will need to break apart the url passed into the setPage($url) method. We’ll also have to declare a public $currentPage . All together it looks like this:

Now whenever the pagination buttons are clicked, the pagination results will be updated to display the proper page. When users search their results will also be paginated, and the pagination will reset on every search to avoid confusion:


Hopefully that was helpful! I plan to continue working on this so please let me know of any ideas/issues. You can follow me on Twitter @branickweix

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade