Skip to Content
Home

Multi-column search on Laravel Twill model index pages.

Posted
Categories
  • Web
  • Quick Tips
Wordcount
413

I recently had to enable searching via multiple columns on a Laravel Twill 2.0 model index page. As how to do this seems far from obvious, I thought I'd write up a quick how-to guide for anyone else trying to implement it.

Rationale

By default, the index page for a Twill CRUD model has a search bar, which searches for model instances based upon their title attribute.

An admin bar complete with search field.
The default admin bar with search input.

I had recently built a site, however, that creates biological records based upon user input. These consist of a species name, alongside a date and location etc; and, therefore, have no logical title. The users of the site wanted to be able to refine the list of records by more than one column (sometimes seeing all the records for a particular location, for example, or of a certain species).

The laravel twill documentation mentions that it is possible to define custom filters on the controller, but doesn't explicitly explain how to do so. Eventually, I discovered several github tickets asking how to enable searching on multiple columns, but none had a complete example, and some resulted in searches which only return results with exact matches.

The code

Eventually, I pieced together a working solution from the various tickets. It just requires adding a method to your Model Repository, and setting a property on the Model Controller.

In app/Repositories/ModelRepository.php define a custom filter() method on your Model Repository. Inside this method, call the searchIn() function and pass it the property names you wish to search in as arguments:

...
/**
* @param \Illuminate\Database\Query\Builder $query
* @param array $scopes
* @return \Illuminate\Database\Query\Builder
*/
public function filter($query, array $scopes = [])
{
    $this->searchIn($query, $scopes, 'search', [ // 'search' = search id.
        'database_column_1',
        'database_column_2',
        'database_column_3'
        ...etc...
    ]);
    return parent::filter($query, $scopes);
}
...

Then, in app/Http/Controllers/Admin/ModelController.php set the $defaultFilters property of your Model Controller to the new custom search function:

...
protected $defaultFilters = ['search' => 'search'];
...

In both of these examples ModelController and ModelRepository should, of course, be renamed to reflect the name of the model you are enalbing the search on. E.g. UserRepository.

Making these changes will update the search logic to perform a LIKE search on all of the columns passed as arguments to searchIn.