Laravel Pagination links not including other GET parameters - laravel

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.

Related

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

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

Laravel, return view with Request::old

fHello, for example, i have simple input field (page index.php)
<input type="text" name="name" value="{{Request::old('name')}}">
In controller
$this->validate($request, ['name' => 'required']);
After this, i want make some check without Laravels rules. For example
if($request['name'] != 'Adam') { return view('index.php'); }
But after redirect, Request::old is empty. How to redirect to index.php and save old inputs and use Request::old, or its impossible? Thank you.
PS its example, i know that Laravel has special rules for check inputs value
Old question, but for future reference, you can return the input to a view by flashing the request input just beforehand.
i.e.
session()->flashInput($request->input());
return view('index.php');
then in your view you can use the helper
{{ old('name') }}
or
{{Request::old('name')}}
In Laravel 8.x, you can simply use $request->flash();
Docs: https://laravel.com/docs/8.x/requests#flashing-input-to-the-session
You can use back() instead if any url. These function helps you in any case to be able to return to previous page without writing route.
return back()->withInput();
To add the input to your request try adding:
return view('index.php')->withInput();

Laravel Blade: Use commands from string

I have variable in Controller:
$abc = '#include('partials.formerror', array(.....))';
And I send that variable to view:
\View::share([
"abc" => $abc,
]);
And I want in view:
......
......
#include('partials.formerror', array(....)
......
......
#include('partials.formerror', array(....) is dynamic content from Controller. But it's COMMAND of Blade, not plain text. How can I do that?
You need a string blade compiler like this one:
https://packagist.org/packages/wpb/string-blade-compiler
Laravel doens't allow blade rendering from strings out of the box.
Fyi: you could also use Blade::compileString which imho is not an elegant solution
your answer is here: https://laravel.com/docs/5.2/views#view-composers
You can create a view composer and attache dynamic content to your view.

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 4 Javascript Link using {{Html}}

Is there any Laravel4 Html() function or way to add a disabled link. Of course I could create the <a> tag directly, though I'd prefer to be consistent.
ie:
{{ Html::link('javascript:;','Delete',array('id'=>"deletebt")) }}
You must use link_to, for example :
link_to('link', 'title', array('id' => 'MyId'));

Resources