【问题标题】:Limit amount of links shown with Laravel pagination限制 Laravel 分页显示的链接数量
【发布时间】:2015-02-23 16:46:07
【问题描述】:

有什么简单的方法可以限制 Laravel 分页显示的链接数量?

目前最多显示13个链接(Prev, 1 2 3 4 5 7 8 .. 78 79 next)

然而,这对于移动设备来说太多了,变成了两行导航......有没有办法将链接设置为例如只显示 10 个?

我搞砸了分页演示器,但实际上似乎没有任何效果。

谢谢

【问题讨论】:

标签: php laravel pagination


【解决方案1】:

我使用 css 来限制我允许的链接。真的很简单。。 这可以扩展为在任意数量的断点处显示任意数量的页面

@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;
    }
}

这个特定的实现允许箭头、'...'、第一页、活动页和最后一页

【讨论】:

  • 谢谢!你的答案加上developer.mozilla.org/en-US/docs/Web/CSS/… 就是我想要的。
  • 这是一个好方法,因为我想在桌面视图上保留更多页面链接,并且只限制它们用于移动设备。
  • 这是一个很好的解决方案。它适用于 Laravel 8,它现在支持 onEachSide 方法,但即使您将其设置为 1,它对于移动设备也是不够的。我在这个答案中看到的唯一问题是,例如,当您在第 4 页时,它没有显示左侧的 ... 。在这种情况下,它会显示:1、2、4、...、19、20。这是因为 Laravel 生成代码的方式。
  • 我还添加了这两个以显示更多元素:.page-item:nth-child(3), .page-item:nth-last-child(3),
  • 如果要在活动页面后显示下一个数字添加.page-item.active + li, 到选择器列表
【解决方案2】:

现在 Laravel 5.7 有一个新的分页方法来自定义分页器每一侧的链接数量。感谢新方法,在某些情况下您不再需要自定义分页视图。这是您可以用来定义当前页面每一侧的链接计数的 API:

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

在您的控制器上编写该代码。

您可以在https://laravel-news.com/laravel-5-7-pagination-link-customizations查看更多详细信息

【讨论】:

  • 似乎在 laravel 6 stackoverflow.com/questions/58521413/…987654322@中没有按预期工作
  • 谢谢!为我工作。我写了这个:$blog = Blog::where('type', "news")->latest('created_at')->paginate(5)->onEachSide(1); 我使用了 onEachSide(1)。这使得链接保持在每个设备的宽度范围内。
  • @calin24 在 Laravel 6 上使用 $collection->render() 时它对我不起作用,但在使用 $collection->onEachSide(1)->links() 时它对我有用
  • 我在 Laravel 8 Bootstrap 分页中使用了{{ $detail_data->onEachSide(3)->links() }},但它不起作用。它显示超过 15 个页面链接按钮。请帮我解决这个问题。我参考了laravel.com/docs/8.x/…官方文档。
  • @HarshPatel 如果您打开一个新的stackoverflow问题并显示相关代码,可能会更容易回答:)
【解决方案3】:

对于 Laravel 5.6+

发布供应商模板:

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

编辑bootstrap-4.blade.php如下:

@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

此示例以正确的方式处理新的 CSS 类、活动链接、三个点(正确,不是 1..2 3 4)以及是否可自定义(您要显示的页面数)。

Example

Three dots handled correctly

