In this article I would like to share how to make a sortable index view with Laravel 4.
Let’s assume you have an index view with a table. Like this example for a table that contains posts.
@extends('layouts.scaffold') @section('main') <h1>All Posts</h1> <div class="search"> {{ Form::model(null, array('route' => array('posts.search'))) }} {{ Form::text('query', null, array( 'placeholder' => 'Search query...' )) }} {{ Form::submit('Search') }} {{ Form::close() }} </div> <p>{{ link_to_route('posts.create', 'Add new post') }}</p> @if ($posts->count()) <table class="table table-striped table-bordered"> <thead> <tr> <th>Title</th> <th>Body</th> </tr> </thead> <tbody> @foreach ($posts as $post) <tr> <td>{{{ $post->title }}}</td> <td>{{ $post->body }}</td> <td>{{ link_to_route('posts.edit', 'Edit', array($post->id), array('class' => 'btn btn-info')) }}</td> <td> {{ Form::open(array('method' => 'DELETE', 'route' => array('posts.destroy', $post->id))) }} {{ Form::submit('Delete', array('class' => 'btn btn-danger')) }} {{ Form::close() }} </td> </tr> @endforeach </tbody> </table> @else There are no posts @endif @stop
And your index action looks like this:
public function index() { $posts = $this->post->all(); return View::make('posts.index', compact('posts')); }
Modifying the code
Now if we want to make our index view sortable by clicking on the column header, we should modify our controller to look like this
public function index() { $sortby = Input::get('sortby'); $order = Input::get('order'); if ($sortby && $order) { $posts = $this->post->orderBy($sortby, $order)->get(); } else { $posts = $this->post->get(); } return View::make('posts.index', compact('posts', 'sortby', 'order')); }
This will retrieve two GET variables: sortby and order.
The sortby variable will contain which field to sort by. The order variable will dontain the direction (ASC or DESC)
Next, we need to modify our view:
@extends('layouts.scaffold') @section('main') <h1>All Posts</h1> <div class="search"> {{ Form::model(null, array('route' => array('posts.search'))) }} {{ Form::text('query', null, array( 'placeholder' => 'Search query...' )) }} {{ Form::submit('Search') }} {{ Form::close() }} </div> <p>{{ link_to_route('posts.create', 'Add new post') }}</p> @if ($posts->count()) <table class="table table-striped table-bordered"> <thead> <tr> <th> @if ($sortby == 'title' && $order == 'asc') {{ link_to_action( 'PostsController@index', 'Title', array( 'sortby' => 'title', 'order' => 'desc' ) ) }} @else {{ link_to_action( 'PostsController@index', 'Title', array( 'sortby' => 'title', 'order' => 'asc' ) ) }} @endif </th> <th>Body</th> </tr> </thead> <tbody> @foreach ($posts as $post) <tr> <td>{{{ $post->title }}}</td> <td>{{ $post->body }}</td> <td>{{ link_to_route('posts.edit', 'Edit', array($post->id), array('class' => 'btn btn-info')) }}</td> <td> {{ Form::open(array('method' => 'DELETE', 'route' => array('posts.destroy', $post->id))) }} {{ Form::submit('Delete', array('class' => 'btn btn-danger')) }} {{ Form::close() }} </td> </tr> @endforeach </tbody> </table> @else There are no posts @endif @stop
We added an if-statement to check if any sorting has been done to generate a clickable table header link. In this example we made the title sortable. You can add the same code to make the other headers sortable too.
Clicking once on the header will sort the posts by title with direction ASC, clicking again will sort by DESC order. (Ascending and Descending)
That’s it!
It was that easy! If this little tip helped you or you like my tutorials, feel free to like my Facebook page, follow me on Twitter, share on StumbleUpon or any other Social Media of your choice!
As always if you have any questions feel free to use the comment form below.