"next" page problem with Illuminate\Pagination\LengthAwarePaginator in the last page - laravel

I am trying to use Illuminate\Pagination\LengthAwarePaginator to paginate a Laravel Collection within a Livewire component in the following way:
public function render(): Factory|View|Application
{
$perPage = 3;
$items = $this->myCollection->forPage($this->page, $perPage);
$paginator = new Illuminate\Pagination\LengthAwarePaginator($items, $this->myCollection->count(), $perPage, $this->page);
return view('livewire.listing', [
'paginatedMyCollection' => $paginator,
]);
}
and in the listing.blade.php:
#foreach ($paginatedMyCollection as $element)
#livewire('row', ['element' => $element], key($element->id))
#endforeach
{{ $paginatedMyCollection->links() }}
It works fine(*)! for example:
except when the last page of the collection is reached. In this case, the «next page» button is erroneously constructed, resulting in the following presentation:
I have checked the Illuminate package and it seems that instead of using 'pagination.next' is taking this 'Showing.next' that does not work.
Can anyone help with this? Thanks and regards.
(*) The small buttons at the beginning and end of the page numbers could be filled with any character...

I think this is CSS issue.
Laravel Pagination is using tailwind per default.
If you are using Bootstrap, you can add Paginator::useBootstrapFive(); in app\Providers\AppServiceProvider boot() function
I am not sure how many libraries is supported, but you can always publish vendor view for pagination and edit it
php artisan vendor:publish --tag=laravel-pagination

Related

variable set in blade that I am not setting

