Languages

Version

Theme

表格 - 过滤器

概述

简介

过滤器允许你在数据上定义特定的约束条件,并允许用户设置查询范围,以查找他们需要的信息。你可以将其放在 $table->filters() 中。

过滤器可以适用静态 make() 方法创建,并传递其唯一名称。你应该传入一个回调函数给 query(),以设置过滤器的查询范围:

use Filament\Tables\Filters\Filter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;

public function table(Table $table): Table
{
    return $table
        ->filters([
            Filter::make('is_featured')
                ->query(fn (Builder $query): Builder => $query->where('is_featured', true))
            // ...
        ]);
}
Table with filter

可用过滤器

默认情况下,使用 Filter::make() 方法将会渲染一个复选框表单组件。当复选框选中时,查询(query())会被激活。

  • 你也可以使用 Toggle 替换 checkbox
  • 你也可以使用 Select 过滤器,允许用户从选项列表中选择,并使用选中的选项进行过滤。
  • 你也可以三元过滤器替换复选框,以允许用户在三种状态(通常为 “true”、“false” 及 “空值”)之间选择。这对于过滤布尔值字段非常有用。
  • 垃圾过滤器是一个预制的三元过滤器,允许你过滤可软删除的记录。
  • 查询构造器(Query builder)允许用户使用用于联合约束条件的高级用户界面创建复杂的过滤器。
  • 你也可以使用其他表单字段创建自定义过滤器

设置标签

默认情况下,过滤器的标签是基于过滤器名生成。使用 label() 方法,可以自定义标签:

use Filament\Tables\Filters\Filter;

Filter::make('is_featured')
    ->label('Featured')
As well as allowing a static value, the label() method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters. Learn more about utility injection.
Utility Type Parameter Description
Filter Filament\Tables\Filters\BaseFilter $filter The current filter instance.
Livewire Livewire\Component $livewire The Livewire component instance.
Table Filament\Tables\Table $table The current table instance.

如果你希望使用本地化翻译字符串功能,使用此方法自定义标签非常有用:

use Filament\Tables\Filters\Filter;

Filter::make('is_featured')
    ->label(__('filters.is_featured'))

自定义过滤器 Schema

默认情况下,使用 Filter 类创建过滤器将会渲染一个复选框(Checkbox)表单组件。点击复选框时,query() 函数会被应用到表格查询中,设置表格中查询记录的范围。如果取消复选框勾选,query() 函数会从表格查询中移除。

过滤器完全是基于 Filament 表单字段创建的。它们可以渲染表单字段的任何组合,使得用户可以与之交互过滤表格。

使用切换按钮替代复选框

管理用于过滤器的表单字段的最简单示例是,使用 toogle() 方法,将[复选框(checkbox)]替换成切换按钮(toogle)

use Filament\Tables\Filters\Filter;

Filter::make('is_featured')
    ->toggle()
Table with toggle filter

自定义内置过滤器表单字段

自定义内置过滤器表单字段

无论你使用的是 Checkbox、Toggle还是 Select,你可以使用 modifyFormFieldUsing() 方法,自定义过滤器使用的内置表单字段。该方法接受一个带 $field 参数的函数,此参数让你可以访问表单字段,以进行自定义:

use Filament\Forms\Components\Checkbox;
use Filament\Tables\Filters\Filter;

Filter::make('is_featured')
    ->modifyFormFieldUsing(fn (Checkbox $field) => $field->inline(false))
The function passed to modifyFormFieldUsing() can inject various utilities as parameters. Learn more about utility injection.
Utility Type Parameter Description
Field Filament\Forms\Components\Field $field The field object to modify.
Filter Filament\Tables\Filters\BaseFilter $filter The current filter instance.
Livewire Livewire\Component $livewire The Livewire component instance.
Table Filament\Tables\Table $table The current table instance.

默认应用过滤器

使用 default() 方法,你可以设置默认启用过滤器:

use Filament\Tables\Filters\Filter;

Filter::make('is_featured')
    ->default()

If you’re using a select filter, visit the “applying select filters by default” section.

在用户 Session 中持久化过滤器

要在用户 Session 中持久化表格过滤器,请使用 persistFiltersInSession() 方法:

use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->filters([
            // ...
        ])
        ->persistFiltersInSession();
}

实时过滤

默认情况下,过滤器修改是延时的,在用户点击“应用(Apply)”按钮之前不会影响表格。要禁用该特性并使之“实时”响应,请使用 deferFilters(false) 方法:

use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->filters([
            // ...
        ])
        ->deferFilters(false);
}

自定义过滤器应用操作

当延时过滤器时,使用 filtersApplyAction() 方法,并传入一个返回 Action 的闭包,你可以自定义 “Apply” 按钮。自定义 Action 触发按钮中的所有方法都可以在此使用:

use Filament\Actions\Action;
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->filters([
            // ...
        ])
        ->filtersApplyAction(
            fn (Action $action) => $action
                ->link()
                ->label('Save filters to table'),
        );
}

过滤器改变后取消记录选择

默认情况下,过滤器修改后,所有记录都会被取消选择。使用 deselectAllRecordsWhenFiltered(false) 方法,可以禁用该行为:

use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->filters([
            // ...
        ])
        ->deselectAllRecordsWhenFiltered(false);
}

修改基础查询

默认情况下,对 query() 方法执行的 Eloquent 查询所做的修改将会应用到设置查询范围的 where() 子句中。这是为了保证查询不会与其他可能应用的过滤器产生冲突,特别是那些使用 orWhere() 的查询。

不过,这样做的缺点是,不能使用 query() 方法以其他方式修改查询,比如移除全局查询范围设置,因为需要直接修改基础查询,而非范围查询。

要直接修改基础查询,请使用 baseQuery(),传入一个接收基础查询的闭包:

use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
use Filament\Tables\Filters\TernaryFilter;

TernaryFilter::make('trashed')
    // ...
    ->baseQuery(fn (Builder $query) => $query->withoutGlobalScopes([
        SoftDeletingScope::class,
    ]))

自定义过滤器触发 Action

要自定义过滤器触发按钮,你可以使用 filtersTriggerAction() 方法,传入一个返回 Action 的闭包。所有可用于自定义 Action 触发按钮的方法也可在此处使用:

use Filament\Actions\Action;
use Filament\Tables\Table;

public function table(Table $table): Table
{
    return $table
        ->filters([
            // ...
        ])
        ->filtersTriggerAction(
            fn (Action $action) => $action
                ->button()
                ->label('Filter'),
        );
}
Table with custom filters trigger action

过滤器 utility 注入

用于配置过滤器的绝大多数方法都接受函数作为参数,而不是硬编码值:

use App\Models\Author;
use Filament\Tables\Filters\SelectFilter;

SelectFilter::make('author')
    ->options(fn (): array => Author::query()->pluck('name', 'id')->all())

仅此一点就开启了许多自定义的可能性。

该包也能将许多 utility 作为参数注入到这些函数中使用。所有接受函数作为参数的自定义方法都可以注入 utility。

这些注入的 utility 要求使用特定的参数名。否则,Filament 不清楚注入的是什么。

注入当前过滤器实例

如果你想访问当前过滤器实例,请定义 $filter 参数:

use Filament\Tables\Filters\BaseFilter;

function (BaseFilter $filter) {
    // ...
}

注入当前 Livewire 组件实例

如果你希望访问表格所属的当前 Livewire 组件实例,请定义 $livewire 参数:

use Filament\Tables\Contracts\HasTable;

function (HasTable $livewire) {
    // ...
}

注入当前表格实例

如果你希望访问过滤器所属的当前表格实例,请定义 $table 参数:

use Filament\Tables\Table;

function (Table $table) {
    // ...
}

注入多个 utility

这些参数使用反射动态注入,因此你可以按照任何顺序组合多个参数:

use Filament\Tables\Contracts\HasTable;
use Filament\Tables\Table;

function (HasTable $livewire, Table $table) {
    // ...
}

注入来自 Laravel 容器的依赖

你可以像平常那样注入来自 Laravel 容器中的任何东西:

use Filament\Tables\Table;
use Illuminate\Http\Request;

function (Request $request, Table $table) {
    // ...
}
Edit on GitHub

Still need help? Join our Discord community or open a GitHub discussion

Previous
自定义列字段