概述
简介
筛选器允许你对数据定义某些约束,并让用户限定范围以查找所需信息。将它们放在 $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))
// ...
]);
}

可用筛选器
默认情况下,使用 Filter::make() 方法会渲染复选框表单组件。当复选框开启时,会激活 query()。
- 你也可以[用开关替换复选框](#using-a-toggle-button-instead-of-a-checkbox)。
- 你可以使用[选择筛选器](/5.x/tables/filters/select)让用户从选项列表中选择,并根据选择进行筛选。
- 你可以使用[三态筛选器](/5.x/tables/filters/ternary)用选择字段替换复选框,让用户在 3 种状态间选择——通常是「true」、「false」和「blank」。这对筛选布尔列很有用。
- [trashed 筛选器](/5.x/tables/filters/ternary#filtering-soft-deletable-records)是预构建的三态筛选器,可用于筛选软删除记录。
- 使用[查询构建器](/5.x/tables/filters/query-builder),用户可以创建复杂的筛选器集合,并通过高级界面组合约束。
- 你可以使用其他表单字段构建[自定义筛选器](/5.x/tables/filters/custom),实现任意需求。
设置标签
默认情况下,筛选器标签由其名称生成。你可以使用 label() 方法自定义:
use Filament\Tables\Filters\Filter;
Filter::make('is_featured')
->label('Featured')TIP
除静态值外,label() 方法也接受函数以动态计算该值。你可以将各种工具作为参数注入到函数中。
以这种方式自定义标签,在你希望使用本地化翻译字符串时很有用:
use Filament\Tables\Filters\Filter;
Filter::make('is_featured')
->label(__('filters.is_featured'))自定义筛选器 Schema
默认情况下,使用 Filter 类创建筛选器会渲染复选框表单组件。勾选复选框时,query() 函数会应用到表格查询,从而限定表格中的记录;取消勾选时,query() 函数会从表格查询中移除。
筛选器完全基于 Filament 的表单字段构建。它们可以渲染任意表单字段组合,用户可通过与之交互来筛选表格。
使用开关按钮代替复选框
use Filament\Tables\Filters\Filter;
Filter::make('is_featured')
->toggle()

自定义内置筛选器表单字段
use Filament\Forms\Components\Checkbox;
use Filament\Tables\Filters\Filter;
Filter::make('is_featured')
->modifyFormFieldUsing(fn (Checkbox $field) => $field->inline(false))TIP
传给 modifyFormFieldUsing() 的函数可以将各种工具作为参数注入。
默认应用筛选器
你可以使用 default() 方法将筛选器设为默认启用:
use Filament\Tables\Filters\Filter;
Filter::make('is_featured')
->default()若使用选择筛选器,请参阅「默认应用选择筛选器」一节。
在用户会话中持久化筛选器
要在用户会话中持久化表格筛选器,请使用 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() 方法自定义「Apply」按钮,传入返回操作的闭包。所有可用于自定义操作触发按钮的方法都可以使用:
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,
]))解析记录时排除筛选器
当用户与表格记录交互(例如点击操作按钮)时,Filament 会从数据库解析该记录。默认情况下会应用所有活动筛选器条件,确保用户无法访问筛选范围之外的记录。
然而,像 TrashedFilter 这类筛选器修改的是全局作用域,而非限制访问。当记录状态在用户于表格中看到之后发生变化时,你可能仍希望用户能与之交互。
你可以使用 excludeWhenResolvingRecord() 方法标记筛选器在解析记录时被排除:
use Filament\Tables\Filters\Filter;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletingScope;
Filter::make('trashed')
->query(fn (Builder $query) => $query->onlyTrashed())
->baseQuery(fn (Builder $query) => $query->withoutGlobalScopes([
SoftDeletingScope::class,
]))
->excludeWhenResolvingRecord()使用 excludeWhenResolvingRecord() 时:
- 解析记录时不应用筛选器的 `query()` 回调
- 解析记录时仍应用筛选器的 `baseQuery()` 回调
DANGER
不要在强制执行授权规则的筛选器上使用 excludeWhenResolvingRecord()。例如,若筛选器按租户或用户所有权限制记录,这些筛选器应保持强制执行,以防止未授权访问。
自定义筛选器触发操作
要自定义筛选器触发按钮,可以使用 filtersTriggerAction() 方法,传入返回操作的闭包。所有可用于自定义操作触发按钮的方法都可以使用:
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'),
);
}

自定义移除全部筛选器操作
要自定义从指示器栏移除所有活动筛选器的操作,可以使用 filtersRemoveAllAction() 方法,传入返回操作的闭包。所有可用于自定义操作触发按钮的方法都可以使用:
use Filament\Actions\Action;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->filters([
// ...
])
->filtersRemoveAllAction(
fn (Action $action) => $action
->tooltip('Clear filters'),
);
}

筛选器工具注入
绝大多数用于配置筛选器的方法都接受函数作为参数,而非硬编码值:
use App\Models\Author;
use Filament\Tables\Filters\SelectFilter;
SelectFilter::make('author')
->options(fn (): array => Author::query()->pluck('name', 'id')->all())仅此一点就解锁了许多自定义可能性。
该包还能够将这些函数内部可用的许多工具作为参数注入。所有接受函数作为参数的自定义方法都可以注入工具。
这些注入的工具需要使用特定的参数名。否则 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) {
// ...
}注入多个工具
参数通过反射动态注入,因此你可以按任意顺序组合多个参数:
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) {
// ...
}