重复器
简介
重复器组件可让你输出由重复表单组件组成的 JSON 数组。
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
Repeater::make('members')
->schema([
TextInput::make('name')->required(),
Select::make('role')
->options([
'member' => 'Member',
'administrator' => 'Administrator',
'owner' => 'Owner',
])
->required(),
])
->columns(2)

我们建议将重复器数据存储在数据库的 JSON 列中。此外,若使用 Eloquent,请确保该列有 array 类型转换。
如上例所示,组件 schema 可在组件的 schema() 方法中定义:
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
Repeater::make('members')
->schema([
TextInput::make('name')->required(),
// ...
])若希望定义可按任意顺序重复的多个 schema 块的重复器,请使用 构建器。
设置空的默认项
重复器可以默认创建一定数量的空项。默认值仅在 schema 加载时无数据的情况下使用。在标准 面板资源 中,默认值用于创建页,而非编辑页。要使用默认项,请将项数传给 defaultItems() 方法:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->defaultItems(3)TIP
除了允许静态值外,defaultItems() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
添加项
重复器下方会显示一个操作按钮,允许用户添加新项。
设置添加操作按钮的标签
你可以使用 addActionLabel() 方法设置标签,以自定义添加重复器项的按钮上显示的文本:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->addActionLabel('Add member')TIP
除了允许静态值外,addActionLabel() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
对齐添加操作按钮
默认情况下,添加操作居中对齐。你可以使用 addActionAlignment() 方法调整,传入 Alignment::Start 或 Alignment::End 的 Alignment 选项:
use Filament\Forms\Components\Repeater;
use Filament\Support\Enums\Alignment;
Repeater::make('members')
->schema([
// ...
])
->addActionAlignment(Alignment::Start)TIP
除了允许静态值外,addActionAlignment() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。


阻止用户添加项
你可以使用 addable(false) 方法阻止用户向重复器添加项:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->addable(false)TIP
除了允许静态值外,addable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
删除项
每项上会显示一个操作按钮,允许用户删除该项。
阻止用户删除项
你可以使用 deletable(false) 方法阻止用户从重复器中删除项:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->deletable(false)TIP
除了允许静态值外,deletable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
重新排序项
每项上会显示一个按钮,允许用户拖放以在列表中重新排序。
阻止用户重新排序项
你可以使用 reorderable(false) 方法阻止用户重新排序重复器中的项:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->reorderable(false)TIP
除了允许静态值外,reorderable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
使用按钮重新排序项
你可以使用 reorderableWithButtons() 方法,启用通过上移/下移按钮重新排序项:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->reorderableWithButtons()

你也可以传入布尔值,以控制重复器是否应使用按钮排序:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->reorderableWithButtons(FeatureFlag::active())TIP
除了允许静态值外,reorderableWithButtons() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
阻止拖放重新排序
你可以使用 reorderableWithDragAndDrop(false) 方法阻止通过拖放排序项:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->reorderableWithDragAndDrop(false)TIP
除了允许静态值外,reorderableWithDragAndDrop() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
折叠项
重复器可设为 collapsible(),以便在长表单中按需隐藏内容:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->schema([
// ...
])
->collapsible()

你也可以默认折叠所有项:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->schema([
// ...
])
->collapsed()

你也可以向 collapsible() 和 collapsed() 方法传入布尔值,以控制重复器是否可折叠以及是否默认折叠:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->schema([
// ...
])
->collapsible(FeatureFlag::active())
->collapsed(FeatureFlag::active())TIP
除了允许静态值外,collapsible() 和 collapsed() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。
若折叠项包含渲染成本高的组件,可 延迟加载其 schema,直到展开时再加载。
延迟加载重复器项 schema
若重复器的项 schema 渲染成本高,可将 Schema 对象传给 schema() 并使用 deferLoading()。当项默认 折叠 时尤其有用。每个项的 schema 会在该项展开并进入视口时独立加载:
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Schemas\Schema;
Repeater::make('members')
->schema(
Schema::make()
->components([
TextInput::make('name'),
TextInput::make('email')
->email(),
])
->deferLoading(),
)
->collapsed()重复器项 schema 会自动从其项状态路径获得唯一键。关于延迟 schema 的更多信息,请参阅 schema 概览。
克隆项
你可以使用 cloneable() 方法允许复制重复器项:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->schema([
// ...
])
->cloneable()

