筛选器允许你对数据定义某些约束,并让用户限定范围以查找所需信息。将它们放在 $table->filters()` 方法中。">
Skip to content
全部文档

概述

简介

筛选器允许你对数据定义某些约束,并让用户限定范围以查找所需信息。将它们放在 $table->filters() 方法中。

筛选器可使用静态 make() 方法创建,并传入唯一名称。然后应向 query() 传入回调以应用筛选器的作用域:

php
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() 方法自定义:

php
use Filament\Tables\Filters\Filter;

Filter::make('is_featured')
    ->label('Featured')

TIP

除静态值外,label() 方法也接受函数以动态计算该值。你可以将各种工具作为参数注入到函数中。

以这种方式自定义标签,在你希望使用本地化翻译字符串时很有用:

php
use Filament\Tables\Filters\Filter;

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

自定义筛选器 Schema

默认情况下,使用 Filter 类创建筛选器会渲染复选框表单组件。勾选复选框时,query() 函数会应用到表格查询,从而限定表格中的记录;取消勾选时,query() 函数会从表格查询中移除。

筛选器完全基于 Filament 的表单字段构建。它们可以渲染任意表单字段组合,用户可通过与之交互来筛选表格。

使用开关按钮代替复选框

管理筛选器所用表单字段的最简单示例,是使用 toggle() 方法将复选框替换为开关按钮

php
use Filament\Tables\Filters\Filter;

Filter::make('is_featured')
    ->toggle()
带开关筛选器的表格带开关筛选器的表格

自定义内置筛选器表单字段

无论使用复选框、开关还是选择,都可以通过 modifyFormFieldUsing() 方法自定义筛选器使用的内置表单字段。该方法接受带 $field 参数的函数,以便你访问并自定义表单字段对象:

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

Filter::make('is_featured')
    ->modifyFormFieldUsing(fn (Checkbox $field) => $field->inline(false))

TIP

传给 modifyFormFieldUsing() 的函数可以将各种工具作为参数注入。

默认应用筛选器

你可以使用 default() 方法将筛选器设为默认启用:

php
use Filament\Tables\Filters\Filter;

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

在用户会话中持久化筛选器

要在用户会话中持久化表格筛选器,请使用 persistFiltersInSession() 方法:

php
use Filament\Tables\Table;

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

实时筛选器

默认情况下,筛选器变更会被延迟,直到用户点击「Apply」按钮后才影响表格。要禁用此行为并使筛选器「实时」生效,请使用 deferFilters(false) 方法:

php
use Filament\Tables\Table;

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

自定义应用筛选器操作

延迟筛选器时,你可以使用 filtersApplyAction() 方法自定义「Apply」按钮,传入返回操作的闭包。所有可用于自定义操作触发按钮的方法都可以使用:

php
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) 方法可以禁用此行为:

php
use Filament\Tables\Table;

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

修改基础查询

默认情况下,在 query() 方法中对 Eloquent 查询的修改会应用在带作用域的 where() 子句内。这是为了确保该查询不会与可能应用的其他筛选器冲突,尤其是使用 orWhere() 的筛选器。

然而,这样做的缺点是 query() 方法无法以其他方式修改查询,例如移除全局作用域,因为需要直接修改基础查询,而非带作用域的查询。

要直接修改基础查询,可以使用 baseQuery() 方法,传入接收基础查询的闭包:

php
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() 方法标记筛选器在解析记录时被排除:

php
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() 方法,传入返回操作的闭包。所有可用于自定义操作触发按钮的方法都可以使用:

php
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() 方法,传入返回操作的闭包。所有可用于自定义操作触发按钮的方法都可以使用:

php
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'),
        );
}
带自定义移除全部筛选器操作的表格带自定义移除全部筛选器操作的表格

筛选器工具注入

绝大多数用于配置筛选器的方法都接受函数作为参数,而非硬编码值:

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

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

仅此一点就解锁了许多自定义可能性。

该包还能够将这些函数内部可用的许多工具作为参数注入。所有接受函数作为参数的自定义方法都可以注入工具。

这些注入的工具需要使用特定的参数名。否则 Filament 不知道该注入什么。

注入当前筛选器实例

若要访问当前筛选器实例,请定义 $filter 参数:

php
use Filament\Tables\Filters\BaseFilter;

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

注入当前 Livewire 组件实例

若要访问表格所属的当前 Livewire 组件实例,请定义 $livewire 参数:

php
use Filament\Tables\Contracts\HasTable;

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

注入当前表格实例

若要访问筛选器所属的当前表格配置实例,请定义 $table 参数:

php
use Filament\Tables\Table;

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

注入多个工具

参数通过反射动态注入,因此你可以按任意顺序组合多个参数:

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

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

从 Laravel 容器注入依赖

你可以像往常一样从 Laravel 容器注入任意内容,并与工具一起使用:

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

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