Filament V4 - 表单复选框分组(GroupedCheckboxList) 组件

AI摘要
本文是一篇知识分享,介绍了为Filament框架开发的GroupedCheckboxList自定义表单组件。该组件用于实现分组多选框功能,支持按组全选、可配置布局,并详细说明了其使用方法、数据格式及核心特性。

前言

目前 v4 是没有 Checkbox 分组 表单组件可用,但这个又很实用,使用AI 手搓一个。

GroupedCheckboxList 组件使用文档

效果展示

简介

GroupedCheckboxList 是一个自定义的 Filament 表单组件,用于显示分组的多选框列表,支持按组全选/取消全选功能。特别适用于需要按类别(如年级、部门等)分组选择多个选项的场景。

组件位置

  • 组件类: app/Filament/Forms/Components/GroupedCheckboxList.php
  • 视图模板: resources/views/filament/forms/components/grouped-checkbox-list.blade.php

基本用法

1. 在表单中引入组件

use App\Filament\Forms\Components\GroupedCheckboxList;

2. 准备分组数据

组件需要的数据格式为:

[
    'group_key_1' => [
        'label' => '组名1',
        'options' => [
            'value1' => '选项1',
            'value2' => '选项2',
        ]
    ],
    'group_key_2' => [
        'label' => '组名2',
        'options' => [
            'value3' => '选项3',
            'value4' => '选项4',
        ]
    ],
]

3. 在表单中使用

GroupedCheckboxList::make('field_name')
    ->label('字段标签')
    ->required()
    ->groups(fn(): array => YourModel::getGroupedData())
    ->gridColumns(2)
    ->bulkToggleable()
    ->helperText('提示文本')

完整示例

示例 1: 按年级选择班级

use App\Filament\Forms\Components\GroupedCheckboxList;
use App\Models\Classes as SchoolClass;

// 在表单 Schema 中
GroupedCheckboxList::make('class_ids')
    ->label('参考班级')
    ->required()
    ->groups(fn(): array => SchoolClass::getGroupedOptionsByGrade())
    ->gridColumns(2)
    ->bulkToggleable()
    ->helperText('选择参加考试的班级,可按年级全选')

示例 2: 自定义分组数据

GroupedCheckboxList::make('subject_ids')
    ->label('考试科目')
    ->groups(function () {
        return [
            'major' => [
                'label' => '主科',
                'options' => [
                    1 => '语文',
                    2 => '数学',
                    3 => '英语',
                ]
            ],
            'minor' => [
                'label' => '副科',
                'options' => [
                    4 => '物理',
                    5 => '化学',
                    6 => '生物',
                ]
            ],
        ];
    })
    ->gridColumns(3)
    ->bulkToggleable()

可用方法

groups(array | Closure $groups)

设置分组数据。

参数:

  • $groups: 数组或闭包,返回分组数据

返回: static

示例:

->groups(fn(): array => SchoolClass::getGroupedOptionsByGrade())

gridColumns(int | Closure | null $columns)

设置每行显示的列数。

参数:

  • $columns: 整数或闭包,返回列数(默认: 2)

返回: static

示例:

->gridColumns(3)  // 每行显示3列
->gridColumns(4)  // 每行显示4列

bulkToggleable(bool $bulkToggleable = true)

启用或禁用批量切换(全选/取消全选)功能。

参数:

  • $bulkToggleable: 布尔值,是否启用(默认: true)

返回: static

示例:

->bulkToggleable()      // 启用全选功能
->bulkToggleable(false) // 禁用全选功能

继承自 Field 的方法

组件继承自 Filament\Forms\Components\Field,可以使用所有 Field 的方法:

  • label(string | Closure | null $label) - 设置标签
  • required(bool | Closure $condition = true) - 设置必填
  • helperText(string | Closure | null $text) - 设置提示文本
  • default(mixed $value) - 设置默认值
  • disabled(bool | Closure $condition = true) - 设置禁用状态
  • visible(bool | Closure $condition = true) - 设置可见性
  • hidden(bool | Closure $condition = true) - 设置隐藏
  • reactive() - 启用响应式
  • afterStateUpdated(Closure $callback) - 状态更新后回调
  • 等等…