你也可以向 cloneable() 方法传入布尔值,以控制重复器是否可克隆:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->schema([
// ...
])
->cloneable(FeatureFlag::active())TIP
除了允许静态值外,cloneable() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
与 Eloquent 关系集成
你可以使用 Repeater 的 relationship() 方法配置 HasMany 关系。Filament 会从该关系加载项数据,并在提交表单时写回关系。若未向 relationship() 传入自定义关系名,Filament 将使用字段名作为关系名:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->relationship()
->schema([
// ...
])在关系中重新排序项
默认情况下,关系重复器项的 重新排序 是禁用的。因为相关模型需要一个 sort 列来存储相关记录的顺序。要启用重新排序,可使用 orderColumn() 方法,传入相关模型上用于存储顺序的列名:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->relationship()
->schema([
// ...
])
->orderColumn('sort')若使用类似 spatie/eloquent-sortable 且排序列为 order_column,可将其传入 orderColumn():
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->relationship()
->schema([
// ...
])
->orderColumn('order_column')TIP
除了允许静态值外,orderColumn() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
与 BelongsToMany Eloquent 关系集成
有一种常见误解:对重复器使用 BelongsToMany 关系就像使用 HasMany 一样简单。事实并非如此,因为 BelongsToMany 关系需要中间表存储关系数据。重复器将其数据保存到相关模型,而非中间表。因此,若希望将每个重复器项映射到中间表的一行,必须通过带 pivot 模型的 HasMany 关系,才能在 BelongsToMany 场景中使用重复器。
假设你有一个创建新 Order 模型的表单。每个订单属于多个 Product 模型,每个产品也属于多个订单。你有一张 order_product 中间表存储关系数据。与其在重复器上使用 products 关系,不如在 Order 模型上新建名为 orderProducts 的关系,并用于重复器:
use Illuminate\Database\Eloquent\Relations\HasMany;
public function orderProducts(): HasMany
{
return $this->hasMany(OrderProduct::class);
}若尚无 OrderProduct pivot 模型,应创建它,并建立到 Order 和 Product 的反向关系:
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\Pivot;
class OrderProduct extends Pivot
{
public $incrementing = true;
public function order(): BelongsTo
{
return $this->belongsTo(Order::class);
}
public function product(): BelongsTo
{
return $this->belongsTo(Product::class);
}
}INFO
请确保 pivot 模型有主键列(如 id),以便 Filament 跟踪哪些重复器项已创建、更新和删除。为确保 Filament 能跟踪主键,pivot 模型需将 $incrementing 属性设为 true。
现在你可以在重复器上使用 orderProducts 关系,数据将保存到 order_product 中间表:
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
Repeater::make('orderProducts')
->relationship()
->schema([
Select::make('product_id')
->relationship('product', 'name')
->required(),
// ...
])在填充字段前变更相关项数据
你可以使用 mutateRelationshipDataBeforeFillUsing() 方法,在相关项数据填充到字段之前对其进行变更。该方法接受一个闭包,通过 $data 变量接收当前项的数据。你必须返回修改后的数据数组:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->relationship()
->schema([
// ...
])
->mutateRelationshipDataBeforeFillUsing(function (array $data): array {
$data['user_id'] = auth()->id();
return $data;
})TIP
你可以将各种工具作为参数注入到传递给 mutateRelationshipDataBeforeFillUsing() 的函数中。
在创建前变更相关项数据
你可以使用 mutateRelationshipDataBeforeCreateUsing() 方法,在新相关项写入数据库之前变更其数据。该方法接受一个闭包,通过 $data 变量接收当前项的数据。你可以返回修改后的数据数组,或返回 null 以阻止创建该项:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->relationship()
->schema([
// ...
])
->mutateRelationshipDataBeforeCreateUsing(function (array $data): array {
$data['user_id'] = auth()->id();
return $data;
})TIP
你可以将各种工具作为参数注入到传递给 mutateRelationshipDataBeforeCreateUsing() 的函数中。
在保存前变更相关项数据
你可以使用 mutateRelationshipDataBeforeSaveUsing() 方法,在已有相关项保存到数据库之前变更其数据。该方法接受一个闭包,通过 $data 变量接收当前项的数据。你可以返回修改后的数据数组,或返回 null 以阻止保存该项:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->relationship()
->schema([
// ...
])
->mutateRelationshipDataBeforeSaveUsing(function (array $data): array {
$data['user_id'] = auth()->id();
return $data;
})TIP
你可以将各种工具作为参数注入到传递给 mutateRelationshipDataBeforeSaveUsing() 的函数中。
在创建相关项后运行代码
你可以使用 afterCreate() 方法,在新相关项创建到数据库之后运行代码。该方法接受一个闭包,通过 $data 变量接收当前项数据,通过 $record 变量接收新创建的记录。当你需要记录 ID 以执行附加操作(如关联 pivot 数据)时很有用:
use Filament\Forms\Components\Repeater;
use Illuminate\Database\Eloquent\Model;
Repeater::make('variants')
->relationship()
->schema([
// ...
])
->afterCreate(function (array $data, Model $record): void {
if (isset($data['attributes'])) {
$record->attributes()->attach($data['attributes']);
}
})TIP
你可以将各种工具作为参数注入到传递给 afterCreate() 的函数中。
在更新相关项后运行代码
你可以使用 afterUpdate() 方法,在已有相关项更新到数据库之后运行代码。该方法接受一个闭包,通过 $data 变量接收当前项数据,通过 $record 变量接收已更新的记录:
use Filament\Forms\Components\Repeater;
use Illuminate\Database\Eloquent\Model;
Repeater::make('variants')
->relationship()
->schema([
// ...
])
->afterUpdate(function (array $data, Model $record): void {
if (isset($data['attributes'])) {
$record->attributes()->sync($data['attributes']);
}
})TIP
你可以将各种工具作为参数注入到传递给 afterUpdate() 的函数中。
在删除相关项后运行代码
你可以使用 afterDelete() 方法,在相关项从数据库删除之后运行代码。该方法接受一个闭包,通过 $record 变量接收刚删除的记录。此时记录已不在数据库中,但仍可访问其属性(如 ID):
use Filament\Forms\Components\Repeater;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Storage;
Repeater::make('attachments')
->relationship()
->schema([
// ...
])
->afterDelete(function (Model $record): void {
Storage::delete($record->file_path);
})TIP
你可以将各种工具作为参数注入到传递给 afterDelete() 的函数中。
在检索后修改相关记录
你可以使用 modifyRecordsUsing 参数,在从数据库检索后筛选或修改重复器的相关记录。该方法接受一个接收相关记录 Collection 的函数。你应返回修改后的集合。
这在将记录限制到特定分组或类别时尤其有用,且不必在数据库查询本身中完成——若记录已预加载,在查询中过滤会触发额外查询:
use Filament\Forms\Components\Repeater;
use Illuminate\Database\Eloquent\Collection;
Repeater::make('startItems')
->relationship(name: 'items', modifyRecordsUsing: fn (Collection $records): Collection => $records->where('group', 'start')),
Repeater::make('endItems')
->relationship(name: 'items', modifyRecordsUsing: fn (Collection $records): Collection => $records->where('group', 'end')),TIP
你可以将各种工具作为参数注入到传递给 modifyRecordsUsing 的函数中。
网格布局
你可以使用 grid() 方法将重复器项组织为多列:
use Filament\Forms\Components\Repeater;
Repeater::make('qualifications')
->schema([
// ...
])
->grid(2)

