布局

开始

布局组件类可在 Filament\Form\Components 命名空间里找到。

布局组件存放于表单 schema 中,和表单字段一起。

如果你在 Livewire 组件中使用布局组件,你可以将它们放在 getFormSchema() 方法中:

protected function getFormSchema(): array
{
return [
// ...
];
}

如果你在后台面板的资源或者关联管理器中使用,你必须将他们放在 $form->schema() 方法中:

public static function form(Form $form): Form
{
return $form
->schema([
// ...
]);
}

组件可以使用静态 make() 方法创建。通常,你随后可以定义子组件内部显示的 schema()

use Filament\Forms\Components\Grid;
 
Grid::make()
->schema([
// ...
])

列数

你可以使用 columns() 方法,在每个布局组件内部创建多个列。

use Filament\Forms\Components\Card;
 
Card::make()->columns(2)

更多关于创建高级、自适应的列布局信息,请移步网格区域。所有该区域的列选项同样对其他布局组件有效。

控制字段宽度

你可以指定组件在父级网格中占据的列宽数:

use Filament\Forms\Components\Grid;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
 
Grid::make(3)
->schema([
TextInput::make('name')
->columnSpan(2),
// ...
])

你也可以使用 columnSpan('full') 指定列宽为父级网格的全宽,无论其有多少列宽:

use Filament\Forms\Components\Grid;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\TextInput;
 
Grid::make(3)
->schema([
TextInput::make('name')
->columnSpan('full'),
// ...
])

另外,你也可以定义组件在不同临界点占用多少列宽:

use Filament\Forms\Components\Grid;
use Filament\Forms\Components\TextInput;
 
Grid::make([
'default' => 1,
'sm' => 3,
'xl' => 6,
'2xl' => 8,
])
->schema([
TextInput::make('name')
->columnSpan([
'sm' => 2,
'xl' => 3,
'2xl' => 4,
]),
// ...
])

设置ID

你可以使用 id() 方法为组件定义ID:

use Filament\Forms\Components\Card;
 
Card::make()->id('main-card')

自定义属性

HTML组件可以进一步自定义,通过传入一个数组到 extraAttributes():

use Filament\Forms\Components\Card;
 
Card::make()->extraAttributes(['class' => 'bg-gray-50'])

全局设置

如果你想要全局修改组件的默认行为,你可以在服务提供者的 boot() 方法中调用静态方法 configrueUsing(),传入闭包修改其使用的组件。比如,你想让所有的卡片组件默认为2列,你可以这样做:

use Filament\Forms\Components\Card;
 
Card::configureUsing(function (Card $card): void {
$card->columns(2);
});

当然,你仍然可以对每个字段单独进行重写:

use Filament\Forms\Components\Card;
 
Card::make()->columns(1)

保存数据到关联模型

使用 relationship() 方法,你可以加载或者保存布局组件的内容到 HasOneBelongsToMorphOne 的关联模型中:

use Filament\Forms\Components\Fieldset;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Textarea;
use Filament\Forms\Components\TextInput;
 
Fieldset::make('Metadata')
->relationship('metadata')
->schema([
TextInput::make('title'),
Textarea::make('description'),
FileUpload::make('image'),
])

此例中,titledescriptionimage 会被自动加载保存到 metadata 关联模型中,当表单提交时会被再次保存。如果 metadata 记录不存在,就自动生成。

要启用这个功能,你必须按照关系型字段设置的指示。如果你使用了后台面板,可以跳过此步。

网格

通常,表单字段以单列的形式堆叠在其他字段之上。要做调整,你可以使用网格(Grid)组件:

use Filament\Forms\Components\Grid;
 
Grid::make()
->schema([
// ...
])

默认情况下,网格组件会产生一个两列的网格适应Tailwind的md或更高的临界点

你可以这样传入数字指定网格 md 临界点的列宽数:

use Filament\Forms\Components\Grid;
 
Grid::make(3)
->schema([
// ...
])

要以不同临界点中自定义网格中的列数,你可以传入一个临界点和列数组成的数组:

use Filament\Forms\Components\Grid;
 
Grid::make([
'default' => 1,
'sm' => 2,
'md' => 3,
'lg' => 4,
'xl' => 6,
'2xl' => 8,
])
->schema([
// ...
])

由于 Tailwind 是移动端优先,如果你忽略临界点,它就会使用它下面那个:

use Filament\Forms\Components\Grid;
 
Grid::make([
'sm' => 2,
'xl' => 6,
])
->schema([
// ...
])

字段集

你可以对字段进行分组归入字段集中。每个字段集(Fieldset)默认都有一个标签、一条边线、和一个两栏的网格:

use Filament\Forms\Components\Fieldset;
 
Fieldset::make('Label')
->schema([
// ...
])

你可以使用 columns() 方法自定义字段集里的网格:

use Filament\Forms\Components\Fieldset;
 
Fieldset::make('Label')
->schema([
// ...
])
->columns(3)

标签页

有些表格比较长、比较复杂。你可以使用标签页(Tabs)来减少组件一次性可见的数量:

use Filament\Forms\Components\Tabs;
 
Tabs::make('Heading')
->tabs([
Tabs\Tab::make('Label 1')
->schema([
// ...
]),
Tabs\Tab::make('Label 2')
->schema([
// ...
]),
Tabs\Tab::make('Label 3')
->schema([
// ...
]),
])

默认情况下会打开第一个标签页。使用 activeTab() 方法可以改变默认打开的标签页:

use Filament\Forms\Components\Tabs;
 
