Select
概述
Select 组件允许你从一组预定义的选项列表中进行选择:
use Filament\Forms\Components\Select;
Select::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
启用 JavaScript 下拉列表
默认情况下,Filament 使用本机 HTML5 下拉列表。使用 native(false)
方法,你可以启用更可自定义的 Javascript 下拉列表:
use Filament\Forms\Components\Select;
Select::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->native(false)
搜索选项
使用 searchable()
方法,你可以启用搜索框,以方 便获取选项:
use Filament\Forms\Components\Select;
Select::make('author_id')
->label('Author')
->options(User::all()->pluck('name', 'id'))
->searchable()
返回自定义搜索结果
如果你有很多选项并想要基于数据库搜索或者其他外部数据源弹出数据,你可以使用 getSearchResultsUsing()
和 getOptionLabelUsing()
方法,而不是 options()
。
getSearchResultsUsing()
方法接收一个返回 $key => $value
格式搜索结果的回调函数。当前用户搜索可通过 $search
获取,你应该使用它来过滤结果。
getOptionLabelUsing()
方法接收一个将选中的选项 $value
转换成标签的回调函数。它用在表单初次加载,用户还未进行搜索时。否则用于展示当前 选择选项的标签将会不可用。
如果你想提供自定义搜索结果,则必须在下拉列表中同时使用 getSearchResultsUsing()
和 getOptionLabelUsing()
:
Select::make('author_id')
->searchable()
->getSearchResultsUsing(fn (string $search): array => User::where('name', 'like', "%{$search}%")->limit(50)->pluck('name', 'id')->toArray())
->getOptionLabelUsing(fn ($value): ?string => User::find($value)?->name),
Multi-select
在 Select
组件上使用 multiple()
方法,允许你从列表中选择多个值:
use Filament\Forms\Components\Select;
Select::make('technologies')
->multiple()
->options([
'tailwind' => 'Tailwind CSS',
'alpine' => 'Alpine.js',
'laravel' => 'Laravel',
'livewire' => 'Laravel Livewire',
])
这些选项以 JSON 格式返回。如果你使用 Eloquent 保存,请确保将 array
cast 添加到对应的模型属性上:
use Illuminate\Database\Eloquent\Model;
class App extends Model
{
protected $casts = [
'technologies' => 'array',
];
// ...
}
如果你要返回自定义搜索结果,应该定义 getOptionLabelsUsing()
而非 getSearchResultsUsing()
。将 $values
而非 $value
传递给回调函数,你应该返回包含标签及其对应值的 $key => $value
标签数组:
Select::make('technologies')
->multiple()
->searchable()
->getSearchResultsUsing(fn (string $search): array => Technology::where('name', 'like', "%{$search}%")->limit(50)->pluck('name', 'id')->toArray())
->getOptionLabelsUsing(fn (array $values): array => Technology::whereIn('id', $values)->pluck('name', 'id')->toArray()),
选项分组
你可以将选项组合到一个标签下面,以便更好地组织它们。为此,请将分组数组传递给 options()
或者其他你通常会传递选项数组的地方。数组的键作为分组标签,数组值是该分组中的选项数组:
use Filament\Forms\Components\Select;
Select::make('status')
->searchable()
->options([
'In Process' => [
'draft' => 'Draft',
'reviewing' => 'Reviewing',
],
'Reviewed' => [
'published' => 'Published',
'rejected' => 'Rejected',
],
])
集成 Eloquent 关联
如果你在 Livewire 组件内创建表单,请确保设置好表单模型。否则,Filament 不知 道应该使用哪个模型来检索关联。
你可以使用 Select
的 relationship()
方法来配置 BelongsTo
关联,以自动检索选项。titleAttribute
是用于为每个选项生成标签的字段名:
use Filament\Forms\Components\Select;
Select::make('author_id')
->relationship(name: 'author', titleAttribute: 'name')
multiple()
方法可以和 relationship()
一起使用,用于 BelongsToMany
关联。Filament 会自动从关联中加载选项,并且在表单提交后将其保存回关联的中间表。如果没有提供 name
,Filament 将回使用关联名作为字段名:
use Filament\Forms\Components\Select;
Select::make('technologies')
->multiple()
->relationship(titleAttribute: 'name')
当 disabled()
和 relationship()
一起使用时,请确保 disabled()
的调用在 relationship()
之前。这可以确保在 relationship()
中进行 dehydrated()
调用不会被 disabled()
调用覆盖:
use Filament\Forms\Components\Select;
Select::make('technologies')
->multiple()
->disabled()
->relationship(titleAttribute: 'name')
在多个字段中搜索关联选项
默认情况下,如果 Select 也是可搜索的,Filament 将会基于关联的标题字段返回关联的搜索结果。如果你想在多个列中搜索,你可以将字段数组传递给 searchable()
方法:
use Filament\Forms\Components\Select;
Select::make('author_id')
->relationship(name: 'author', titleAttribute: 'name')
->searchable(['name', 'email'])
预加载关联选项
如果你希望在页面加载时弹出可搜索的选项,而不是在用户搜索时才弹出选项,你可以使用 preload()
方法:
use Filament\Forms\Components\Select;
Select::make('author_id')
->relationship(name: 'author', titleAttribute: 'name')
->searchable()
->preload()
排除当前记
当使用递归关联时,你可能希望从结果集中移除当前记录。
可以使用 ignoreRecord
参数实现该功能:
use Filament\Forms\Components\Select;
Select::make('parent_id')
->relationship(name: 'parent', titleAttribute: 'name', ignoreRecord: true)
自定义关联查询
你可以使用 relationship()
的第三个参数,自定义检索选项的数据库查询:
use Filament\Forms\Components\Select;
use Illuminate\Database\Eloquent\Builder;
Select::make('author_id')
->relationship(
name: 'author',
titleAttribute: 'name',
modifyQueryUsing: fn (Builder $query) => $query->withTrashed(),
)