Sortable index view tables with Laravel 4



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 ASCclicking 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.

Share the knowledge!
Share on Facebook0Tweet about this on Twitter0Share on Google+8Share on StumbleUpon0Share on Reddit0Share on LinkedIn0Share on TumblrBuffer this pageDigg this

Comments

You may also like...

Stay updated
Subscribe!