Laravel 5 - Manual pagination
Asked Answered
C

8

15

Pagination::make() method doesn't exist in Pagination class anymore in Laravel 5.

Is there a workaround to make manual pagination work in Laravel 5?

Calefacient answered 30/11, 2014 at 12:54 Comment(0)
R
32

You need to add use:

use Illuminate\Pagination\LengthAwarePaginator as Paginator;

and now you can use:

 $paginator = new Paginator($items, $count, $limit, $page, [
            'path'  => $this->request->url(),
            'query' => $this->request->query(),
        ]);

to get data in the same format as paginating on model object;

Redivivus answered 18/12, 2014 at 12:37 Comment(4)
Just to say (Laravel doc): When manually creating a paginator instance, you should manually "slice" the array of results you pass to the paginator.Ardellaardelle
Could you explain parameters please?Santee
The parameters are discussed over the construct method: laravel.com/api/5.0/Illuminate/Pagination/…Santee
how to render pages on the blade frontend then? thanksChaps
H
10

Example of using the Illuminate\Pagination\LengthAwarePaginator:

use Illuminate\Http\Request;
use Illuminate\Pagination\LengthAwarePaginator;

public function getItems(Request $request)
{
    $items = []; // get array/collection data from somewhere
    $paginator = $this->getPaginator($request, $items);

    // now we can treat $paginator as an array/collection
    return view('some-view')->with('items', $paginator);
}

private function getPaginator(Request $request, $items)
{
    $total = count($items); // total count of the set, this is necessary so the paginator will know the total pages to display
    $page = $request->page ?? 1; // get current page from the request, first page is null
    $perPage = 3; // how many items you want to display per page?
    $offset = ($page - 1) * $perPage; // get the offset, how many items need to be "skipped" on this page
    $items = array_slice($items, $offset, $perPage); // the array that we actually pass to the paginator is sliced

    return new LengthAwarePaginator($items, $total, $perPage, $page, [
        'path' => $request->url(),
        'query' => $request->query()
    ]);
}

Then in some-view.blade.php file, for example:

@foreach($items as $item)
    {{--  --}}
@endforeach


{{ $items->links() }}

See https://laravel.com/docs/5.7/pagination#manually-creating-a-paginator

Hexachlorophene answered 4/12, 2019 at 14:50 Comment(1)
I wish I could upvote more than once. This kind of example should be added to the official docs. They just mentioned that you can manually create pagination but don't show how. Your code works just as expected thanks.Somatoplasm
G
3

You can create manual pagination like this

$data = DB::table('post')->skip(0)->take(20)->get();

Grove answered 20/12, 2016 at 8:0 Comment(0)
B
3

Pretty way to instance this class

 use Illuminate\Pagination\LengthAwarePaginator as Paginator;
 //...
 $paginator = new Paginator($items->forPage($page, $limit), $count, $limit, $page, [
            'path'  => Paginator::resolveCurrentPath()
        ]);

Note items must be a Collection Object. Use collect(Array()) to convert Array to Collection

More informations

Beatty answered 13/6, 2018 at 19:12 Comment(0)
V
1

Try below code for manual pagination

<?php

namespace App\Http\Controllers;

use Illuminate\Pagination\LengthAwarePaginator as Paginator;
// use Illuminate\Pagination\Paginator;
use Illuminate\Http\Request;
use App\Product;
class MyController extends Controller
{
    public function index(Request $request){
        $items = Product::all();

        $filter_products = []; // Manual filter or your array for pagination

        foreach($items as $item){
            if($item['id']>40 && $item['id']<50){
                array_push($filter_products, $item);
            }
        }

        $count = count($filter_products); // total product for pagination
        $page = $request->page; // current page for pagination

        // manually slice array of product to display on page
        $perPage = 5;
        $offset = ($page-1) * $perPage;
        $products = array_slice($filter_products, $offset, $perPage);

        // your pagination 
        $products = new Paginator($products, $count, $perPage, $page, ['path'  => $request->url(),'query' => $request->query(),]);
        // use {{ $products->appends($_GET)->links() }} to dispaly your pagination
        return view('index',['products' => $products]);
    }
}
Victual answered 20/4, 2018 at 12:57 Comment(1)
Add some explanation to your answer . Code only answer are not really useful.Myca
N
0
public function myData($userid)
{
    $data = static::get();


    $result = [];
    if(!empty($data)){
        foreach ($data as $key => $value) {
            $result[$value->type.'-'.$value->postid][] = $value;
        }
    }


    $paginate = 10;
    $page = Input::get('page', 1);


    $offSet = ($page * $paginate) - $paginate;  
    $itemsForCurrentPage = array_slice($result, $offSet, $paginate, true);  
    $result = new \Illuminate\Pagination\LengthAwarePaginator($itemsForCurrentPage, count($result), $paginate, $page);
    $result = $result->toArray();
    return $result;
}
Nicoline answered 7/2, 2020 at 17:23 Comment(0)
U
-1

based on @Avishay28, i think php array_slice is not needed.

working in laravel 8.

i think this is a better approach in terms of performance, because we are not querying "SELECT * FROM products"

$items_per_page = 5;
$page_id = (int)$request->query('page') ?? 1;
$model_docs_count = Product::count();
$total_pages = ceil($model_docs_count / $items_per_page);
$model = Product::skip(($page_id - 1) * $items_per_page)->limit($items_per_page)->latest();
// dd($model->toSql()); "SELECT * FROM `products` WHERE ORDER BY `created_at` DESC LIMIT 5 OFFSET 0"

$custom_paginate = new LengthAwarePaginator($model, $total_pages, $items_per_page, $page_id, [
    'path' => $request->url(),
    'query' => $request->query()
]);

return response()->json([$custom_paginate], 200);
Ullage answered 27/12, 2020 at 7:53 Comment(0)
P
-5

Another way of using pagination would be like this:

public function index()
{
    $posts = DB::table('posts')->paginate(15);
}
Paapanen answered 10/11, 2016 at 4:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.