数据模型方法示例

在模型中创建分组数据方法

// app/Models/Classes.php

/**
 * 获取班级选项(按年级分组,用于分组复选框)
 * 
 * @return array 格式: [
 *   'grade_id' => [
 *     'label' => '年级名',
 *     'options' => ['class_id' => '班级名', ...]
 *   ]
 * ]
 */
public static function getGroupedOptionsByGrade(): array
{
    $classes = self::with('classGrade')
        ->enabled()
        ->orderBy('grade_id')
        ->orderBy('name')
        ->get();

    $groups = [];
    foreach ($classes as $class) {
        $gradeId = $class->grade_id ?? 0;
        $gradeName = $class->classGrade->name ?? '未分年级';

        if (!isset($groups[$gradeId])) {
            $groups[$gradeId] = [
                'label' => $gradeName,
                'options' => [],
            ];
        }

        $groups[$gradeId]['options'][$class->id] = $class->name;
    }

    return $groups;
}

显示效果

组件会渲染为以下格式:

┌─────────────────────────────────────┐
│ 高一                    [全选]      │
├─────────────────────────────────────┤
│ ☐ 一组    ☐ 二组    ☐ 三组         │
│ ☐ 四组    ☐ 五组                   │
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ 高二                    [全选]      │
├─────────────────────────────────────┤
│ ☐ 一组    ☐ 二组    ☐ 三组         │
└─────────────────────────────────────┘

┌─────────────────────────────────────┐
│ 高三                    [全选]      │
├─────────────────────────────────────┤
│ ☐ 一组    ☐ 二组                   │
└─────────────────────────────────────┘

功能特性

✅ 已实现功能

  1. 分组显示: 按组显示选项,每个组有独立的标题
  2. 全选功能: 每个组都有”全选/取消全选”按钮(如果启用)
  3. 响应式设计: 支持暗色模式,适配移动端
  4. 状态管理: 使用 Livewire 的 $entangle 进行状态绑定
  5. 可配置列数: 可以设置每行显示的列数
  6. 表单集成: 完全集成到 Filament 表单系统,支持验证、响应式等

🎨 UI 特性

  • 每个分组有独立的边框和背景
  • 悬停效果
  • 选中状态视觉反馈
  • 全选按钮状态同步(显示”全选”或”取消全选”)

注意事项

  1. 数据格式: 确保 groups() 方法返回的数据格式正确,必须包含 labeloptions
  2. 值类型: 选项的值会被转换为字符串进行比较,确保数据类型一致
  3. 性能: 如果数据量很大,建议在模型中添加适当的索引和缓存
  4. 响应式: 组件使用 Livewire,确保页面已正确加载 Livewire 脚本

常见问题

Q: 如何禁用某个组的全选功能?

A: 使用 bulkToggleable(false) 可以禁用所有组的全选功能。如果需要部分禁用,需要修改组件代码。

Q: 如何自定义样式?

A: 可以修改视图文件 resources/views/filament/forms/components/grouped-checkbox-list.blade.php 中的样式类。

Q: 如何获取选中的值?

A: 选中的值会自动保存到表单字段中,可以通过 $get('field_name') 或表单提交后的数据获取。

Q: 支持多级分组吗?

A: 当前版本只支持一级分组。如需多级分组,需要扩展组件功能。

更新日志

  • v1.0.0 (2025-12-13)
    • 初始版本
    • 支持分组显示
    • 支持全选/取消全选功能
    • 支持可配置列数
    • 集成 Filament 表单系统

如果您也在用 Filament ,遇到什么难题,可以进群交流

2mcOiFT5d2.png!large

本作品采用《CC 协议》,转载必须注明作者和本文链接
Dcat-Admin (plus版)是汇聚Filament,Laravel-admin , Dcat-admin 优点于一身的基于Laravel + Bootstrap 的极速开发框架
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
Dcat-plus Admin @ 速码邦
文章
42
粉丝
61
喜欢
215
收藏
166
排名:365
访问:2.6 万
私信
所有博文
社区赞助商