Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

elliotk's avatar

Sort and Paginate

Hello,

I am hoping for some help and advice on sorting. I have a Category page which lists out Products which I paginate.

    public function view(Category $category)
    {   
        $category->load('media');
        $products = $category->products()->enabled()->with('media')->paginate(12);
        return view('shop.category.index', compact('category','products'));
    }

I now want to provide the option to sort the products on the category page.

Product->Name (A-z) Product->Name (Z-a) Product->Price (Low-High) Product->Price (High-Low)

What is the best way of accomplishing this? I'd considered a drop down box, wrapped by a form, which posts to the server, however I don't want any warnings about resubmitting if the user doesn't navigate properly.

I guess something like mysite.com/laptops?page=2&sort=price&price=asc would be ideal.

Any pointers how to do this in my route, controller and blade?

Thanks

0 likes
5 replies
elliotk's avatar

Anybody got a moment to review this?

Dalma's avatar

There are two options that immediately come to mind. Either some client side sorting options like you might find with Datatables that combines client java and ajax queries or you provide a form with perhaps a dropdown of the various options available which would need to then make a query back to your controller.

In your controller you can receive the query request by

$option = $request->query('optionname');
elliotk's avatar

Thanks @dalma i don't want to go to the java / ajay way, i'd much rather do something in the controller.

I'm thinking something like this, but can't get the syntax right.

        $products = $category->products()->enabled()->with('media');

        if (request('sort') && request('order')) {
            $products->orderBy(request('sort'), request('order'));
        }

        $products->paginate(12);

I think on the front end, i can do a simple dropdown, which does a redirect to the page with the query parameters appended.

elliotk's avatar

So, I sorted the query..

$products = $category->products()->enabled()->with('media')
            ->when(request('sort'), function ($query) {
                    return $query->orderBy(request('sort'), request('order'));
                })->paginate(12);

And then on the front end I've done this

      <div class="form-group">
        <select class="form-control" name="sort" id="sort" onchange="if (this.value) window.location.href=this.value">
          <option value="?sort=name&order=asc">Name [A-Z]</option>
          <option value="?sort=name&order=desc">Name [Z-A]</option>
          <option value="?sort=price&order=asc">Price [Low-High]</option>
          <option value="?sort=price&order=desc">Price [High-Low]</option>
        </select>
      </div>

This does the correct sorting, so that's good. The issue now is that when I move to the second page on the paginate, the sorts are dropped from the URL and the results that are displayed are unsorted.

Any ideas?

elliotk's avatar

Heres the paginate solutions

{!! $products->appends(\Request::except('page'))->render() !!}

I hope all this helps someone else too

Please or to participate in this conversation.