Have you read. http://laravel.io/forum/11-13-2014-laravel-5-pagination, or use ajax.
You can write your own paginator, you don't have to use the built in one.
AJAX, indeed, would be the way to go.
But you can also solve it another way.
Paginator class has a setPageName
method for setting the name of url parameter designating page number (page
by default). And it also allows to append additional parameters to page links via appends
method.
So, you can probably do something like this (haven't tested it myself):
//In your controller
$table1 = ModelOne::paginate(20)->setPageName('page1');
$table2 = ModelTwo::paginate(20)->setPageName('page2');
//In your view
<table>
//content
</table>
$table1->appends( [ $table2->getPageName() => $table2->currentPage() ] )->render();
<table>
//content
</table>
$table2->appends( [ $table1->getPageName() => $table1->currentPage() ] )->render();
I agree, ajax would definitely be the way to go, but I'm not familiar enough with it to begin to know how to implement it (I'm still pretty new to programming in general). So if you maybe had any suggestions on how to get started with that, that would be great.
Though in the interim, I did try implementing Xum's suggestion, but I ended up with a an error "parameter 1 expects to be a valid callback". I'll look into it a little farther, but I will also look into the ajax option if I can figure out where to start.
Also jimgwhit, thanks for your suggestion, I'll take a look at the thread.
Go to the jquery site and browse around. Also YouTube search jquery ajax.
Hey, you don't learn this stuff in 5 minutes, you learn in months. You could pass current page numbers to view, then if hitting next on table 2, that will advance, meanwhile repass pages to controller to maintain other tables page no. Look at using skip and take. Read the post I referenced, the answer lies there, it's called request data.
Yelldon said: Though in the interim, I did try implementing Xum's suggestion, but I ended up with a an error "parameter 1 expects to be a valid callback". I'll look into it a little farther, but I will also look into the ajax option if I can figure out where to start.
My bad, there's is no getPageName()
method. No problem, you'll just have to write page parameter name explicitly:
$table1->appends( [ 'page2' => $table2->currentPage() ] )->render();
//...
$table2->appends( [ 'page1' => $table1->currentPage() ] )->render();
Excellent jimgwhit, thank you for the direction. It is very much appreciated!
And Xum, using your suggestion, it does append the the url properly, ie. /?page1=2&page2=1, yet it does nothing, the page stays and doesn't paginate anything. If I drop the append method and, I get the same result with just the single paginate, it shows in the url, the page does nothing. If I manually change page1 or page2 to just page, I get a result. My guess is that the setPageName() method in the controller doesn't work properly in this case?
Take it a step further, you have to request page1 and 2 in controller and re-send to view each time. You probably need to use skip and take. Look at query builder example in docs. You almost have it.
Yeah, it's trickier than I thought.
@jimgwhit, if you use skip()
and take()
you lose the paginator.
I dug into how the built-in paginator gets the current page from the input. AbstractPaginator
class has a static method resolveCurrentPage()
which just calls a closure stored in a static member, which in turn can be set by currentPageResolver()
. And it is set by PaginationServiceProvider
like this:
Paginator::currentPageResolver(function()
{
return $this->app['request']->input('page');
});
And that's what we have to do, too.
//In your controller which should have $request argument
Paginator::currentPageResolver(function() use ($request) {
return $request->input('page1');
});
$table1 = ModelOne::paginate(20)->setPageName('page1');
Paginator::currentPageResolver(function() use ($request) {
return $request->input('page2');
});
$table2 = ModelTwo::paginate(20)->setPageName('page2');
//In your view
<table>
//content
</table>
$table1->appends( [ 'page2' => $table2->currentPage() ] )->render();
<table>
//content
</table>
$table2->appends( [ 'page1' => $table1->currentPage() ] )->render();
Yeah, it's not pretty, but a quick test in artisan tinker
showed that it works.
Look again at:
public function ownerlist()
{
if(isset($_REQUEST['t1']))
{
$t1 = $_REQUEST['t1'];
}
else
{
$t1 = "";
}
if(isset($_REQUEST['page']))
{
$page = $_REQUEST['page'];
}
else
{
$page = "1";
}
$perpage = "5";
$offset = ($page - 1) * $perpage;
$ownersearch = $t1;
$ownersearch = $ownersearch . "%";
$krows = \Illuminate\Support\Facades\DB::select('select COUNT(ownerid) as count from powners where oname like :oname', ["oname" => $ownersearch]);
//$numrows = (int)$krows;
$numrows = $krows[0]->count;
echo $numrows;
$data = \Illuminate\Support\Facades\DB::table('powners')
->where('oname', 'like', $ownersearch)
->orderBy('oname', 'asc')
->skip($offset)->take($perpage)->get();
$pagelinks = Pagination::makeLengthAware($data , $numrows, $perpage, ['t1' => $t1]);
return \View::make('owner/pownerlist')->with('data',$data)->with('data2',$pagelinks);
You do not loose paginator, just done a different way. Of course you have to chain another ->with for each seperate
table you are paginating. The bulk of work is in controller. study again all info from:
http://laravel.io/forum/11-13-2014-laravel-5-pagination.
Note the line:
$pagelinks = Pagination::makeLengthAware($data , $numrows, $perpage, ['t1' => $t1]);
for other table you change variable name i.e.:
$pagelinks2 = Pagination::makeLengthAware($data2 , $numrows2, $perpage2, ['whatever2' => $whatever]);
And add this with a ->with
Now in view the page links are also displayed different:
<div class="pagination" style="margin-left: 20px; margin-right: auto; width: 900px; border:solid red; display: block;">
<?php
use App\Services\Pagination;
echo $data2; ?>
<?php
</div>
And under table 2 add another paginator with the variables for it. Really easy not hard.....
Xum, your suggestion absolutely works. I have it functioning as it should.
jimgwhit, I do see what your doing now, by creating your own pagination. Right now I'm sticking to the Laravel one, for simplicity sake, and later I will try and tackle it I think, when I get more familiar with the framework (and become better at PHP in general). Looking at it, I'm still not sure how it's using ajax as you mention, but I'm obviously no expert, but I'll keep looking at it.
I would say the only thing I do not like about the Laravel pagination, is its so heavily tied to bootrap classes. I was thinking about extending the classes used for it and going that route (and still something I might do), but then I also found this handy package quite randomly https://github.com/Landish/Pagination for using other front end frameworks, or creating your own. Not sure which direction I'll head yet, but also thought I would drop it in here in case anyone reading this thread ever comes across a need for it.
Thank you to both of your efforts, you have put a lot of time into looking at this and I want to think your both. Your efforts have been invaluable.
No this is laravel 5 pagination read all of this post http://laravel.io/forum/11-13-2014-laravel-5-pagination
jimgwhit, maybe then I'm confused as to what you're getting at then. In the thread you talk about a pagination you've used before by author David Carr, and that seems to be what you are implementing and using from that point on, not that default one that comes with Laravel, unless I'm reading that wrong.
No I show that, but the last examples are laravel. READ whole post. Read query builder helper. That's where you use skip take built in. This line is all laravel.
$pagelinks = Pagination::makeLengthAware($data , $numrows, $perpage, ['t1' => $t1]);
Forget the docs on simple pagination, this is how to paginate in L5. Skip take also works with eloquent that's where makeLengthAware comes in. These are advanced undocumented features. Do like I showed you and you'll be fine.
User bestmomo helped me through this, his class function will be needed, namespaces, and proper use statement used. I'm on mobile now, I will shoot you more code later, when I am on regular computer.
Step1 make this file Pagination.php and put it at app\Services. If you do not have a Services folder, create it.
<?php namespace App\Services;
use Illuminate\Pagination\Paginator;
use Illuminate\Pagination\LengthAwarePaginator;
abstract class Pagination
{
/**
* Create paginator
*
* @param Illuminate\Support\Collection $collection
* @param int $total
* @param int $perPage
* @return string
*/
public static function makeLengthAware($collection, $total, $perPage, $appends = null)
{
$paginator = new LengthAwarePaginator(
$collection,
$total,
$perPage,
Paginator::resolveCurrentPage(),
['path' => Paginator::resolveCurrentPath()]
);
if($appends) $paginator->appends($appends);
return str_replace('/?', '?', $paginator->render());
//return str_replace('/?', '?', $paginator);
}
}//end class
At top of controller where you use LengthAwarePaginator, put:
use App\Services\Pagination;
Then paginate how I showed, not some other way.
Thank User bestmomo for this, he helped me through this. You will need to css your page links properly.
jimgwhit, I do think I see what you're getting at now. I'll try and see if I can implement it.
Sign in to participate in this thread!
The Laravel portal for problem solving, knowledge sharing and community building.
The community