Thursday, 17 September 2020

Laravel 8 Search with Pagination using Livewire


Hi, In this post, we will show you how to make search with pagination application using Livewire in Laravel 8 framework. In previous our Laravel Livewire tutorial, we have make single page CRUD application. Now we want to make application in which we can load data with pagination link and with search filter by using Livewire package in Laravel 8. So here we will step by step learn how to make pagination with Mysql database using Livewire package in Laravel 8 framework.

If you are looking for how to make Livewire search with pagination tutorial from scratch in Laravel 8 framework, then in this post we have share tutorial on how to create Search with Pagination Livewire app in Laravel 8 framework. So this tutorial will help you to learn How to make Laravel 8 Livewire search with pagination app step by step and how to implement live data search functionality with pagination by using Livewire in your Laravel 8 project.

Follow following steps for implement livewire search with pagination in Laravel 8.

  • 1 - Install Laravel 8
  • 2 - Make Database connection
  • 3 - Create table with fake data
  • 4 - Install Livewire package with component
  • 5 - Generate Laravel Pagination Templates
  • 6 - Run Laravel 8 Development Server

Laravel 8 Search with Pagination using Livewire


1 - Install Laravel 8


In first steps we want to download Laravel 8 framework. For this we want to go command prompt and in command prompt go to directory in which we want to download and install Laravel 8 framework. After this run following command.


composer create-project --prefer-dist laravel/laravel livewire-search-pagination

Above command will make livewire-search-pagination directory and under this directory it will download Laravel 8 framework.

2 - Make Database connection


In second steps we want to make Mysql database connection. So in Laravel 8 framework for make database connection, we have to open .env file and under this file we have to define mysql database configuration details.


DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=testing
DB_USERNAME=root
DB_PASSWORD=

The above configuration will make mysql database connection with testing database in your Laravel 8 framework.





3 - Create table with fake data


After making database connection, now in third steps we want to generate fake data. So for generate fake data here we will use Laravel default models class which is User.php and it has been stored in app/Models/User.php this path. So first we want to make table in our testing database. For this we have to go command prompt and run following command.


php artisan migrate

The above command will export user table defination to mysql database and create users table in mysql database. Now we want to generate fake data, so for generate fake data, here we will use Laravel Database seeder class which has been stored under database/seeders/DatabaseSeeder.php path. So we have open this file and define models class at header of this class and write code for generate fake data which you can find below.

database/seeders/DatabaseSeeder.php

<?php

namespace Database\Seeders;

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

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     *
     * @return void
     */
    public function run()
    {
        // User::factory(10)->create();
        User::factory(500)->create();
    }
}


After this we have again go to command prompt and run following command.


php artisan db:seed

This command will execute run() method of DatabaseSeeder.php class and it will generate fake 500 data in users table. So this way we can generate fake data in Laravel 8 framework.

4 - Install Livewire package with component


Now in fourth steps, we want to install Livewire package in Laravel 8 framework. For this, we have go to command prompt and run following command.


composer require livewire/livewire

This command will install Livewire package in Laravel 8 framework. Next we want to make Livewire component. So for this also we have go to command prompt and write following command.


php artisan make:livewire filter

This command will generate two file, one is Filter.php class at app/Http/Livewire directory and filter.blade.php views file at views/livewire directory. This both file will be used for create Livewire Search with pagination application.

So, first we have open app/Http/Livewire/Filter.php file and under this file, we have add use Livewire\WithPagination; and use App\Models\User; at the header of this class and then after Under this class, we have define public $searchTerm; for handle search query request. Under this class render method, which is root method of this class, we have define code for search data and create pagination links.

app/Http/Livewire/Filter.php

<?php

namespace App\Http\Livewire;

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

class Filter extends Component
{
	use WithPagination;

	public $searchTerm;

    public function render()
    {
    	$query = '%'.$this->searchTerm.'%';

    	return view('livewire.filter', [
    		'users'		=>	User::where(function($sub_query){
    							$sub_query->where('name', 'like', '%'.$this->searchTerm.'%')
    									  ->orWhere('email', 'like', '%'.$this->searchTerm.'%');
    						})->paginate(10)
    	]);
    }
}


After this, we have go to views/livewire/filter.blade.php file and under this file, we have create one html table and fill that table with data and below that table we have also make pagination links also.

views/livewire/filter.blade.php

<div>
    <div class="container">
	    <div class="row">
	        <div class="col-md-12">	            
	            <input type="text"  class="form-control" placeholder="Search" wire:model="searchTerm" />
	            <table class="table table-bordered" style="margin: 10px 0 10px 0;">
	                <tr>
	                    <th>Name</th>
	                    <th>Email</th>
	                </tr>
	                @foreach($users as $user)
	                <tr>
	                    <td>
	                        {{ $user->name }}
	                    </td>
	                    <td>
	                        {{ $user->email }}
	                    </td>
	                </tr>
	                @endforeach
	            </table>
	            {{ $users->links() }}
	        </div>
	    </div>
	</div>
</div>


Next we have go to resources/views/welcome.blade.php file and under this file, we want to include source of resources/views/livewire/filter.blade.php file. So for this, we have write @livewire('filter') and then after we want to include livewire scripts, so for this, we have write @livewireScripts. By using this tag, we can included livewire javascript file under this welcome.blade.php file.

resources/views/welcome.blade.php

<!DOCTYPE html>
<html>
    <head>
        <title></title>
        <!-- Fonts -->
        <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
 
        <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.1/css/bootstrap.min.css">
    </head>
     
