web-dev-qa-db-fra.com

Limiter le nombre de liens affichés avec Laravel pagination

Un moyen facile de limiter le nombre de liens affichés avec la pagination Laravels?

Actuellement, il affiche 13 liens au plus (Précédent, 1 2 3 4 5 7 8 .. 78 79 suivant)

C’est toutefois trop pour les appareils mobiles et devient une navigation sur deux lignes ... existe-t-il un moyen de définir les liens, par exemple, montrer seulement 10?

J'ai joué avec le présentateur de la pagination, mais rien ne semblait réellement fonctionner.

Merci

16
Lovelock

L'ancienne façon de définir un présentateur personnalisé ne fonctionnait pas avec Laravel 5.3+, le nombre de liens affichés semblait être codé en dur dans le paramètre $onEachSide de Illuminate/Pagination/UrlWindow::make():

public static function make(PaginatorContract $paginator, $onEachSide = 3)

J'ai fini par écrire ma propre fonction render (), en volant du code de LengthAwarePaginator

/**
 * Stole come code from LengthAwarePaginator::render() and ::elements() to allow for a smaller UrlWindow
 *
 * @param LengthAwarePaginator $paginator
 * @param int $onEachSide
 * @return string
 */
public static function render(LengthAwarePaginator $paginator, $onEachSide = 2)
{
    $window = UrlWindow::make($paginator, $onEachSide);

    $elements = array_filter([
        $window['first'],
        is_array($window['slider']) ? '...' : null,
        $window['slider'],
        is_array($window['last']) ? '...' : null,
        $window['last'],
    ]);

    return LengthAwarePaginator::viewFactory()->make(LengthAwarePaginator::$defaultView, [
        'paginator' => $paginator,
        'elements' => $elements,
    ])->render();
}

}

Nous utilisons Twig, alors j’ai enregistré cela en tant que filtre Twig. J'imagine que quelque chose de similaire pourrait être fait pour Blade.

1
barryp

J'avais créé un nouveau présentateur personnalisé pour ne montrer que 10 liens. Il comporte 3 étapes:

Créez votre propre présentateur personnalisé

use Illuminate\Pagination\BootstrapPresenter;

class CustomPresenter extends BootstrapPresenter{
    protected function getPageSlider()
    {
        // Changing the original value from 6 to 3 to reduce the link count
        $window = 3;

        // If the current page is very close to the beginning of the page range, we will
        // just render the beginning of the page range, followed by the last 2 of the
        // links in this list, since we will not have room to create a full slider.
        if ($this->currentPage <= $window)
        {
            $ending = $this->getFinish();

            return $this->getPageRange(1, $window + 2).$ending;
        }

        // If the current page is close to the ending of the page range we will just get
        // this first couple pages, followed by a larger window of these ending pages
        // since we're too close to the end of the list to create a full on slider.
        elseif ($this->currentPage >= $this->lastPage - $window)
        {
            $start = $this->lastPage - 8;

            $content = $this->getPageRange($start, $this->lastPage);

            return $this->getStart().$content;
        }

        // If we have enough room on both sides of the current page to build a slider we
        // will surround it with both the beginning and ending caps, with this window
        // of pages in the middle providing a Google style sliding paginator setup.
        else
        {
            $content = $this->getAdjacentRange();

            return $this->getStart().$content.$this->getFinish();
        }
    }

} 

Créez votre propre vue de pagination (par exemple, custom-paginator.php), placez-la dans votre dossier views

<ul class="pagination">
    <?php echo with(new CustomPresenter($paginator))->render(); ?>
</ul>

Mettez à jour votre app/config.view.php

'pagination' => 'custom-paginator',

En apportant les modifications suivantes, vous pourrez obtenir un paginateur de 10 liens. 

J'espère que cette aide: D

5
Zesky

Je sais que c’est une vieille question, mais il n’existe toujours aucun moyen de configurer les paramètres function links (). J'ai créé un code jQuery simple, cela aidera peut-être quelqu'un. C'est beaucoup plus simple que la réponse de Zesky. Je ne veux pas dire mieux, juste plus simple :)

JavaScript:

(function($) {
    $('ul.pagination li.active')
        .prev().addClass('show-mobile')
        .prev().addClass('show-mobile');
    $('ul.pagination li.active')
        .next().addClass('show-mobile')
        .next().addClass('show-mobile');
    $('ul.pagination')
        .find('li:first-child, li:last-child, li.active')
        .addClass('show-mobile');
})(jQuery);

CSS:

@media (max-width: /* write what you need, for me it's 560px */) {
    ul.pagination li:not(.show-mobile) {
        display: none;
    }
}

Ce code ne rend visible que quelques éléments li. Actif, deux avant, deux après, flèches précédente/suivante. Cela ne fait que 7 éléments visibles au maximum au lieu de 15.

3
ElChupacabra

Pour Laravel 5.6+

