Simple Laravel Paginated Sortable Table

Posted by Amith Gotamey on August 5, 2015 in aBit Blogs

Let’s assume that you need a table view with clickable headings which sorts the data in it with the values from that particular column. This should work on any page with pagination. Please note that this doesn’t work with queries using group_by clause.

Let’s get started. For this particular tutorial we are going to work with users table, displaying their details in a table format and making them sortable. First the Controller, UserController:

<?php

namespace App\MyAwesome\ControllerNamespace;

use App\User;
use Illuminate\Http\Request;

class UserController extends …
{
	private $user;

	public function __constructor(User $user)
	{
		$this->user = $user;
    }

    public function index(Request $request)
    {
        $users = $user->newQuery(); // Start a query
                    
        $order = $request->get('order'); // Order by what column?
        $dir = $request->get('dir'); // Order direction: asc or desc
        $page_appends = null;

        if ($order && $dir) {
            $users = $users->orderBy($order, $dir);

            // Tell the Paginator to append the following to the page URL as well
            $page_appends = [
                'order' => $order,
                'dir' => $dir,
            ];
        }

        $users = $users->paginate(20); // Hard coded 20 per page

        $data['users'] = $users;
        $data['dir'] = $dir == 'asc' ? 'desc' : 'asc';
        $data['page_appends'] = $page_appends;

        return view('user.index', $data);
    }
}

Now that the controller code is done, let’s get on with the view. Please note that I’ll be using Laravel’s Blade templating, and I am assuming that you have a basic base layout setup for all of your pages, I am just going to focus on the content section for the user.index view:

@extends(‘base_layout’)

@section(‘content’)
{!! $users->appends($page_appends)->render() !!}
<table>
    <tr>
        <td>
            <a href="/user?page={{ $users->currentPage() }}&order=username&dir={{ $dir ? $dir : 'asc' }}">
                Username
            </a>
        
            <a href="/user?page={{ $users->currentPage() }}&order=email&dir={{ $dir ? $dir : 'asc' }}">
                Email
            </a>
        
        
            <a href="/user?page={{ $users->currentPage() }}&order=city&dir={{ $dir ? $dir : 'asc' }}">
                City
            </a>
        
    
    @foreach($users as $user)
    
        
            {{ $user->username }}
        
        
            {{ $user->email }}
        
        
            {{ $user->city }}
        
    
    @endforeach

{!! $users->appends($page_appends)->render() !!}
@endsection

That’s it and it should do the trick. Remember, for this to work, you need the following:

  1. A User model linked to a `users` table having `username`, `email` and `city` columns
  2. A route to the User resource (url() . '/users')

Please submit your questions and doubts in the comments below.

Cheers!

Leave a Reply

© Copyright . aBit. All Rights Reserved.