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-filterYou 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
valueneed pass as array key andlabelas 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
freshmethod 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.