I am trying to display certain content in my blade files based on if variables are set. But variables are being set that I'm not setting.
I have GameController.php:
use App\Models\Game;
class GameController extends Controller
{
public function index() {
$games = Game::latest()->get();
return view('game.index', [
'games' => $games
]);
}
...
and then in the layout blade file I do this:
#isset($game->name)
<h1>{{ $game->name }}</h1>
#endisset
So I'm setting $games, but I am NOT setting $game. however, $game is set. I want this header to show if I do a show() and $game would be set, but it shouldn't be showing in the index() where $game is not set. Is this normal behavior, and if so what's a better way for me to handle this?
$games = Game::latest()->get();
in code above get() returns collection (may be called array) of games, and you will need #foreach directive in blade template to loop through the games collection.
if you want only one latest game then you should use $games = Game::latest()->first();
I have found the issue. It was lack of understanding of how #extend and #section work.
index.blade.php extends layout.blade.php
#extends ('layout')
it appears all of index processes before layout. Because of that a foreach in index, despite technically being below the header if you were to view source on the web page, was processing before the header and setting $game. I just refactored the variable used in the foreach and that resolved my issue.
Thank you kerbh0lz, you technically helped me find it.

Laravel 5.7 Pagination Customization

$users = Student::paginate(2);
I was trying to paginate some data with paginate function() but am want to show only data no links
You can customize the way pagination is displayed, first step:
php artisan vendor:publish --tag=laravel-pagination
This command publishes the pagination views under the resources/views/vendor directory.
Here you can modify files as you want, the bootstrap-4.blade.php file is the default view for pagination.
You can find more info in the laravel official documentation
Using the $students->links() is optional if yo have a custom blade file showing pagination. However, if you do not need detailed pagination, you can use simplePaginate
$students = Student::simplePaginate(2);
And then in blade file just loop through it :
#foreach($students as $student)
Show student details
#endforeach
If you want to show just next or prev page links then you can use $students->links(), otherwise do not use links at all.
it's simple you must create a function to display your students in your template, add this code in your controller :
public function index()
{
$students = Student::paginate(10);
return view('student.index', ['students ' => $students ]);
}
And on the bottom of your template for example views\student\index.blade.php add :
<div class="row">
<div class="col-md-12">
{{ $students->links() }}
</div>
</div>
if you want display additional pagination information use the following methods: :
Paginator Instance Methods

Does custom pagination in Laravel 5.6 still have a bug?

I am using LengthAwarePaginator class to "transform" collection into the paginator object. Everything works like a charm, but I need necessarily to change pagination page name. When i use setPageName() method- the page name inside url changes from default "page" to whatever I need to, but pagination links are not working at all- by clicking, the next page contents don't appear, even the url has its custom page name for pagination.
I read everywhere that this was bug before, but now its claimed it is fixed- although it gives the same bug as before this Laravel fix somewhere at v. 5.0.
PS: I need to do this by setPageName method.
PS2: If this is a bug again, why to not solve it if we found out.
Here is my code:
Controller
$currentPage=LengthAwarePaginator::resolveCurrentPage()-1;
perPage=1;
// $items is collection variable
$currentPageBlogResults = $items->slice($currentPage * $perPage, $perPage)->all();
$items= new LengthAwarePaginator($currentPageBlogResults, count($items), $perPage);
$items->setPageName('special');
$items->setPath('main-category');
View
#foreach($items as $items)
.....
#endforeach
{{$items->links()}}
It's not a bug (I guess). You're resolving current page with LengthAwarePaginator::resolveCurrentPage() but it has own page name (defaults to "page"). You have two options:
$currentPage = LengthAwarePaginator::resolveCurrentPage('special') - 1;
or
LengthAwarePaginator::currentPageResolver(function () {
return 'special';
});

Laravel 5 multiple paginations on one page

I'm trying to have 2 paginations on a single page.
View:
{{!! $items->appends(['page2' => Request::input('page2', 1)])->render() !!}}
But it is not working, as using custom $pageName for pagination ($items->setPageName('custom_page_parameter')) links are not working in laravel 5.
https://stackoverflow.com/questions/29035006/laravel-5-pagination-wont-move-through-pages-with-custom-page-name
Here is how I did it in laravel 4:
Laravel Multiple Pagination in one page
What is Laravel 5 way of doing this?
I've spent far too much time trying to find out how to do this, so thought I'd share my findings in case there is another poor soul like me out there. This works in 5.1...
In controller:
$newEvents = Events::where('event_date', '>=', Carbon::now()->startOfDay())
->orderBy('event_date')
->paginate(15,['*'], 'newEvents');
$oldEvents = Events::where('event_date', '<', Carbon::now()->startOfDay())
->orderBy('event_date', 'desc')
->paginate(15,['*'], 'oldEvents');
Then continue as usual in the view: `
// some code to display $newEvents
{!! $newEvents->render() !!}
// some code to display $oldEvents
{!! $oldEvents->render() !!}
Now, what this doesn't do is remember the page of $oldEvents when paging through $newEvents. Any idea on this?
References:
pull request addressing the original issue
API docs for method
$published = Article::paginate(10, ['*'], 'pubArticles');
$unpublished = Article::paginate(10, ['*'], 'unpubArticles');
The third argument for paginate() method is used in the URI as follows:
laravel/public/articles?pubArticles=3
laravel/public/articles?unpubArticles=1
In Controller:
$produk = Produk::paginate(5, ['*'], 'produk');
$region = Region::paginate(5, ['*'], 'region');
in view:
{{$produk->appends(['region' => $region->currentPage()])->links()}}
{{$region->appends(['produk' => $produk->currentPage()])->links()}}
reference to :[Laravel 5] Multi Paginate in Single Page
Try using the \Paginator::setPageName('foo'); function befor buidling your paginator object:
\Paginator::setPageName('foo');
$models = Model::paginate(1);
return view('view_foo', compact('models'));
This question might help too: Laravel 5 pagination, won't move through pages with custom page name
Also note there is a bug atm: https://github.com/laravel/framework/issues/8000

Laravel Pagination links not including other GET parameters

I am using Eloquent together with Laravel 4's Pagination class.
Problem: When there are some GET parameters in the URL, eg: http://site.example/users?gender=female&body=hot, the pagination links produced only contain the page parameter and nothing else.
Blade Template
{{ $users->link() }}
There's a ->append() function for this, but when we don't know how many of the GET parameters are there, how can we use append() to include the other GET parameters in the paginated links without a whole chunk of if code messing up our blade template?
I think you should use this code in Laravel version 5+.
Also this will work not only with parameter page but also with any other parameter(s):
$users->appends(request()->input())->links();
Personally, I try to avoid using Facades as much as I can. Using global helper functions is less code and much elegant.
UPDATE:
Do not use Input Facade as it is deprecated in Laravel v6+
EDIT: Connor's comment with Mehdi's answer are required to make this work. Thanks to both for their clarifications.
->appends() can accept an array as a parameter, you could pass Input::except('page'), that should do the trick.
Example:
return view('manage/users', [
'users' => $users->appends(Input::except('page'))
]);
You could use
->appends(request()->query())
Example in the Controller:
$users = User::search()->order()->with('type:id,name')
->paginate(30)
->appends(request()->query());
return view('users.index', compact('users'));
Example in the View:
{{ $users->appends(request()->query())->links() }}
Be aware of the Input::all() , it will Include the previous ?page= values again and again in each page you open !
for example if you are in ?page=1 and you open the next page, it will open ?page=1&page=2 So the last value page takes will be the page you see ! not the page you want to see
Solution : use Input::except(array('page'))
Laravel 7.x and above has added new method to paginator:
->withQueryString()
So you can use it like:
{{ $users->withQueryString()->links() }}
For laravel below 7.x use:
{{ $users->appends(request()->query())->links() }}
Not append() but appends()
So, right answer is:
{!! $records->appends(Input::except('page'))->links() !!}
LARAVEL 5
The view must contain something like:
{!! $myItems->appends(Input::except('page'))->render() !!}
Use this construction, to keep all input params but page
{!! $myItems->appends(Request::capture()->except('page'))->render() !!}
Why?
1) you strip down everything that added to request like that
$request->request->add(['variable' => 123]);
2) you don't need $request as input parameter for the function
3) you are excluding "page"
PS) and it works for Laravel 5.1
In Your controller after pagination add withQueryString() like below
$post = Post::paginate(10)->withQueryString();
Include This In Your View
Page
$users->appends(Input::except('page'))
for who one in laravel 5 or greater
in blade:
{{ $table->appends(['id' => $something ])->links() }}
you can get the passed item with
$passed_item=$request->id;
test it with
dd($passed_item);
you must get $something value
In Laravel 7.x you can use it like this:
{{ $results->withQueryString()->links() }}
Pass the page number for pagination as well. Some thing like this
$currentPg = Input::get('page') ? Input::get('page') : '1';
$boards = Cache::remember('boards' . $currentPg, 60, function() {
return WhatEverModel::paginate(15);
});
Many solution here mention using Input...
Input has been removed in Laravel 6, 7, 8
Use Request instead.
Here's the blade statement that worked in my Laravel 8 project:
{{$data->appends(Request::except('page'))->links()}}
Where $data is the PHP object containing the paginated data.
Thanks to Alexandre Danault who pointed this out in this comment.

Resources