该方法接受与 网格 的 columns() 方法相同的选项。这允许你在不同断点响应式地自定义网格列数。
TIP
除了允许静态值外,grid() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
根据内容为重复器项添加标签
你可以使用 itemLabel() 方法为重复器项添加标签。该方法接受一个闭包,通过 $state 变量接收当前项的数据。你必须返回用作项标签的字符串:
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Forms\Components\Select;
Repeater::make('members')
->schema([
TextInput::make('name')
->required()
->live(onBlur: true),
Select::make('role')
->options([
'member' => 'Member',
'administrator' => 'Administrator',
'owner' => 'Owner',
])
->required(),
])
->columns(2)
->itemLabel(fn (array $state): ?string => $state['name'] ?? null),TIP
若希望在使用表单时实时更新项标签,从 $state 使用的任何字段都应设为 live()。
TIP
你可以将各种工具作为参数注入到传递给 itemLabel() 的函数中。


为重复器项编号
你可以使用 itemNumbers() 方法在项标签旁添加重复器项编号:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->itemNumbers()

单字段简易重复器
你可以使用 simple() 方法创建仅含单个字段、采用精简设计的重复器
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
Repeater::make('invitations')
->simple(
TextInput::make('email')
->email()
->required(),
)TIP
除了允许静态值外,simple() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。