Publier le modèle de fournisseur:

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

Éditez bootstrap-4.blade.php comme suit:

@if ($paginator->hasPages())
<ul class="pagination" role="navigation">
    {{-- 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="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
        </li>
    @endif

    <?php
        $start = $paginator->currentPage() - 2; // show 3 pagination links before current
        $end = $paginator->currentPage() + 2; // show 3 pagination links after current
        if($start < 1) {
            $start = 1; // reset start to 1
            $end += 1;
        } 
        if($end >= $paginator->lastPage() ) $end = $paginator->lastPage(); // reset end to last page
    ?>

    @if($start > 1)
        <li class="page-item">
            <a class="page-link" href="{{ $paginator->url(1) }}">{{1}}</a>
        </li>
        @if($paginator->currentPage() != 4)
            {{-- "Three Dots" Separator --}}
            <li class="page-item disabled" aria-disabled="true"><span class="page-link">...</span></li>
        @endif
    @endif
        @for ($i = $start; $i <= $end; $i++)
            <li class="page-item {{ ($paginator->currentPage() == $i) ? ' active' : '' }}">
                <a class="page-link" href="{{ $paginator->url($i) }}">{{$i}}</a>
            </li>
        @endfor
    @if($end < $paginator->lastPage())
        @if($paginator->currentPage() + 3 != $paginator->lastPage())
            {{-- "Three Dots" Separator --}}
            <li class="page-item disabled" aria-disabled="true"><span class="page-link">...</span></li>
        @endif
        <li class="page-item">
            <a class="page-link" href="{{ $paginator->url($paginator->lastPage()) }}">{{$paginator->lastPage()}}</a>
        </li>
    @endif

    {{-- Next Page Link --}}
    @if ($paginator->hasMorePages())
        <li class="page-item">
            <a class="page-link" href="{{ $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>
@endif

Cet exemple gère correctement les nouvelles classes CSS, le lien actif, trois points (correctement, pas 1..2 3 4) et est-il personnalisable (nombre de pages à afficher).

Exemple

Trois points gérés correctement

2
Jacopo Bernasconi

Il y a plusieurs façons de s'y prendre, en fonction de votre comportement.

Pour mes besoins, je voulais une solution rapide pour la raccourcir afin qu'elle ne casse pas la mise en page de mes mobiles.

Laravel 5.3

Éditez ce fichier: (ou celui que vous utilisez dans vos appels de paginateur)

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

J'ajoute une seule ligne pour sortir de la boucle de rendu de lien après 2 liens.

{{-- Array Of Links --}}
    @if (is_array($element))
        @foreach ($element as $page => $url)
             @if ($page == $paginator->currentPage())
                 <li class="page-item active"><span class="page-link">{{ $page }}</span></li>
              @else
                  <li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
                  {{--Add the line below to limit rendered links--}}
                  <?php if($loop->count > 2) break; ?>
              @endif
         @endforeach
     @endif
2
JR Lawhorne

J'ai utilisé css pour limiter les liens que je permettais. Vraiment simple. Ceci peut être étendu pour montrer n'importe quel nombre de pages, à n'importe quel nombre de points d'arrêt

@media screen and ( max-width: 400px ){

    li.page-item {

        display: none;
    }

    .page-item:first-child,
    .page-item:nth-child( 2 ),
    .page-item:nth-last-child( 2 ),
    .page-item:last-child,
    .page-item.active,
    .page-item.disabled {

        display: block;
    }
}

cette implémentation spécifique permet les flèches, le '...', la première page, la page active et la dernière page

1
Tyler Johnson

Maintenant Laravel 5.7 a une nouvelle méthode de pagination permettant de personnaliser le nombre de liens de chaque côté du paginateur. Grâce à la nouvelle méthode, dans certains cas, vous n'avez plus besoin d'une vue de pagination personnalisée. Voici l'API que vous pouvez utiliser pour définir le nombre de liens de chaque côté de la page en cours:

User::paginate(10)->onEachSide(2);

écrivez ce code sur votre contrôleur.

vous pouvez voir plus de détails à https://laravel-news.com/laravel-5-7-pagination-link-customizations

1
Abid Khairy

Ma table étant trop étroite, j'ai décidé de ne montrer que le premier et le dernier li (flèches Next et Back) de la pagination avec jQuery filter (). Vous pouvez personnaliser cela davantage.

$('ul.pagination li').hide().filter(':lt(1), :nth-last-child(1)').show();

Assurez-vous de l'ajouter avant la fin de la balise body.

1
Waqas Bukhary

Créez un fichier default.blade.php dans le nouveau dossier de pagination dans le dossier d'affichage avec le code ci-dessous. Cela signifie que vous devez remplacer le fichier de pagination principal par notre nouveau fichier de pagination. Cela établira une limite en lien de pagination.

@if ($paginator->hasPages())
    <ul class="pagination pagination">
        {{-- Previous Page Link --}}
        @if ($paginator->onFirstPage())
            <li class="disabled"><span>«</span></li>
        @else
            <li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">«</a></li>
        @endif

        @if($paginator->currentPage() > 3)
            <li class="hidden-xs"><a href="{{ $paginator->url(1) }}">1</a></li>
        @endif
        @if($paginator->currentPage() > 4)
            <li><span>...</span></li>
        @endif
        @foreach(range(1, $paginator->lastPage()) as $i)
            @if($i >= $paginator->currentPage() - 2 && $i <= $paginator->currentPage() + 2)
                @if ($i == $paginator->currentPage())
                    <li class="active"><span>{{ $i }}</span></li>
                @else
                    <li><a href="{{ $paginator->url($i) }}">{{ $i }}</a></li>
                @endif
            @endif
        @endforeach
        @if($paginator->currentPage() < $paginator->lastPage() - 3)
            <li><span>...</span></li>
        @endif
        @if($paginator->currentPage() < $paginator->lastPage() - 2)
            <li class="hidden-xs"><a href="{{ $paginator->url($paginator->lastPage()) }}">{{ $paginator->lastPage() }}</a></li>
        @endif

        {{-- Next Page Link --}}
        @if ($paginator->hasMorePages())
            <li><a href="{{ $paginator->nextPageUrl() }}" rel="next">»</a></li>
        @else
            <li class="disabled"><span>»</span></li>
        @endif
    </ul>
@endif

Ensuite, où vous souhaitez obtenir la pagination, vous devez appeler la fonction de pagination Laravel avec ce paramètre de fichier de vue. 

 $data->links('pagination.default')
1
Bhavin Thummar

C'est une vieille question, mais je pensais que je partagerais comment j'ai récemment réussi à réduire le nombre de liens de pagination dans un Laravel 5.2 application:

Dans votre ViewServiceProvider:

 \Illuminate\Pagination\AbstractPaginator::presenter(function($paginator) {
      return new \App\Pagination\BootstrapPresenter($paginator);
 });

App\Pagination\BootstrapPresenter.php

<?php namespace App\Pagination;

use Illuminate\Pagination\UrlWindow;
use Illuminate\Contracts\Pagination\Paginator as PaginatorContract;
use Illuminate\Pagination\BootstrapThreePresenter as LaravelBootstrapThreePresenter;

class BootstrapPresenter extends LaravelBootstrapThreePresenter
{
    /**
     * Create a new Bootstrap presenter instance.
     *
     * @param  \Illuminate\Contracts\Pagination\Paginator  $paginator
     * @param  \Illuminate\Pagination\UrlWindow|null  $window
     * @return void
     */
    public function __construct(PaginatorContract $paginator, UrlWindow $window = null)
    {
        $this->paginator = $paginator;

        // Make the pagination window smaller (default is 3).
        $this->window = UrlWindow::make($paginator, 1);
    }
}

De:

 enter image description here

À:

 enter image description here

1
Gary Green

C'est une question plus ancienne, mais aucune des réponses ici n'est à jour avec la dernière documentation Laravel. Pour les versions plus récentes de Laravel (Laravel 5.6+), il existe une solution assez simple à ce problème, mais il faut publier les vues de pagination des fournisseurs, comme indiqué dans Laravel Documentation . En supposant que vous n'ayez pas déjà publié ou modifié la vue de pagination par défaut, la commande que vous exécutez est la suivante:

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

Une fois les vues publiées, vous trouverez bootstrap-4.blade.php dans le répertoire resources/views/vendor/pagination. Vous pouvez éditer ce fichier et faire en sorte que les liens de pagination apparaissent comme vous le souhaitez. Afin de réduire le nombre de liens affichés par défaut, j'ai simplement utilisé un peu de php en ligne pour définir un index et limiter le nombre de liens à afficher, comme indiqué ci-dessous:

{{-- Array Of Links --}}
@if (is_array($element))
    <?php $index = 0; ?>
    @foreach ($element as $page => $url)
        @if($index<4)
            @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="{{ $url }}">{{ $page }}</a></li>
            @endif
        @endif
        <?php $index++ ?>
    @endforeach
@endif

La plupart de ce code est dans la vue par défaut de la lame pour bootstrap-4.blade.php, mais j'ai ajouté le code $ index = 0, $ index <4, $ index ++ code pour LIMITER le nombre de liens sur le côté gauche du paginateur. 4.

C’est la bonne façon de traiter ce problème conformément à la documentation de Laravel, sans éditer les fichiers du fabricant du compositeur ni essayer de pirater le système d’une autre manière. Je me rends bien compte que JR Lawhorne a posté une réponse similaire, mais elle n’inclut pas l’ensemble du processus de publication du fichier du fournisseur avant la publication. J'espère que cela aide les autres.

1
eResourcesInc