Pagination not work

What seems to be the problem:
I have done everything as in the documentations but pagination don’t work at all even wire:click seems has no action

Steps to Reproduce:
Form web.php
Route::get( 'show-by-categories/{name}', [ ProductCategory::class, 'render' ] )->name( 'show.by.categories' );

Livewire\Component
use Livewire\WithPagination;

class ProductCategory extends Component {
    use WithPagination;

    public function render( $name ) {
        $mainCategory = Category::whereTranslation( 'name', $name )->first();
        $subCategory  = ProductSubCategory::whereProductCategoryId( $mainCategory->id );

        return view( 'livewire.customer-product.category.product-category', [
            'subCategories' => $subCategory->paginate( 1 ),
            'mainCategory'  => $mainCategory
        ] );
    }

}

Here is the product_category.blade

@foreach($subCategories as $subCategory)
                                                        <div class="col-xl-2 col-lg-3 col-md-4 col-6 col-grid-box">
                                                            <div class="product">
                                                                <div class="product-box">
                                                                    <div class="product-imgbox">
                                                                        <div class="product-front">
                                                                            <a href="#">
                                                                                {!! Html::image('images/productSubCategories/'.$subCategory->image, $subCategory->name, ['class'=>'img-fluid']) !!}
                                                                                <div
                                                                                    class="categoryLabels">{{ $subCategory->name }}</div>
                                                                            </a>
                                                                        </div>
                                                                    </div>
                                                                </div>
                                                            </div>
                                                        </div>
                                                    @endforeach
                                                </div>
                                            </div>

{{ $subCategories->links('vendor.pagination.customTemplatePagination') }}

and here is my custom pagination

<div class="col-xl-6 col-md-6 col-sm-12">
                    @if ($paginator->lastPage() > 1)
                        <nav aria-label="Page navigation">
                            <ul class="pagination">
                                <li class="page-item {{ ($paginator->currentPage() == 1) ? ' disabled' : '' }}">
                                    <a class="page-link" href="{{ $paginator->previousPageUrl() }}" wire:click="previousPage">
                                        <span aria-hidden="true"><i class="fas fa-chevron-left" aria-hidden="true"></i>
                                        </span>
                                        <span class="sr-only">Previous</span>
                                    </a>
                                </li>
                                @for ($i = 1; $i <= $paginator->lastPage(); $i++)
                                    <li class="page-item {{ ($paginator->currentPage() == $i) ? ' active' : '' }}">
                                        <a class="page-link" href="{{ $paginator->url($i) }}">{{ $i }}</a>
                                    </li>
                                @endfor
                                <li class="page-item {{ ($paginator->currentPage() == $paginator->lastPage()) ? ' disabled' : '' }}">
                                    <button  class="page-link" wire:click="nextPage">Next</button>
                                </li>
                            </ul>
                        </nav>
                    @endif
                </div>

Are you using the latest version of Livewire:
Yes using latest version of Livewire 2
Do you have any screenshots or code examples: No

It sounds like a Dom Diffing Issue check out https://laravel-livewire.com/docs/2.x/troubleshooting

Hey, @Pom

Make sure the livewire assets/config is published by:

php artisan livewire:publish --config
php artisan livewire:publish --assets

And the Assets is included in your blade file.

<html>
<head>
    ...
    @livewireStyles
</head>
<body>
    ...
    @livewireScripts
</body>
</html>

Or you can refer to this thread.

@skywalker

Yes I did

php artisan livewire:publish --config
php artisan livewire:publish --assets

and of course

@livewireStyles
@livewireScripts

and the the login-customer works fine. this means the livewire is working.

@Pom yes I saw this part but I didn’t understand how to debug with it.

Any errors in the console?

@skywalker no this is what makes me confused.

Try with default pagination template shipped with livewire and test if it works

@if ($paginator->hasPages())
    <nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
        {{-- Previous Page Link --}}
        @if ($paginator->onFirstPage())
            <span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
                {!! __('pagination.previous') !!}
            </span>
        @else
            <a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                {!! __('pagination.previous') !!}
            </a>
        @endif

        {{-- Next Page Link --}}
        @if ($paginator->hasMorePages())
            <a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:shadow-outline-blue focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
                {!! __('pagination.next') !!}
            </a>
        @else
            <span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
                {!! __('pagination.next') !!}
            </span>
        @endif
    </nav>
@endif

@skywalker Yes I did this too, but this refresh the page when click next.

@for ($i = 1; $i <= $paginator->lastPage(); $i++)
    <li class="page-item {{ ($paginator->currentPage() == $i) ? ' active' : '' }}">
        <a wire:key="paginator-page{{ $i }}" 
            wire:click="gotoPage({{ $i }})"
            class="page-link" href="{{ $paginator->url($i) }}">{{ $i }}</a>
    </li>