简易重复器使用扁平值数组而非嵌套数组存储数据。这意味着上例的数据结构可能如下:
[
'invitations' => [
'dan@filamentphp.com',
'ryan@filamentphp.com',
],
],使用 $get() 访问父级字段值
所有表单组件都能 使用 $get() 和 $set() 访问另一字段的值。但在重复器的 schema 内使用时,可能会遇到意外行为。
因为 $get() 和 $set() 默认作用域为当前重复器项。这意味着你可以轻松与该重复器项内的另一字段交互,而无需知道当前表单组件属于哪一项。
其后果是,当你无法与重复器外的字段交互时可能会感到困惑。我们使用 ../ 语法解决此问题——$get('../parent_field_name')。
假设你的表单有如下数据结构:
[
'client_id' => 1,
'repeater' => [
'item1' => [
'service_id' => 2,
],
],
]你正尝试从重复器项内部检索 client_id 的值。
$get() 相对于当前重复器项,因此 $get('client_id') 实际在查找 $get('repeater.item1.client_id')。
你可以使用 ../ 在数据结构中上移一层,因此 $get('../client_id') 即 $get('repeater.client_id'),而 $get('../../client_id') 即 $get('client_id')。
无参的 $get(),或 $get('') / $get('./') 这一特殊情况,将始终返回当前重复器项的完整数据数组。
表格重复器
你可以使用 table() 方法以表格形式呈现重复器项,该方法接受 TableColumn 对象数组。这些对象表示表格的列,对应重复器 schema 中的各个组件:
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Repeater\TableColumn;
use Filament\Forms\Components\Select;
use Filament\Forms\Components\TextInput;
Repeater::make('members')
->table([
TableColumn::make('Name'),
TableColumn::make('Role'),
])
->schema([
TextInput::make('name')
->required(),
Select::make('role')
->options([
'member' => 'Member',
'administrator' => 'Administrator',
'owner' => 'Owner',
])
->required(),
])