Tabs::make('Heading')
->tabs([
Tabs\Tab::make('Label 1')
->schema([
// ...
]),
Tabs\Tab::make('Label 2')
->schema([
// ...
]),
Tabs\Tab::make('Label 3')
->schema([
// ...
]),
])
->activeTab(2)

使用 icon()badge() 方法,可以为标签页设置图标和徽章:

use Filament\Forms\Components\Tabs;
 
Tabs::make('Heading')
->tabs([
Tabs\Tab::make('Notifications')
->icon('heroicon-o-bell')
->badge('39')
->schema([
// ...
]),
// ...
])

Wizard

类似于标签页,你可能想要使用多步骤的表单向导(Wizard),减少组件的一次性的可见数量。这对于表单中有明显时间先后顺序的处理步骤,尤其有用。

use Filament\Forms\Components\Wizard;
 
Wizard::make([
Wizard\Step::make('Order')
->schema([
// ...
]),
Wizard\Step::make('Delivery')
->schema([
// ...
]),
Wizard\Step::make('Billing')
->schema([
// ...
]),
])

对于后台面板资源创建页及表格操作,我们提供了不同的操作指南。按照对应的文档能够确保将表单提交只在最后一步可用。

每一步都必须有一个标签。你也可以添加描述(description)提供额外信息:

use Filament\Forms\Components\Wizard;
 
Wizard\Step::make('Order')
->description('Review your basket')
->schema([
// ...
]),

步骤也可以有图标,图标可以是任何的 Blade 图标组件:

use Filament\Forms\Components\Wizard;
 
Wizard\Step::make('Order')
->icon('heroicon-o-shopping-bag')
->schema([
// ...
]),

你可以使用 submitAction() 方法,渲染最后一步的提交按钮的 HTML 或者向导尾部的视图。这便提供了更为清晰的用户界面,而不必在向导的每一步底下都展示提交按钮:

use Filament\Forms\Components\Wizard;
use Illuminate\Support\HtmlString;
 
Wizard::make([
// ...
])->submitAction(view('order-form.submit-button'))
 
Wizard::make([
// ...
])->submitAction(new HtmlString('<button type="submit">Submit</button>'))

你可以使用 startOnStep() 方法载入指定的步骤:

use Filament\Forms\Components\Wizard;
 
Wizard::make([
// ...
])->startOnStep(2)

如果你想允许自由导航,使所有步骤都可以跳过,重写 hskippable() 方法:

use Filament\Forms\Components\Wizard;
Wizard::make([
// ...
])->skippable()

分区

你可能将字段分成不同区域,每个分区由一个标题和描述。可以使用分区(Section)组件实现这个功能:

use Filament\Forms\Components\Section;
 
Section::make('Heading')
->description('Description')
->schema([
// ...
])

你可以使用 columns() 方法在分区内快速创建网格:

use Filament\Forms\Components\Section;
 
Section::make('Heading')
->schema([
// ...
])
->columns(2)

分区可以在长表单中选择性隐藏内容,可设为可折叠的 collapsible():

use Filament\Forms\Components\Section;
 
Section::make('Heading')
->schema([
// ...
])
->collapsible()

分区可以设为默认已折叠的,collapsed()

use Filament\Forms\Components\Section;
 
Section::make('Heading')
->schema([
// ...
])
->collapsed()

嵌套分区时,你可以使用更为紧凑的样式:

use Filament\Forms\Components\Section;
 
Section::make('Heading')
->schema([
// ...
])
->compact()

占位符

占位符可在表单中用于渲染仅限文本的字段。占位符由一个 content() 方法,用户不可修改。

use Filament\Forms\Components\Placeholder;
 
Placeholder::make('Label')
->content('Content, displayed underneath the label')

你甚至可以在占位符中渲染HTML内容:

use Filament\Forms\Components\Placeholder;
use Illuminate\Support\HtmlString;
 
Placeholder::make('Documentation')
->content(new HtmlString('<a href="https://filamentphp.com/docs">filamentphp.com</a>'))

卡片

卡片(Card)组件可用于渲染卡片内的表单组件:

use Filament\Forms\Components\Card;
 
Card::make()
->schema([
// ...
])

你可以使用 columns() 在卡片内快速创建网格

use Filament\Forms\Components\Card;
 
Card::make()
->schema([
// ...
])
->columns(2)

视图组件

除了创建自定义布局组件,你也可以在不用新建PHP类的情况下,新建视图组件。

use Filament\Forms\Components\View;
 
View::make('filament.forms.components.wizard')

在视图中,你可以使用 $getChildComponentContainer() 闭包渲染组件的 schema()

<div>
{{ $getChildComponentContainer() }}
</div>

创建自定义布局组件

你可以创建自定义的组件类和视图,在应用中复用甚至是以插件形式发布到社区。

如果你只是需要创建一次性使用的简单自定义字段,你可以使用视图组件来渲染自定义模板文件。

要创建自定义的组件类和视图,你可以使用以下命令:

php artisan make:form-layout Wizard

此命令会新建如下布局组件类:

use Filament\Forms\Components\Component;
 
class Wizard extends Component
{
protected string $view = 'filament.forms.components.wizard';
 
public static function make(): static
{
return new static();
}
}

在视图文件内,你可以使用 $getChildComponentContainer() 闭包来渲染组件的 schema()

<div>
{{ $getChildComponentContainer() }}
</div>

需要帮助? 加入论坛 或者打开 GitHub讨论

喜欢Filament?

Filament 中文文档由 laravel-filament.cn 翻译整理。站长用爱发电,希望为英文阅读不畅的朋友提供快速掌握Filament框架的途径。文档的翻译,社区的运营维护都需要时间精力上的付出。如果文档社区使你受益,如果你想支持站长...

打赏