What is the best way to implement the items filter functionality?
I have a table with some items, and each item has some fields.
How can I select items with fields filtering, like e-commerce filtering, using Laravel 5 and Eloquent?
What is the best way to implement the items filter functionality?
I have a table with some items, and each item has some fields.
How can I select items with fields filtering, like e-commerce filtering, using Laravel 5 and Eloquent?
I've always used eloquent scopes to filter eloquent results: https://laravel.com/docs/5.1/eloquent#query-scopes
Your Controller:
use App\Item;
class ItemController extends Controller
{
public function index(Request $request)
{
$items = Item::name($request->name)->price($request->price)->paginate(25);
return view('items.index', compact('items'));
}
}
Your Model:
class Item extends Model
{
public function scopeName($query, $name)
{
if (!is_null($name)) {
return $query->where('name', 'like', '%'.$name.'%');
}
return $query;
}
public function scopePrice($query, $price)
{
if (!is_null($price)) {
return $query->where(compact('price'));
}
return $query;
}
}
Your View:
<form action="{{ route('items.index') }}" method="get">
<input type="text" name="price" />
<input type="text" name="name" />
<input type="submit" value="Search">
</form>
@foreach($items as $item)
{{ $item->name }}
@endforeach
{!! $items->render() !!}
In your scopes, you can check if the given value is null before limiting your query results. This effectively allows users to search and filter paginated results.
You could further enhance the search by automatic validation using Laravel's Form Requests so you can sure that the input they are searching for matches the data type for your query.
Keep in mind you'll have to modify the getRedirectUrl()
method since your users will be executing a GET
request and by default the getRedirectUrl()
will contain the GET
URL parameters resulting in an infinite loop since the one of the params failed validation.
Here's an example using the above:
class ItemSearchRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'nullable|string|min:2|max:100',
'price' => 'nullable|numeric',
];
}
protected function getRedirectUrl()
{
return url('/items');
}
}
I wrote a package for exactly this here: https://github.com/Tucker-Eric/EloquentFilter
It allows you to do something like:
use App\Item;
class ItemController extends Controller
{
public function index(Request $request)
{
$items = Item::filter($request->all())->paginateFilter(25);
return view('items.index', compact('items'));
}
}
You can use this awesome laravel package: github.com/abdrzakoxa/laravel-eloquent-filter
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
class UserController extends Controller
{
public function index(Request $request)
{
$users = Item::filter($request->all())->paginateFilter(10);
return view('users.index', compact('users'));
}
}
You can use package for regular index workflow to filter, sort, search and paginate https://packagist.org/packages/abyss403/request-meta
class UserController extends Controller
{
...
public function index(Request $request){
// Define model
$model = new User();
// Obtain collection based on request metadata
$collection = \RequestMeta::load($model, $request)->data();
// And just return it
return $collection;
// OR using resources
return new UserResourceCollection($collection);
}
...
}
That's it