This package provides filters what depends of another filters.
You can install the package in to a Laravel app that uses Nova via composer:
composer require awesome-nova/dependent-filter
You can declare filters in you filters method directly:
function filters(Request $request)
{
return [
(new DependentFilter('State'))
->withOptions([
'all' => 'All orders',
'dragt' => 'Draft',
'outstanding' => 'Outstanding',
'past_due' => 'Past due',
'paid' => 'Paid',
]),
];
}
Also you can use DependentFilter::make()
instead new DependentFilter()
.
For queries you need to use callback declaration:
function filters(Request $request)
{
return [
DependentFilter::make('Category', 'category_id'))
->withOptions(function (Request $request) {
return Category::pluck('title', 'id');
}),
];
}
Note: In difference with Nova filters filter's
value
need pass as array key andlabel
as array value.
As is Nova filters you can create filter's class:
class CategoryFilter extends DependentFilter
{
/**
* Name of filter.
*
* @var string
*/
public $name = 'Category';
/**
* Attribute name of filter. Also it is key of filter.
*
* @var string
*/
public $attribute = 'ctaegory_uid';
public function options(Request $request, array $filters = [])
{
return Category::pluck('title', 'id');
}
}
Note: The
fresh
method is identical with the callback for declaring options.
function filters(Request $request)
{
return [
CategoryFilter::make(),
];
}
For creating dependent filter you need to specify dependent filters values at which the option will be shown:
function filters(Request $request)
{
return [
CategoryFilter::make(),
SubCategory::make('Subcategory', 'subcategory_id')
->withOptions(function (Request $request) {
return SubCategory::all()->map(function ($subcategory) {
return [
'value' => $subcategory->id,
'label' => $subcategory->title.
'depends' => [
'category_id' => $subcategory->category_id, //Also you can set array of values
],
];
});
}),
];
}
Note. Instead of an attribute or class name, you must specify the key of the filter.
For big collection of data you can use dynamic updating of the filter.
function filters(Request $request)
{
return [
StateFilter::make('State', 'state_id'),
DependentFilter::make('City', 'city_id')
->dependentOf('state_id')
->withOptions(function (Request $request, $filters) {
return City::where('state_id', $filters['state_id'])
->pluck('title', 'id');
}),
];
}
In class declaration you also need to set $dependentOf
property:
class CityFilter extends DependentFilter
{
public $dependentOf = ['state_id'];
function options(Request $request, $filters = [])
{
return City::where('state_id', $filters['state_id'])
->pluck('title', 'id');
}
}
If you want to show options only when main filter is selected you can use when
for check it:
function options(Request $request, $filters = []) {
return City::when($filters['state_id'], function ($query, $value) {
$query->where('state_id', $value)
})->pluck('title', 'id');
}
You can hide filters until they have options.
For it you need set $hideWhenEmpty
or call hideWhenEmpty()
method:
class CityFilter extends DependentFilter
{
public $hideWhenEmpty = true;
}
function filters(Request $request) {
return [
StateFilter::make('State', 'state_id'),
CityFilter::make('City', 'city_id')->hideWhenEmpty(),
];
}
If you want to set default value you need to call withDefault
method with value or overload default
method in class declaration.
function filters(Request $request) {
return [
StateFilter::make('State', 'code')->withDefault('WA'),
];
}
class StateFilter extends DependentFilter
{
public function default()
{
return 'WA';
}
}
By default filter checking by equal filed specified in $attribute
and filter value. You can overload it like as in Nova filters:
class MyFilter extends DependentFilter
{
public function apply(Request $request, $query, $value)
{
return $query->where('column', '>=', $value);
}
}
When you use declare style you can set pass apply callback to withApply
method:
function filters(Request $request) {
return [
StateFilter::make('State', 'code')->withApply(function ($request, $query, $value) {
return $query->where('code', '=', $value);
}),
];
}
Also you can specify another filter key over method key
.
Thanks to Brian for his support and advices.