表头中显示的标签会传给 TableColumn::make() 方法。若希望为列提供无访问标签但不显示,可使用 hiddenHeaderLabel() 方法:
use Filament\Forms\Components\Repeater\TableColumn;
TableColumn::make('Name')
->hiddenHeaderLabel()若希望用红色星号将列标记为「必填」,可使用 markAsRequired() 方法:
use Filament\Forms\Components\Repeater\TableColumn;
TableColumn::make('Name')
->markAsRequired()你可以使用 wrapHeader() 方法启用列标题换行:
use Filament\Forms\Components\Repeater\TableColumn;
TableColumn::make('Name')
->wrapHeader()你也可以使用 alignment() 方法调整列标题对齐方式,传入 Alignment::Start、Alignment::Center 或 Alignment::End:
use Filament\Forms\Components\Repeater\TableColumn;
use Filament\Support\Enums\Alignment;
TableColumn::make('Name')
->alignment(Alignment::Start)你可以使用 width() 方法设置固定列宽,传入表示列宽的字符串。该值会直接传给列标题的 style 属性:
use Filament\Forms\Components\Repeater\TableColumn;
TableColumn::make('Name')
->width('200px')紧凑表格重复器
你可以使用 compact() 方法让表格重复器更紧凑,以便在更小空间中容纳更多数据:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->table([
// ...
])
->compact()
->schema([
// ...
])你也可以传入布尔值,以控制表格重复器是否紧凑:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->table([
// ...
])
->compact(FeatureFlag::active())
->schema([
// ...
])TIP
除了允许静态值外,compact() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。