<body>
    <div class="container mt-4">
        <div class="card">
            <div class="card-header">
                <b>Search & Pagination with Livewire in Laravel 8</b>
            </div>
            <div class="card-body">
                @livewire('filter')
            </div>
        </div>
    </div>
</body>

@livewireScripts

</html>

The above process will make Livewire Search with pagination application using default Livewire pagination templates but you want to use Bootstrap 4 pagination templates you have to follow 5thstep which you can find below.

5 - Generate Laravel Pagination Templates


For implement Bootstrap 4 pagination templates under this Laravel Livewire pagination templates, so first want to generate different Laravel pagination templates. So for this we have go to command prompt and run following command.


php artisan vendor:publish

After run this command it will ask for which vendor class want be publish, so we have to enter 16 which is Laravel-Pagination and then after it will generate different Laravel pagination templates at resources/views/vendor/pagination directory which you can find in below image.


Laravel 8 Search with Pagination using Livewire


So from that list of templates, we have to open resources/views/vendor/pagination/bootstrap-4.blade.php file and copy whole file code and paste into resources/views/livewire/livewire-pagination.blade.php file. After this, we want to removed all of the href="url" links and put href="#" so page will not be reload when we have click on pagination links. After this, we have to add wire:click attribute in each link so our file code will be look like below file.

resources/views/vendor/pagination/bootstrap-4.blade.php

@if ($paginator->hasPages())
    <nav>
        <ul class="pagination">
            {{-- Previous Page Link --}}
            @if ($paginator->onFirstPage())
                <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
                    <span class="page-link" aria-hidden="true">&lsaquo;</span>
                </li>
            @else
                <li class="page-item">
                    <a class="page-link" href="#" wire:click="setPage('{{ $paginator->previousPageUrl() }}')" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
                </li>
            @endif

            {{-- Pagination Elements --}}
            @foreach ($elements as $element)
                {{-- "Three Dots" Separator --}}
                @if (is_string($element))
                    <li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
                @endif

                {{-- Array Of Links --}}
                @if (is_array($element))
                    @foreach ($element as $page => $url)
                        @if ($page == $paginator->currentPage())
                            <li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
                        @else
                            <li class="page-item"><a class="page-link" href="#" wire:click="setPage('{{ $url }}')">{{ $page }}</a></li>
                        @endif
                    @endforeach
                @endif
            @endforeach

            {{-- Next Page Link --}}
            @if ($paginator->hasMorePages())
                <li class="page-item">
                    <a class="page-link" href="#" wire:click="setPage('{{ $paginator->nextPageUrl() }}')" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
                </li>
            @else
                <li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
                    <span class="page-link" aria-hidden="true">&rsaquo;</span>
                </li>
            @endif
        </ul>
    </nav>
@endif


Then after we have to open resources/views/livewire/filter.blade.php file and put {{ $users->links('livewire.livewire-pagination') }} in place of {{ $users->links() }} code which you can seen below.

resources/views/livewire/filter.blade.php

<div>
    <div class="container">
	    <div class="row">
	        <div class="col-md-12">	            
	            <input type="text"  class="form-control" placeholder="Search" wire:model="searchTerm" />
	            <table class="table table-bordered" style="margin: 10px 0 10px 0;">
	                <tr>
	                    <th>Name</th>
	                    <th>Email</th>
	                </tr>
	                @foreach($users as $user)
	                <tr>
	                    <td>
	                        {{ $user->name }}
	                    </td>
	                    <td>
	                        {{ $user->email }}
	                    </td>
	                </tr>
	                @endforeach
	            </table>
	            {{ $users->links('livewire.livewire-pagination') }}
	        </div>
	    </div>
	</div>
</div>


Next we have go add setPage($url) method in app/Http/Livewire/Filter.php which you can seen below source code.

app/Http/Livewire/Filter.php

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use Livewire\WithPagination;
use Illuminate\Pagination\Paginator;
use App\Models\User;

class Filter extends Component
{
	use WithPagination;

	public $searchTerm;
    public $currentPage = 1;

    public function render()
    {
    	$query = '%'.$this->searchTerm.'%';

    	return view('livewire.filter', [
    		'users'		=>	User::where(function($sub_query){
    							$sub_query->where('name', 'like', '%'.$this->searchTerm.'%')
    									  ->orWhere('email', 'like', '%'.$this->searchTerm.'%');
    						})->paginate(10)
    	]);
    }

    public function setPage($url)
    {
        $this->currentPage = explode('page=', $url)[1];
        Paginator::currentPageResolver(function(){
            return $this->currentPage;
        });
    }
}



6 - Run Laravel 8 Development Server


So, All are sets now we are ready for view output in browser. So first we want to start Laravel server. So we have go to command prompt and run following command.


php artisan serve

After run this command it will start Laravel development server and provide us base url of our Laravel application.


http://127.0.0.1:8000/

So, for view Laravel 8 Livewire Search with Pagination application, we have to type above base url in browser and we check output in browser. So, this is complete step by step process for make Livewire Search with Pagination in Laravel 8 tutorial with implementing Bootstrap 4 pagination templates in place of default Livewire pagination templates. If you have any query regarding this tutorial you can make comment in below comment box and then after we will solve your query by replying on your comment.

2 comments:

  1. Unfortunatley, this works except that when I click the pagination link it throws an error: Unable to call component method. Public method [http://127.0.0.1:9000/contacts/?page=2] not found on component: [data-tables]. Any ideas on how to solve this?

    ReplyDelete
  2. Unmatched '}' (View: H:\New Data\htdocs\livewire-search-pagination\resources\views\welcome.blade.php)

    ReplyDelete