Posts Learn Components Snippets Categories Tags Tools About
/

Laravel Get Previous And Next Records Sorted By Name (Livewire Component)

Learn how to get the previous and next records in Laravel using the record name or title to display links on the front-end to allow users to navigate easily

2 years ago

10 mins read

6783 views

In this post, you will learn how to get previous and next records in Laravel by using the record's name sorted in ascending or descending order. In our other post Getting previous and next record in Laravel, we have guided you on how to get the "previous" and "next" by using the "record ID" and columns that have a "number" value but in this post, you will learn the other approach.

Step 1: Define the Column To Sort By


Firstly you have to define the column to be used for sorting. For example, do imagine a "Post" eloquent model that has a "Title" column or an "Article" eloquent model that has a "Name" column and sort it in ascending order.
<?php

// If you are using "Post" model then your code should be as follows
$posts = Post::query()->sortBy('title', 'asc')->get();

// Or if you are using Article model then sort it by the "name" column
$articles = Article::query()->sortBy('name', 'asc')->get();
In a real-world scenario, you might also want to select only the one that's published and only select the columns that are necessary.
<?php

$posts = Post::query()
    ->select(['id', 'title', 'body'])
    ->sortBy('title', 'asc')
    ->whereNotNull('published_at')
    ->get();

Step 2: Define Previous and Next Logic


The next step is to define the logic to get the previous and next posts. The important part is to find the logic to get the location of the "index" from the collection of posts. To achieve this, you need to compare the existing post against the current Post collection. This location of this code should be in the "Show" method of your PostController.
<?php // PostController

public function show(Post $post)
{
    /* Collection of posts */
    $posts = Post::query()
        ->select(['id', 'title', 'body'])
        ->sortBy('title', 'asc')
        ->whereNotNull('published_at')
        ->get();

    $index = $posts->search(fn ($post) => $post->name === $post->name);

    /* Retrieve Previous and Next Post */
    $prevPost = ($theIndex = ($index - 1)) >= 0 ? $posts[$theIndex] : null;

    $nextPost = ($theIndex = ($index + 1)) < count($posts) ? $posts[$theIndex] : null;

    return view('posts.show', compact('post', 'prevPost', 'nextPost'));
}
The code logic above will retrieve the previous post and next post by using the post index we retrieved earlier using the "search" method available from the Laravel Collection instance. Since the "posts" is accessible using the array notation you can call it like the following "$posts[$theIndex]".

Step 3: Create Laravel Livewire Component


Now that you have retrieved the previous and next post, you can then display it on the front-end blade template. In this case, you can create a Laravel Livewire component to make it reusable across the application. To create the Laravel Livewire component, do run the command below. If you have not installed it, do make sure to check this getting started guide from the official Laravel Livewire website.
php artisan livewire:make components/prev-next
The command above will output the following in the terminal.
COMPONENT CREATED 🤙

CLASS: app/Http/Livewire/Components/PrevNext.php
VIEW:  resources/views/livewire/components/prev-next.blade.php
From the PrevNext component class, you can define the required properties that can be passed on to the component. Do refer to the code below for the full implementation.
<?php

namespace App\Http\Livewire\Components;

use Livewire\Component;

class PrevNext extends Component
{
    public $prevLabel;

    public $nextLabel;

    public $prevTitle;

    public $nextTitle;

    public $prevUrl;

    public $nextUrl;

    public function render()
    {
        return view('livewire.components.prev-next');
    }
}
Now from the "prev-next" blade component, you can define navigation links. I have placed multiple checks for the previous and next variables and it will facilitate all the necessary conditions.
<div class="grid grid-cols-1 {{ isset($prevTitle, $nextTitle) ? 'md:grid-cols-2' : null }} gap-4">
    @isset($prevTitle)
        <a
            class="card flex flex-col"
            href="{{ $prevUrl }}"
            title="{{ $prevTitle }}"
        >
            <div class="flex items-center">
                <svg class="w-3 h-auto fill-current text-gray-400 mr-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512">
                    <path d="M166.5 424.5l-143.1-152c-4.375-4.625-6.562-10.56-6.562-16.5c0-5.938 2.188-11.88 6.562-16.5l143.1-152c9.125-9.625 24.31-10.03 33.93-.9375c9.688 9.125 10.03 24.38 .9375 33.94l-128.4 135.5l128.4 135.5c9.094 9.562 8.75 24.75-.9375 33.94C190.9 434.5 175.7 434.1 166.5 424.5z"/>
                </svg>

                <span class="uppercase font-semibold text-sm text-gray-400">
                    {{ $prevLabel }}
                </span>
            </div>

            <p class="mt-1 line-clamp-1 text-gray-700 dark:text-gray-400">
                {{ $prevTitle }}
            </p>
        </a>
    @endisset

    @isset($nextTitle)
        <a
            href="{{ $nextUrl }}"
            class="card flex flex-col"
            title="{{ $nextTitle }}"
        >
            <div class="flex items-center justify-end">
                <span class="uppercase font-semibold text-sm text-gray-400">
                    {{ $nextLabel }}
                </span>

                <svg class="w-3 h-auto fill-current text-gray-400 ml-2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 256 512">
                    <path d="M89.45 87.5l143.1 152c4.375 4.625 6.562 10.56 6.562 16.5c0 5.937-2.188 11.87-6.562 16.5l-143.1 152C80.33 434.1 65.14 434.5 55.52 425.4c-9.688-9.125-10.03-24.38-.9375-33.94l128.4-135.5l-128.4-135.5C45.49 110.9 45.83 95.75 55.52 86.56C65.14 77.47 80.33 77.87 89.45 87.5z"/>
                </svg>
            </div>

            <p class="mt-1 line-clamp-1 text-gray-700 dark:text-gray-400">
                {{ $nextTitle }}
            </p>
        </a>
    @endisset
</div>

Display Previous and Next Post on Front-end


Now that you have defined the component, you can call it from anywhere within your Laravel project using the "livewire:components.prev-next" tag.
<livewire:components.prev-next
    prevLabel="Prev Post"
    nextLabel="Next Post"
    :prevTitle="optional($prevPost)->title"
    :nextTitle="optional($nextPost)->title"
    :prevUrl="$prevPost ? route('posts.show', ['slug' => $prevPost->slug]) : null"
    :nextUrl="$nextPost ? route('posts.show', ['slug' => $nextPost->slug]) : null"
/>
Below is the preview of the implementation in PostSrc and you can check it all across the Posts and Code Snippets section.
PostSrc Previous and Next Post


PostSrc Previous and Next Code Snippets

By now you should be able to Get Prev And Next Records Sorted By Name and create custom Laravel Livewire components to make it reusable across the application. If you find this tutorial helpful do make sure to share it with your friends and cheers, happy coding! 

Other Reads

Alternative Tags

If you like our tutorial, do make sure to support us by being our Patreon or buy us some coffee ☕️

)