尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Filament 4 表格筛选器布局完全指南:从网格列数到模态弹窗的自定义方案

Filament 4 表格筛选器布局完全指南:从网格列数到模态弹窗的自定义方案 Filament 4 表格筛选器布局完全指南从网格列数到模态弹窗的自定义方案【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament本文围绕 Filament 表格组件Filament\Tables\Table的筛选器布局系统展开系统讲解如何通过filtersFormColumns()、filtersFormWidth()、filtersFormMaxHeight()与FiltersLayout枚举将默认的下拉筛选器改造成网格、模态框、表头上下方、左右侧栏等任意形态并深入filterFormSchema()自定义整个筛选表单的排列结构。读完本文你将掌握 Filament 表格筛选区域全部 8 类布局 API 的用法、默认行为与底层实现原理能够按业务需要自由编排筛选器的展示位置与外观。从下拉到任意位置筛选器布局的核心机制Filament 表格的筛选器默认渲染为一个下拉面板用户点击工具栏中的漏斗图标后展开。这套布局系统由 packages/tables/src/Table/Concerns/HasFilters.php 中HasFilterstrait 统一管理其内部维护了filtersFormColumns、filtersFormWidth、filtersFormMaxHeight、filtersLayout、filtersFormSchema、filtersResetActionPosition等一系列受保护属性并暴露了对应的链式方法。整个布局体系的入口是filters()方法。从源码可以看到filters()的第二个参数直接接受一个FiltersLayout枚举值并将它透传给filtersLayout()方法public function filters(array $filters, FiltersLayout | string | Closure | null $layout null): static { $this-filters []; $this-pushFilters($filters); if ($layout) { $this-filtersLayout($layout); } return $this; }也就是说你可以把布局类型作为filters()的具名参数传入文档中的推荐写法也可以在定义表格后单独调用-filtersLayout(FiltersLayout::Modal)达到相同效果。所有布局枚举定义在 packages/tables/src/Enums/FiltersLayout.php共包含 10 个用例枚举用例含义Dropdown默认布局渲染为下拉面板Modal渲染为模态弹窗AboveContent渲染在表格内容上方AboveContentCollapsible渲染在表格上方且可折叠BelowContent渲染在表格内容下方BeforeContent渲染在表格内容左侧之前AfterContent渲染在表格内容右侧之后BeforeContentCollapsible左侧且可折叠AfterContentCollapsible右侧且可折叠Hidden隐藏筛选表单仅保留程序化筛选能力默认布局的判定逻辑在getFiltersLayout()中当未显式设置时回退到Dropdown即return $this-evaluate($this-filtersLayout) ?? FiltersLayout::Dropdown;。此外HasFilters中还有一个deferFilters()方法默认开启用于控制筛选器是否延迟应用到查询在模态与下拉布局下工具栏中会额外出现应用apply按钮其可见性由getFiltersApplyAction()中的-visible($this-hasDeferredFilters())决定。控制筛选区域的网格列数与响应式断点默认情况下无论何种布局筛选表单都是单列排列。要改变筛选器可占用的列数使用filtersFormColumns()方法use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ // ... ]) -filtersFormColumns(3); }值得注意的是一处源码细节filtersFormColumns()的参数类型是int | arraystring, int | null | Closure | null见 HasFilters.php因此它同样支持传入响应式断点数组例如[sm 2, lg 3, xl 4]让筛选器在不同屏幕宽度下自动调整列数。当你不显式设置列数时getFiltersFormColumns()会根据当前布局给出智能默认值public function getFiltersFormColumns(): int | array { return $this-evaluate($this-filtersFormColumns) ?? match ($this-getFiltersLayout()) { FiltersLayout::AboveContent, FiltersLayout::AboveContentCollapsible, FiltersLayout::BelowContent [ sm 2, lg 3, xl 4, 2xl 5, ], default 1, }; }可以看到当筛选器被放置到表格上方或下方时框架会自动采用sm → 2 列、lg → 3 列、xl → 4 列、2xl → 5 列的响应式排布而下拉、模态、左右侧栏等布局默认保持单列。这一默认行为意味着即便你什么都不配置把筛选器放到表格上方也能获得良好的横向空间利用。控制筛选下拉的宽度与最大高度对于下拉布局Filament 通过filtersFormWidth()控制面板宽度通过filtersFormMaxHeight()控制内容最大高度超出后滚动。宽度filtersFormWidth()use Filament\Support\Enums\Width; use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ // ... ]) -filtersFormWidth(Width::FourExtraLarge); }可用的宽度枚举全部定义在 packages/support/src/Enums/Width.php 中本文档涉及的核心档位包括ExtraSmall、Small、Medium、Large、ExtraLarge、TwoExtraLarge、ThreeExtraLarge、FourExtraLarge、FiveExtraLarge、SixExtraLarge、SevenExtraLarge其字符串值依次为xs、sm、md、lg、xl、2xl、3xl、4xl、5xl、6xl、7xl映射到 Tailwind CSS 的 max-width 体系。此外该枚举还提供None、Full、MinContent、MaxContent、FitContent、Prose、Container以及screen-sm到screen的整屏档位可用于更精细的尺寸控制。官方文档指出默认宽度为ExtraSmall但源码中有更精细的联动逻辑getFiltersFormWidth()会根据列数自动推导宽度——public function getFiltersFormWidth(): Width | string | null { return $this-evaluate($this-filtersFormWidth) ?? match ($this-getFiltersFormColumns()) { 2 Width::TwoExtraLarge, 3 Width::FourExtraLarge, 4 Width::SixExtraLarge, default null, }; }即筛选表单为 2 列时默认TwoExtraLarge3 列时默认FourExtraLarge4 列时默认SixExtraLarge单列时回退为null由前端应用ExtraSmall级别的默认样式。这也解释了文档中默认宽度为 ExtraSmall的表述来源——当你在单列下显式设置列数之前宽度档位保持最窄值。若筛选器较多建议配合列数显式指定一个更大的宽度。最大高度filtersFormMaxHeight()当筛选器数量很多、下拉内容过长时可以限制其高度并启用滚动use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ // ... ]) -filtersFormMaxHeight(400px); }参数接受任意合法的 CSS 长度 字符串如400px、50vh、30rem底层由getFiltersFormMaxHeight()直接求值后应用到筛选表单的容器样式上。将筛选器放入模态弹窗FiltersLayout::Modal会把筛选表单渲染为模态框而不是下拉面板use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ // ... ], layout: FiltersLayout::Modal); }模态布局特别适合筛选条件繁多、不适合在下拉中拥挤展示的后台管理场景。你可以借助 触发器动作 API 来进一步定制打开模态的按钮并按照 动作模态框文档 的方式自定义模态本身例如将模态改造成 滑动抽屉slideOveruse Filament\Actions\Action; public function table(Table $table): Table { return $table -filters([ // ... ], layout: FiltersLayout::Modal) -filtersTriggerAction(fn (Action $action) $action-slideOver()); }从源码来看触发器动作由getFiltersTriggerAction()构建HasFilters.php它是一个名为openFilters的图标按钮默认图标为漏斗Heroicon::Funnel、灰色系并且会自动附加应用筛选与重置筛选两个底部动作——这些内置动作同样可以通过filtersApplyAction()与filtersRemoveAllAction()回调进行二次定制。将筛选器放到表格内容的上方、下方或两侧除了弹窗化Filament 还允许把筛选区域直接嵌入到表格主体的上下左右形成常驻筛选栏。表格内容上方可折叠use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ // ... ], layout: FiltersLayout::AboveContent); }若希望筛选栏可被用户收起/展开改用AboveContentCollapsiblepublic function table(Table $table): Table { return $table -filters([ // ... ], layout: FiltersLayout::AboveContentCollapsible); }上方布局是使用最广泛的常驻形态尤其配合前述的响应式默认列数sm:2 / lg:3 / xl:4 / 2xl:5能够在宽屏下充分利用横向空间展示筛选条件。表格内容下方public function table(Table $table): Table { return $table -filters([ // ... ], layout: FiltersLayout::BelowContent); }BelowContent与AboveContent共享同一套响应式默认列数见getFiltersFormColumns()的 match 分支适合把次要的筛选条件收纳在数据底部。表格内容左侧或右侧public function table(Table $table): Table { return $table -filters([ // ... ], layout: FiltersLayout::BeforeContent); // 或 FiltersLayout::AfterContent }BeforeContent将筛选器放在表格左侧内容之前AfterContent放在右侧内容之后适合需要长时间保持筛选条件可见的侧边栏式交互。两种方向也都提供可折叠变体public function table(Table $table): Table { return $table -filters([ // ... ], layout: FiltersLayout::BeforeContentCollapsible); // 或 FiltersLayout::AfterContentCollapsible }隐藏激活筛选的指示器当筛选器生效时Filament 默认会在表格上方渲染一组激活筛选指示器每个指示器显示筛选名与当前值并带有 × 按钮可单独移除对应源码 HasFilterIndicators.php 中通过removeTableFilter(...)Livewire 调用实现的移除逻辑。若希望隐藏这组指示器调用hiddenFilterIndicators()use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ // ... ]) -hiddenFilterIndicators(); }该方法定义于 packages/tables/src/Table/Concerns/HasFilterIndicators.php参数为bool | Closure因此也支持按条件动态隐藏例如-hiddenFilterIndicators(fn (): bool auth()-user()-isAdmin())。需要提醒的是隐藏指示器只影响 UI 展示筛选条件本身仍然生效用户只能通过重置按钮清空筛选。使用 filterFormSchema 自定义整个筛选表单结构当默认的每个筛选器一行的排列无法满足需求时可以使用filtersFormSchema()接管整个筛选表单的 schema把筛选器重新编排进 表单布局组件如 Section、Grid、Tabs、Wizard 等中。use Filament\Schemas\Components\Section; use Filament\Tables\Filters\Filter; use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ Filter::make(is_featured), Filter::make(published_at), Filter::make(author), ]) -filtersFormColumns(2) -filtersFormSchema(fn (array $filters): array [ Section::make(Visibility) -description(These filters affect the visibility of the records in the table.) -schema([ $filters[is_featured], $filters[published_at], ]) -columns(2) -columnSpanFull(), $filters[author], ]); }上例中我们把is_featured与published_at两个筛选器放进了名为 Visibility 的 Section 组件中Section 内部通过columns(2)让这两个筛选器并排两列再通过columnSpanFull()让 Section 横跨整个筛选表单此时表单整体为 2 列宽而author筛选器则独占表单剩余区域。每个筛选器通过其在$filters数组中以筛选器名称为键的条目插入 schema 中。从底层实现看HasFilters.phpgetFiltersFormSchema()在调用用户回调之前会先把每个筛选器包装成一个Group组件foreach ($this-getFilters() as $filterName $filter) { $filters[$filterName] Group::make() -schema($filter-getSchemaComponents()) -statePath($filterName) -key($filterName) -columnSpan($filter-getColumnSpan()) -columnStart($filter-getColumnStart()) -columns($filter-getColumns()); }这意味着$filters数组中的每个元素其实都是一个已绑定好statePath等于筛选器名称的 Group 容器筛选器的状态、列跨度和内部列数在进入你的自定义 schema 之前就已就绪。因此你可以在filtersFormSchema()里像使用普通表单组件一样自由嵌套、重新排列它们而不会破坏筛选状态的读写链路。若用户回调返回null则回退到默认的array_values($filters)平铺排列。将重置动作移动到筛选表单底部筛选表单的头部默认有一个重置reset动作位置由FiltersResetActionPosition枚举控制定义于 packages/tables/src/Enums/FiltersResetActionPosition.php仅含Header与Footer两个用例。将其移动到表单底部与应用动作相邻的方法如下use Filament\Tables\Enums\FiltersResetActionPosition; use Filament\Tables\Table; public function table(Table $table): Table { return $table -filters([ // ... ]) -filtersResetActionPosition(FiltersResetActionPosition::Footer); }默认位置是Header这在getFiltersResetActionPosition()中有明确体现return $this-evaluate($this-filtersResetActionPosition) ?? FiltersResetActionPosition::Header;。将重置动作移到 Footer 后用户先看到筛选控件再在底部依次看到重置与应用按钮操作路径更符合从上到下的填写习惯尤其适合筛选条件较多、需要频繁重置重选的场景。布局选型建议与完整示例综合以上 API可以把布局决策简化为一张速查表业务诉求推荐方案关键 API筛选条件少、保持界面简洁下拉默认FiltersLayout::Dropdown筛选条件多、避免遮挡数据模态弹窗FiltersLayout::Modal筛选是核心操作、需要常驻可见表格上方FiltersLayout::AboveContent常驻但需节省纵向空间表格上方可折叠FiltersLayout::AboveContentCollapsible次要筛选、放在数据下方表格下方FiltersLayout::BelowContent类似侧边栏的长表单左侧/右侧BeforeContent/AfterContent及 Collapsible 变体需要精细分组排布自定义 schemafilterFormSchema() 布局组件下面给出一个组合多种布局能力的中型示例将筛选器放在表格上方、两列排布、最大高度受限、重置动作移到底部并隐藏激活指示器use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Enums\FiltersResetActionPosition; use Filament\Tables\Filters\SelectFilter; use Filament\Tables\Table; public function table(Table $table): Table { return $table -query(Post::query()) -filters([ SelectFilter::make(status) -options([ draft Draft, published Published, archived Archived, ]), SelectFilter::make(author) -relationship(author, name), ], layout: FiltersLayout::AboveContentCollapsible) -filtersFormColumns(2) -filtersFormMaxHeight(400px) -filtersResetActionPosition(FiltersResetActionPosition::Footer) -hiddenFilterIndicators(); }结语Filament 的筛选器布局体系通过filters()的layout参数、filtersFormColumns()、filtersFormWidth()、filtersFormMaxHeight()、filterFormSchema()与filtersResetActionPosition()等一组高度一致的链式 API覆盖了从默认下拉到常驻侧栏的全部主流交互形态。其底层实现集中在 HasFilters trait 与 FiltersLayout、FiltersResetActionPosition 两个枚举中列数与宽度的智能联动默认值让最常见的上方常驻场景开箱即用。实际开发中建议结合筛选条件的数量与业务操作频率选择布局并在条件复杂时优先使用filterFormSchema()进行分组编排从而兼顾界面整洁与操作效率。【免费下载链接】filamentA powerful open-source UI framework for Laravel • Build and ship apps admin panels fast with Livewire项目地址: https://gitcode.com/GitHub_Trending/fi/filament创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表