Create custom pagination layout in Laravel

400
laravel pagination

In this article, we will learn about setting custom pagination links in laravel. Pagination is a basic feature in web applications. Laravel provides a default pagination system built on bootstrap. We can change the default pagination view to our custom ones. This process is pretty simple than you may have thought.

We have a base project with a basic setup including a database, config and others. First of all, we need to publish the pagination view files from the default laravel package. Simply, run the below command to publish.

php artisan vendor:publish --tag=laravel-pagination

Here we define the tag because we only want to export the pagination files. You may also not use tag which will publish all the publishable files into your views directory. By running above command, it will copy the list of files from [/vendor/laravel/framework/src/Illuminate/Pagination/resources/views] To [/resources/views/vendor/pagination].

The default that laravel uses is default.blade.php. Since, we are creating our own pagination layout, we will create a new file as custom.blade.php. In this file, we will write the custom layout code.

//resources/views/vendor/pagination/custom.blade.php

<div class="pagination p12">
    @if ($paginator->hasPages())
        <ul>
            @if ($paginator->onFirstPage())
                <a class="disabled" href="javascript:void(0)"><li>Previous</li></a>
            @else
                <a href="{{ $paginator->previousPageUrl() }}"><li>Previous</li></a>
            @endif

            @foreach ($elements as $element)

                @if (is_string($element))
                    <li class="disabled"><span>{{ $element }}</span></li>
                @endif



                @if (is_array($element))
                    @foreach ($element as $page => $url)
                        @if ($page == $paginator->currentPage())
                            <a class="is-active" href="javascript:void(0)"><li>{{ $page }}</li></a>
                        @else
                            <a href="{{ $url }}"><li>{{ $page }}</li></a>
                        @endif
                    @endforeach
                @endif
            @endforeach



            @if ($paginator->hasMorePages())
                <a href="{{ $paginator->nextPageUrl() }}"><li>Next</li></a>
            @else
                <a href="javascript:void(0)"><li>Next</li></a>
            @endif


        </ul>
    @endif
</div>

In the above code, $paginatoris an instance of Illuminate\Pagination\LengthAwarePaginator class which is used by pagination in Laravel. This object has various methods such as hasPages(), onFirstPage(), previousPageUrl() etc. If we remove the PHP code from the above code, the basic HTML structure will be as follow.

//pagination HTML markup
<div class="container">
    <div class="pagination p12">
      <ul>
        <a href="#"><li>Previous</li></a>
        <a href="#"><li>1</li></a>
        <a href="#"><li>2</li></a>
        <a class="is-active" href="#"><li>3</li></a>
        <a href="#"><li>Next</li></a>
      </ul>
    </div>
  </div>

Laravel comes with the default users table and factory. We can use tinker to populate the users table. Note that you must have migrated the tables prior to this. To use tinker and populate the database, run the below command serially.

//command

//enter tinker
php artisan tinker

//populate users table with 50 records
App\Models\User::factory()->count(50)->create();

Now, we have created the layout of our pagination, let’s populate the database, retrieve the data and pass it to the view. First of all, we will create a route for displaying records.

//web.php
Route::resource('users', UserController::class);

Secondly, we need to create a controller. Run the below to create it.

//command

php artisan make:controller UserController

Inside the UserController, retrieve the users list that we have already populated and pass it to view. Note, we must use paginate to retrieve the records otherwise there will be no pagination instance on the collection.

//UserController.php

<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;

class UserController extends Controller
{
    /**
     * Display a listing of the resource.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        $users = User::paginate(5);
        return view('users.index', ['users' => $users]);
    }
}

Our index.blade.php file that the index method points to include the HTML structure. I have use the full HTML structure, but you can sliced it it different layouts and partials.

<!DOCTYPE html>
<html lang="en">

<head>
    <title>Kodementor</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>

    <link href="{{ asset('css/style.css') }}">

</head>

<body>

    <div class="jumbotron text-center">
        <h1>Kodementor Demo Tutorials</h1>
        <p>List of users!!!</p>
    </div>

    <div class="container">

        
<div class="table-responsive">
    <table class="table table-bordered">
        <thead>
            <tr>
                <th>SN</th>
                <th>Name</th>
                <th>Email</th>
            </tr>
        </thead>
        <tbody>
            @foreach  ($users as $user)
                <tr>
                    <td>{{$user->id }}</td>
                    <td>{{ $user->name }}</td>
                    <td>{{ $user->email }}</td>
                </tr>
            @endforeach
        </tbody>
    </table>
    {{ $users->links('vendor.pagination.custom') }}  // <<== note here

</div>

    </div>

</body>

</html>

Note that we need to pass the newly created custom pagination file path for the use. Lastly, we need CSS to style our pagination lists.

<style>

a{
    text-decoration: none;
  }

  .pagination{
    padding: 30px 0;
  }

  .pagination ul{
    margin: 0;
    padding: 0;
    list-style-type: none;
  }

  .pagination a{
    display: inline-block;
    padding: 10px 18px;
    color: #222;
  }

  .p12 a:first-of-type, .p12 a:last-of-type, .p12 .is-active{
    background-color: #2ecc71;
    color: #fff;
    font-weight: bold;
  }

</style>

For each pagination you use, you need to give the path to the file. However, we can set the new layout as default pagination. For this, we need to add path with static method inside boot method in AppServiceProvider.

//AppServiceProvider

<?php

namespace App\Providers;

use Illuminate\Pagination\Paginator; //import this
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        Paginator::defaultView('vendor.pagination.custom'); //add this
    }
}

Tada!!! our new pagination system with custom layout is ready.

Read More Articles

LEAVE A REPLY

Please enter your comment!
Please enter your name here

This site uses Akismet to reduce spam. Learn how your comment data is processed.