Laravel 5.3 - Multiple pagination on a single page not working
Asked Answered
D

3

13

I am displaying paginated results that I get from Algolia. I have two queries in my controller that I paginate. This is how I send the data from the controller to the view:

public function index(Request $request)
{
    if(!$request->q && !$request->page){
      return redirect('/');
    }

    $videos = Video::search($request->q)->paginate(1);
    $videosCollection = $videos->getCollection();

    return fractal()
      ->collection($videosCollection)
      ->parseIncludes(['player'])
      ->transformWith(new VideoTransformer)
      ->paginateWith(new IlluminatePaginatorAdapter($videos))
      ->toArray();
}

So then when I search for example for 'rene' the result is displayed on url http://videoapp.app/search?q=rene And the data that I get looks like this:

{
  data: [
    {
      id: 46,
      description: null,
      views: 0,
      created_at: "1 month ago",
      player: {
        data: {
          id: 34,
          image: "15889ca47e557c12240142_1013305815416003_5199651181367705874_n.jpg",
          first_name: "Bruno",
          last_name: "Hendricks"
    }
  }
}
],
meta: {
  pagination: {
    total: 2,
    count: 1,
    per_page: 1,
    current_page: 1,
    total_pages: 2,
    links: {
      next: "http://videoapp.app/search?query=rene&page=2"
      }
    }
  }
}

But the pagination link that is being created for the next page is "http://videoapp.app/search?query=rene&page=2" and if I click on it the metadata is changed and I get the results for the whole table and not just for the result of my first query that was 'rene' in this example. If I on the other hand type the url in the browser http://videoapp.app/search?q=rene&page=2 then it works like it should be. How I can change those generated links so that it works as it should be?

I have also tried with another example from SO, which again didn't work for me:

Controller:

    if(!$request->q && !$request->page){
      return redirect('/');
    }

    $players = Player::search($request->q)
                ->paginate(1);

    $videos = Video::search($request->q)
                ->paginate(1);
    $videos->setPageName('videos');

View

{{ $videos->appends(array_except(Request::only('q'), 'page'))->links() }}

and

{{ $players->appends(array_except(Request::only('q'), 'videos'))->links() }}

I have also tried the suggestion from the answers:

public function index(Request $request)
{
    $q = $request->q;
    $videosPage = $request->vpage;
    $playersPage = $request->ppage;

    if (! $request->q) {
        return redirect('/');
    }

    $players = Player::search($q)
        ->paginate(1, 'ppage')
        ->appends(['q' => $q, 'vpage' => $videosPage]);
    $videos = Video::search($q)
        ->paginate(1, 'vpage')
        ->appends(['q' => $q, 'ppage' => $playersPage]);

    return view('search.index', [
        'players' => $players,
        'videos'  => $videos,
    ]);
}

But that also didn't work, when I would click on a link for players it would go back to video results for example. Can't seem to find any solution for this problem?

Dorri answered 19/2, 2017 at 18:58 Comment(1)
This question has been anwered here #24086769Alceste
I
4

The problem is you need 3 separate query string values ("q" for search term, and the page number of each paginator), and the default pagination links clear them, leaving only the one corresponding to the current paginator.

I would try this:

public function index(Request $request)
{
    $q = $request->q;
    $videosPage = $request->vpage;
    $playersPage = $request->ppage;

    if (! $request->q) {
        return redirect('/');
    }

    $players = Player::search($q)
        ->paginate(1, 'ppage')
        ->appends(['q' => $q, 'vpage' => $videosPage]);
    $videos = Video::search($q)
        ->paginate(1, 'vpage')
        ->appends(['q' => $q, 'ppage' => $playersPage]);

    return view('search.index', [
        'players' => $players,
        'videos'  => $videos,
    ]);
}

This way, each paginator has its own page name, and keeps the other one and the search term in the query string.

Inland answered 23/2, 2017 at 15:45 Comment(3)
It seems to work fine for videos, but when I switch to players tab and start clicking on new pages it goes back to videos tab and video results.Dorri
@Dorri well, clicking on the paginator link will refresh the browser with the response of the new request, so the "active tab state" will not be preserved. It seems like the simplest way would be AJAX requests then... In fact, why don't you use the Algolia javascript client instead?Inland
I am using Algolia javascript client for autocomplete, not sure how would I use it for this problem.Dorri
M
0
if (!$request->q) {
    return redirect('/');
}

This is causing your problem, when you press the paginate link it will replace ?q=something to ?page=2 which will cause your function to redirect.

Use something else ex:

if(!request->q && !request->page){
    return redirect('/');
}
Miscellaneous answered 22/2, 2017 at 22:12 Comment(6)
I don't have any search method in Player model, I am just using the Laravel\Scout\Searchable in my model for it.Dorri
and use paginate(1); and not paginate(1, ['*'], 'videos');Miscellaneous
It is still not working as it should be, the pagination links are created, and there is no error, but I don't get two separate queries, pagination links continue from video results to player results, and I would like to have separate results and paginations in each tab, for players and videos.Dorri
Now that is a different problem ;) solution to that here: #24086769Miscellaneous
Yes, and that was my question all along, I saw the solutions from that question, but it didn't help in my case.Dorri
Should work with his solution, remember to add other_page to your redirect functionMiscellaneous
E
0

Divide the window for players or for videos with <-- - Iframe -- - > or <--- frameset --> Use different method into your controller and output will appear on same window.

Exhibition answered 23/2, 2017 at 13:15 Comment(1)
I am not sure how to do that, could you give some code example?Dorri

© 2022 - 2024 — McMap. All rights reserved.