【讨论】:

    【解决方案4】:

    From laravel 8 docs。如果需要,您可以使用刀片中的onEachSide 方法控制在当前页面的每一侧显示多少附加链接:

    {{ $posts->onEachSide(1)->links() }}
    

    【讨论】:

      【解决方案5】:

      我创建了一个新的自定义演示者,只显示 10 个链接。它涉及三个步骤:

      创建您自己的自定义演示者

      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();
              }
          }
      
      } 
      

      创建您自己的分页视图(例如 custom-paginator.php),放置在您的 views 文件夹中

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

      更新您的 app/config.view.php

      'pagination' => 'custom-paginator',
      

      通过进行以下更改,您将能够获得 10 个链接的分页器。

      希望有帮助:D

      【讨论】:

      • 感谢 Henrik & hakre 的反馈,我已经用示例答案更新了我的答案。将来会改进我的回答方式:D我想发布一张图片截图但没有足够的声誉>_
      【解决方案6】:

      使用以下代码在视图文件夹的新分页文件夹中创建一个文件 default.blade.php。这意味着您已经使用我们的新分页文件覆盖了核心分页文件。这将对分页链接设置一些限制。

      @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
      

      然后你想在哪里获得分页然后你必须使用这个视图文件参数调用 laravel 分页函数。

       $data->links('pagination.default')
      

      【讨论】:

        【解决方案7】:

        我知道这是一个老问题,但仍然无法设置使用函数 links() 参数。我制作了简单的 jQuery 代码,也许它会对某人有所帮助。这比 Zesky 的回答要简单得多。我不是说更好,只是更简单:)

        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;
            }
        }
        

        此代码仅显示几个 li 元素。活动,两个之前,两个之后,上一个/下一个箭头。这使得最多只有 7 个可见元素,而不是 15 个。

        【讨论】:

        【解决方案8】:

        定义自定义演示者的旧方法不适用于 Laravel 5.3+,显示的链接数量似乎是硬编码在Illuminate/Pagination/UrlWindow::make()$onEachSide 参数中:

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

        我最终只是编写了自己的 render() 函数,从 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();
            }
        }
        

        我们使用 Twig,所以我将它注册为 Twig 过滤器,我想可以为 Blade 做类似的事情。

        【讨论】:

        • 这是正确的答案,除了在 Larvel 5.6 中,默认变量 $onEachSide = 3 位于 Illuminate\Pagination\UrlWindow::get($onEachSide = 3){ // }。它也可以在 Illuminate\Pagination\LengthAwarePaginator::elements() 函数中设置,它被称为$window = UrlWindow::make($this);,只需像这样传入第二个变量$window = UrlWindow::make($this, 1);
        • @barryp - 您能否通过示例文件提供更多信息?答案对于新手来说很难理解。
        • @KM - 该示例适用于不再适用的旧版本的 Laravel。请参阅下面使用分页器的 onEachSide(n) 方法的答案。
        • @barryp - 我正在为旧版本的 Laravel 寻找解决方案。
        【解决方案9】:

        我的表格太窄了,所以我决定用 jQuery filter() 只显示分页的第一个和最后一个 li(下一个和后退箭头)。您可以进一步自定义。

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

        一定要在body标签结束前添加。

        【讨论】:

          【解决方案10】:

          这是一个老问题,但我想分享一下我最近如何减少 Laravel 5.2 应用程序中的分页链接数量:

          在你的ViewServiceProvider

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

          应用\分页\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);
              }
          }
          

          发件人:

          收件人:

          【讨论】:

            【解决方案11】:

            有很多方法可以解决它,具体取决于您希望它的行为方式。

            出于我的需要,我想要一个快速的解决方案来缩短它,这样它就不会破坏我的移动布局。

            Laravel 5.3

            编辑此文件:(或您在分页器调用中使用的文件)

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

            我在 2 个链接之后添加了一行以打破链接呈现循环。

            {{-- 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
            

            【讨论】:

            • 这个真的又快又实用,我在Laravel 5.7测试过
            • 您不应该更改 /vendor 目录中的文件。
            【解决方案12】:

            这是一个较老的问题,但这里的答案都不是最新的 Laravel 文档。对于较新版本的 Laravel(Laravel 5.6+),这个问题有一些简单的解决方法,但它确实需要发布供应商分页视图,如 Laravel Documentation。假设您尚未发布或更改默认分页视图,您运行的命令是:

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

            视图发布后,您将在 resources/views/vendor/pagination 目录中找到 bootstrap-4.blade.php。您可以编辑此文件并根据需要显示分页链接。为了减少默认显示的链接数,我简单地用了一点inline php设置索引,限制显示的链接数,如下图:

            {{-- 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
            

            大部分代码在 bootstrap-4.blade.php 的默认刀片视图中,但我添加了 $index=0, $index

            这是根据 Laravel 文档处理此问题的正确方法,无需编辑作曲家供应商文件,或尝试以其他方式破解系统。我确实意识到 JR Lawhorne 发布了类似的答案,但它不包括在发布之前发布供应商文件的整个过程。希望这对其他人有所帮助。

            【讨论】:

            • 这个比onEachSide(1)好一点。
            猜你喜欢
            • 1970-01-01
            • 2011-07-09
            • 2015-11-07
            • 1970-01-01
            • 2013-01-22
            • 2021-11-02
            • 2013-06-13
            • 2021-03-27
            • 1970-01-01
            相关资源
            最近更新 更多