重复器校验
除了 校验 页面列出的全部规则外,还有专门针对重复器的额外规则。
项数量校验
你可以通过设置 minItems() 和 maxItems() 方法校验重复器中可有的最小与最大项数:
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->minItems(2)
->maxItems(5)TIP
除了允许静态值外,minItems() 和 maxItems() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到这些函数中。
互斥状态校验
在许多情况下,你希望确保重复器项之间具有某种唯一性。几个常见例子包括:
- 确保重复器各项中同一时间只有一个 [复选框](/5.x/forms/checkbox) 或 [开关](/5.x/forms/toggle) 被激活。
- 确保某个选项在重复器中的 [选择框](/5.x/forms/select)、[单选](/5.x/forms/radio)、[复选框列表](/5.x/forms/checkbox-list) 或 [切换按钮](/5.x/forms/toggle-buttons) 字段中只能被选择一次。
你可以使用 distinct() 方法校验某字段状态在重复器所有项中唯一:
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Repeater;
Repeater::make('answers')
->schema([
// ...
Checkbox::make('is_correct')
->distinct(),
])distinct() 校验的行为取决于字段处理的数据类型
- 若字段返回布尔值,如 [复选框](/5.x/forms/checkbox) 或 [开关](/5.x/forms/toggle),校验将确保只有一项的值为 `true`。重复器中可以有许多字段值为 `false`。
- 否则,对于 [选择框](/5.x/forms/select)、[单选](/5.x/forms/radio)、[复选框列表](/5.x/forms/checkbox-list) 或 [切换按钮](/5.x/forms/toggle-buttons) 等字段,校验将确保每个选项在重复器所有项中只能被选择一次。
你也可以向 distinct() 方法传入布尔值,以控制字段是否应互斥:
use Filament\Forms\Components\Checkbox;
Checkbox::make('is_correct')
->distinct(FeatureFlag::active())TIP
除了允许静态值外,distinct() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
自动修复非互斥状态
若希望自动修复非互斥状态,可使用 fixIndistinctState() 方法:
use Filament\Forms\Components\Checkbox;
use Filament\Forms\Components\Repeater;
Repeater::make('answers')
->schema([
// ...
Checkbox::make('is_correct')
->fixIndistinctState(),
])此方法会自动在字段上启用 distinct() 和 live()。
根据字段处理的数据类型,fixIndistinctState() 的行为会相应调整:
- 若字段返回布尔值,如 [复选框](/5.x/forms/checkbox) 或 [开关](/5.x/forms/toggle),且其中一个字段被启用,Filament 会代表用户自动禁用所有其他已启用的字段。
- 否则,对于 [选择框](/5.x/forms/select)、[单选](/5.x/forms/radio)、[复选框列表](/5.x/forms/checkbox-list) 或 [切换按钮](/5.x/forms/toggle-buttons) 等字段,当用户选择某个选项时,Filament 会代表用户自动取消该选项在其他位置的选择。
你也可以向 fixIndistinctState() 方法传入布尔值,以控制字段是否应修复非互斥状态:
use Filament\Forms\Components\Checkbox;
Checkbox::make('is_correct')
->fixIndistinctState(FeatureFlag::active())TIP
除了允许静态值外,fixIndistinctState() 方法也接受函数以动态计算。你可以将各种工具作为参数注入到该函数中。
在其他项已选时禁用选项
若希望在 选择框、单选、复选框列表 或 切换按钮 中,当选项已在其他项中被选中时将其禁用,可使用 disableOptionsWhenSelectedInSiblingRepeaterItems() 方法:
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
Repeater::make('members')
->schema([
Select::make('role')
->options([
// ...
])
->disableOptionsWhenSelectedInSiblingRepeaterItems(),
])此方法会自动在字段上启用 distinct() 和 live()。
WARNING
若还想添加其他 禁用选项 的条件,可以链式调用带 merge: true 参数的 disableOptionWhen():
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\Select;
Repeater::make('members')
->schema([
Select::make('role')
->options([
// ...
])
->disableOptionsWhenSelectedInSiblingRepeaterItems()
->disableOptionWhen(fn (string $value): bool => $value === 'super_admin', merge: true),
])自定义重复器项操作
此字段使用 action 对象,便于自定义其中的按钮。你可以通过向操作注册方法传入函数来自定义这些按钮。该函数可访问 $action 对象,用于 自定义它。以下方法可用于自定义操作:
addAction()cloneAction()collapseAction()collapseAllAction()deleteAction()expandAction()expandAllAction()moveDownAction()moveUpAction()reorderAction()
以下是自定义操作的示例:
use Filament\Actions\Action;
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->collapseAllAction(
fn (Action $action) => $action->label('Collapse all members'),
)TIP
操作注册方法可以将各种工具作为参数注入到函数中。
用模态确认重复器操作
你可以通过在 action 对象上使用 requiresConfirmation() 方法,用模态确认操作。你可以使用任意 模态自定义方法 更改其内容与行为:
use Filament\Actions\Action;
use Filament\Forms\Components\Repeater;
Repeater::make('members')
->schema([
// ...
])
->deleteAction(
fn (Action $action) => $action->requiresConfirmation(),
)INFO
collapseAction()、collapseAllAction()、expandAction()、expandAllAction() 和 reorderAction() 方法不支持确认模态,因为点击其按钮不会发起显示模态所需的网络请求。
向重复器添加额外项操作
你可以通过将 Action 对象传入 extraItemActions(),在每个重复器项的标题栏添加新的 操作按钮:
use Filament\Actions\Action;
use Filament\Forms\Components\Repeater;
use Filament\Forms\Components\TextInput;
use Filament\Support\Icons\Heroicon;
use Illuminate\Support\Facades\Mail;
Repeater::make('members')
->schema([
TextInput::make('email')
->label('Email address')
->email(),
// ...
])
->extraItemActions([
Action::make('sendEmail')
->icon(Heroicon::Envelope)
->action(function (array $arguments, Repeater $component): void {
$itemData = $component->getItemState($arguments['item']);
Mail::to($itemData['email'])
->send(
// ...
);
}),
])在此示例中,$arguments['item'] 给出当前重复器项的 ID。你可以使用重复器组件上的 getItemState() 方法校验该重复器项中的数据。该方法返回该项的已校验数据。若该项无效,将取消操作并在表单中为该项显示错误消息。
若希望获取当前项的原始数据而不校验,可改用 $component->getRawItemState($arguments['item'])。
若希望操作整个重复器的原始数据,例如添加、移除或修改项,可以使用 $component->getState() 获取数据,再用 $component->state($state) 重新设置:
use Illuminate\Support\Str;
// Get the raw data for the entire repeater
$state = $component->getState();
// Add an item, with a random UUID as the key
$state[Str::uuid()] = [
'email' => auth()->user()->email,
];
// Set the new data for the repeater
$component->state($state);