@endfor

Aha! Make sure you are implementing <livewire:scripts> in your page because most of the time this is the issue.

See the Page source and check if the livewire script is implemented correctly

@skywalker in the same page I have the following copied from source page.

<!-- Livewire Styles -->
<style>
    [wire\:loading], [wire\:loading\.delay], [wire\:loading\.inline-block], [wire\:loading\.inline], [wire\:loading\.block], [wire\:loading\.flex], [wire\:loading\.table], [wire\:loading\.grid] {
        display: none;
    }

    [wire\:offline] {
        display: none;
    }

    [wire\:dirty]:not(textarea):not(input):not(select) {
        display: none;
    }

    input:-webkit-autofill, select:-webkit-autofill, textarea:-webkit-autofill {
        animation-duration: 50000s;
        animation-name: livewireautofill;
    }

    @keyframes livewireautofill { from {} }
</style>   

and in footer

<!-- Livewire Scripts -->

<script src="/vendor/livewire/livewire.js?id=eb510e851dceb24afd36" data-turbolinks-eval="false"></script>
<script data-turbolinks-eval="false">
    if (window.livewire) {
        console.warn('Livewire: It looks like Livewire\'s @livewireScripts JavaScript assets have already been loaded. Make sure you aren\'t loading them twice.')
    }

    window.livewire = new Livewire();
    window.livewire.devTools(true);
    window.Livewire = window.livewire;
    window.livewire_app_url = '';
    window.livewire_token = 'wrZu89y4vdGBhEyGrSSDuAtx1A9ymzbk0EUz66Co';

    /* Make sure Livewire loads first. */
    if (window.Alpine) {
        /* Defer showing the warning so it doesn't get buried under downstream errors. */
        document.addEventListener("DOMContentLoaded", function () {
            setTimeout(function() {
                console.warn("Livewire: It looks like AlpineJS has already been loaded. Make sure Livewire\'s scripts are loaded before Alpine.\n\n Reference docs for more info: http://laravel-livewire.com/docs/alpine-js")
            })
        });
    }

    /* Make Alpine wait until Livewire is finished rendering to do its thing. */
    window.deferLoadingAlpine = function (callback) {
        window.addEventListener('livewire:load', function () {
            callback();
        });
    };

    document.addEventListener("DOMContentLoaded", function () {
        window.livewire.start();
    });
</script>

Try to remove turbo links and all scripts related and try again.

Try to debug your code line by line

@Pom something strange happens when try to click on next after adding your code it fetches the login function.

fetch("http://localhost:8000/livewire/message/customer-auth.login-customer", {
  "headers": {
    "accept": "text/html, application/xhtml+xml",
    "accept-language": "en-US,en;q=0.9,ar;q=0.8",
    "cache-control": "no-cache",
    "content-type": "application/json",
    "pragma": "no-cache",
    "sec-ch-ua": "\"Google Chrome\";v=\"87\", \" Not;A Brand\";v=\"99\", \"Chromium\";v=\"87\"",
    "sec-ch-ua-mobile": "?0",
    "sec-fetch-dest": "empty",
    "sec-fetch-mode": "cors",
    "sec-fetch-site": "same-origin",
    "x-csrf-token": "wrZu89y4vdGBhEyGrSSDuAtx1A9ymzbk0EUz66Co",
    "x-livewire": "true",
    "x-socket-id": "undefined"
  },
  "referrer": "http://localhost:8000/en/show-by-categories/Clothes?page=2",
  "referrerPolicy": "strict-origin-when-cross-origin",
  "body": "{\"fingerprint\":{\"id\":\"Y1YCcLABOvn4nyX3QZ4e\",\"name\":\"customer-auth.login-customer\",\"locale\":\"en\"},\"serverMemo\":{\"children\":[],\"errors\":[],\"htmlHash\":\"218d2cf5\",\"data\":{\"email\":\"\",\"password\":\"\"},\"dataMeta\":[],\"checksum\":\"9090ae9d86a757766997370a651418ae0de28470ca4cafe4a7b732660d676589\"},\"updates\":[{\"type\":\"syncInput\",\"payload\":{\"name\":\"email\",\"value\":\"[email protected]\"}},{\"type\":\"syncInput\",\"payload\":{\"name\":\"password\",\"value\":\"******"}}]}",
  "method": "POST",
  "mode": "cors",
  "credentials": "include"
});

See if this works:

<div>
    @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">
                        <button type="button" dusk="previousPage" class="page-link" wire:click="previousPage" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</button>
                    </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" wire:key="paginator-page-{{ $page }}" aria-current="page"><span class="page-link">{{ $page }}</span></li>
                            @else
                                <li class="page-item" wire:key="paginator-page-{{ $page }}"><button type="button" class="page-link" wire:click="gotoPage({{ $page }})">{{ $page }}</button></li>
                            @endif
                        @endforeach
                    @endif
                @endforeach

                {{-- Next Page Link --}}
                @if ($paginator->hasMorePages())
                    <li class="page-item">
                        <button type="button" dusk="nextPage" class="page-link" wire:click="nextPage" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</button>
                    </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
</div>
1 Like

Oh you mean this

<script data-turbolinks-eval="false">
    if (window.livewire) {

it comes by default with livewire.

@pom sorry to say it didn’t work, the all issue is this wire:key="paginator-page-2" has no action?!

even try new fresh laravel without anything just empty project and still not working.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel</title>

    <!-- Fonts -->
    <link href="https://fonts.googleapis.com/css2?family=Nunito:wght@400;600;700&display=swap" rel="stylesheet">

    <!-- Styles -->
    <!-- Livewire Styles -->
<style>
    [wire\:loading], [wire\:loading\.delay], [wire\:loading\.inline-block], [wire\:loading\.inline], [wire\:loading\.block], [wire\:loading\.flex], [wire\:loading\.table], [wire\:loading\.grid] {
        display: none;
    }

    [wire\:offline] {
        display: none;
    }

    [wire\:dirty]:not(textarea):not(input):not(select) {
        display: none;
    }

    input:-webkit-autofill, select:-webkit-autofill, textarea:-webkit-autofill {
        animation-duration: 50000s;
        animation-name: livewireautofill;
    }

    @keyframes livewireautofill { from {} }
</style>
</head>
<body class="antialiased">
<div>
            <div class="col-xl-2 col-lg-3 col-md-4 col-6 col-grid-box">
            <div class="product">
                <div class="product-box">
                    <div class="product-imgbox">
                        <div class="product-front">
                            <a href="#">
                                <div class="categoryLabels">Here what</div>
                            </a>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div>
            <nav>
            <ul class="pagination">
                
                                    <li class="page-item disabled" aria-disabled="true" aria-label="&laquo; Previous">
                        <span class="page-link" aria-hidden="true">&lsaquo;</span>
                    </li>
                
                
                                    
                    
                    
                                                                                                        <li class="page-item active" wire:key="paginator-page-1" aria-current="page"><span class="page-link">1</span></li>
                                                                                                                <li class="page-item" wire:key="paginator-page-2"><button type="button" class="page-link" wire:click="gotoPage(2)">2</button></li>
                                                                                        
                
                                    <li class="page-item">
                        <button type="button" dusk="nextPage" class="page-link" wire:click="nextPage" rel="next" aria-label="Next &raquo;">&rsaquo;</button>
                    </li>
                            </ul>
        </nav>
    </div>

</div>

<!-- Livewire Scripts -->

<script src="/livewire/livewire.js?id=eb510e851dceb24afd36" data-turbolinks-eval="false"></script>
<script data-turbolinks-eval="false">
    if (window.livewire) {
        console.warn('Livewire: It looks like Livewire\'s @livewireScripts JavaScript assets have already been loaded. Make sure you aren\'t loading them twice.')
    }

    window.livewire = new Livewire();
    window.livewire.devTools(true);
    window.Livewire = window.livewire;
    window.livewire_app_url = '';
    window.livewire_token = 'uWpns3ezRuiu7qwOS4yaXPNc8c4PRmm1CGqTAmko';

    /* Make sure Livewire loads first. */
    if (window.Alpine) {
        /* Defer showing the warning so it doesn't get buried under downstream errors. */
        document.addEventListener("DOMContentLoaded", function () {
            setTimeout(function() {
                console.warn("Livewire: It looks like AlpineJS has already been loaded. Make sure Livewire\'s scripts are loaded before Alpine.\n\n Reference docs for more info: http://laravel-livewire.com/docs/alpine-js")
            })
        });
    }

    /* Make Alpine wait until Livewire is finished rendering to do its thing. */
    window.deferLoadingAlpine = function (callback) {
        window.addEventListener('livewire:load', function () {
            callback();
        });
    };

    document.addEventListener("DOMContentLoaded", function () {
        window.livewire.start();
    });
</script>
</body>
</html>

dear @Pom and @skywalker it was all my mistake I shouldn’t point to render directly from my route I made new blade file called product-category and I called the components into it like so
<livewire:customer-product.category.product-category :name="$name"/> and it worked fine.

Thanks for your efforts with me trying to solve the issue with me. :heart:

1 Like

OH! Glade to hear that.

I’m happy for you, that you solved your issue by your own :wink:

Happy coding mate.

1 Like