Filtering data based on checkbox selection in laravel

When displaying data to a user, it could be convenient to allow them to filter the data. So we
don’t have to make the user click on submit and reload the page every time, we can do all the
filtering using Ajax. For this recipe, we’ll make a book list and allow the user to filter it based
on the genre.

Getting ready

For this recipe, we need a standard Laravel installation that’s configured to work with a
database. We’ll need to set up a table to use by running this SQL statement:
DROP TABLE IF EXISTS books;
CREATE TABLE books (
id int(10) unsigned NOT NULL AUTO_INCREMENT,
name varchar(255) DEFAULT NULL,
author varchar(255) DEFAULT NULL,
genre varchar(255) DEFAULT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
INSERT INTO books VALUES (‘1’, ‘Alice in Wonderland’,
‘Lewis Carroll’, ‘fantasy’);
INSERT INTO books VALUES (‘2’, ‘Tom Sawyer’, ‘Mark
Twain’, ‘comedy’);
INSERT INTO books VALUES (‘3’, ‘Gulliver\’s Travels’,
‘Jonathan Swift’, ‘fantasy’);

INSERT INTO books VALUES (‘4’, ‘The Art of War’, ‘Sunzi’,
‘philosophy’);
INSERT INTO books VALUES (‘5’, ‘Dracula’, ‘Bram Stoker’,
‘horror’);
INSERT INTO books VALUES (‘6’, ‘War and Peace’, ‘Leo
Tolstoy’, ‘drama’);
INSERT INTO books VALUES (‘7’, ‘Frankenstein’, ‘Mary
Shelley’, ‘horror’);
INSERT INTO books VALUES (‘8’, ‘The Importance of Being
Earnest’, ‘Oscar Wilde’, ‘comedy’);
INSERT INTO books VALUES (‘9’, ‘Peter Pan’, ‘J. M.
Barrie’, ‘fantasy’);

How to do it…

To complete this recipe, follow these steps:
1. In the controllers directory, create a new file named BooksController.php:
<?php
class BooksController extends BaseController {
public function getIndex()
{
return View::make(‘books.index’);
}

public function postBooks()
{
if (!$genre = Input::get(‘genre’)) {
$books = Book::all();
} else {
$books = Book::whereIn(‘genre’, $genre)->get();
}
return $books;
}
}
2. Register the books controller in the routes.php file:
Route::controller(‘books’, ‘BooksController’);
3. In the views directory, create a new folder named books, and in that folder, create a
file named index.php:
<!doctype html>
<html lang=”en”>
<head>
<meta charset=”utf-8″>

<title>Books filter</title>
<scriptsrc=”//ajax.googleapis.com/ajax/libs/jquery
/1.10.2/jquery.min.js”></script>
</head>
<body>
<form id=”filter”>
Comedy: <input type=”checkbox” name=”genre[]”
value=”comedy”><br>
Drama: <input type=”checkbox” name=”genre[]”
value=”drama”><br>
Fantasy: <input type=”checkbox” name=”genre[]”
value=”fantasy”><br>
Horror: <input type=”checkbox” name=”genre[]”
value=”horror”><br>
Philosophy: <input type=”checkbox” name=”genre[]”
value=”philosophy”><br>
</form>
<hr>
<h3>Results</h3>
<div id=”books”></div>
<script>
$(function(){
$(“input[type=checkbox]”).on(‘click’, function() {
var books = ”;
$(“#books”).html(‘loading…’);
$.post(‘books/books’, $(“#filter”).serialize(),
function(data){
$.each(data, function(){
books += this.name + ‘ by ‘ + this.author + ‘ (‘ +
this.genre + ‘)<br>’;
});
$(“#books”).html(books);
});
});
});
</script>
</body>
</html>
4. In the models directory, create a file named Book.php:
<?php
class Book extends Eloquent {
}
5. In the browser, go to http://{my-server}/books and click on a few checkboxes
to see the result.

How it works…

With our database set up, we begin with our main list page. This page has a number of
checkboxes, with the value of each corresponding to a genre in our books table. When a box
is checked, the form is submitted asynchronously to our postBooks() method. We use those
results, loop through them, and display them in our books div.
Our postBooks() method begins by making sure a genre was actually submitted. If not, that
means everything is unchecked and it will return all the books. If something is checked, we
get everything from the database that matches the checked values. Since Laravel provides us
with the raw returned data in JSON format, we then return the results, and in our index, the
results are displayed correctly.

Leave a Reply

Your email address will not be published. Required fields are marked *