rodrigofs/filament-masterdetail 问题修复 & 功能扩展

解决BUG、新增功能、兼容多环境部署,快速响应你的开发需求

邮箱:yvsm@zunyunkeji.com | QQ:316430983 | 微信:yvsm316

rodrigofs/filament-masterdetail

最新稳定版本:v1.4.0

Composer 安装命令:

composer require rodrigofs/filament-masterdetail

包简介

Filament plugin designed specifically for managing Laravel HasMany relationships without relying on Filament's default repeater field, using instead a dedicated modal and table-based form interface.

README 文档

README

Filament Master Detail

Latest Version on Packagist PHP Run Tests fix-code-style phpstan Total Downloads

Overview

Filament Master Detail is a dynamic management plugin Form Component for HasMany (1,n) and Many to Many(n,n) relationships in FilamentPHP. It allows you to add and remove related records directly within the parent form, without the need to save the parent record first. Ideal for fast and fluid data entry scenarios.

Table of Contents

Installation

Requirements

  • PHP >= 8.1
  • Laravel >= 10
  • Filament >= 3.x

Installation Steps

  composer require rodrigofs/filament-masterdetail

Basic Usage

Important: When using the table(...) method, it is not compatible with Filament's TextColumn or other default columns. You must exclusively use the DataColumn provided by this package.

Example

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;
use Rodrigofs\FilamentMasterDetail\Tables\Columns\DataColumn;

MasterDetail::make('items')
    ->relationship('items')
    ->schema([
        TextInput::make('name')->required(),
        TextInput::make('description'),
    ])
    ->table([
        DataColumn::make('name'),
        DataColumn::make('description'),
    ]);

Define the HasMany relationship in the parent model:

public function items(): HasMany
{
    return $this->hasMany(Item::class);
}

Common Use Cases

Order Creation with Items

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;
use Rodrigofs\FilamentMasterDetail\Tables\Columns\DataColumn;

MasterDetail::make('items')
    ->relationship()
    ->schema([
        Select::make('shop_product_id')
            ->label('Product')
            ->options(Product::query()->pluck('name', 'id'))
            ->required()
            ->reactive()
            ->afterStateUpdated(fn ($state, Set $set) => $set('price', Product::find($state)?->price ?? 0))
            ->distinct()
            ->disableOptionsWhenSelectedInSiblingRepeaterItems()
            ->columnSpan(['md' => 5])
            ->searchable(),

        TextInput::make('quantity')
            ->label('Quantity')
            ->numeric()
            ->default(1)
            ->required()
            ->columnSpan(['md' => 2]),

        TextInput::make('price')
            ->label('Unit Price')
            ->numeric()
            ->disabled()
            ->dehydrated()
            ->required()
            ->columnSpan(['md' => 3]),
    ])
    ->unique('shop_product_id')
    ->table([
        DataColumn::make('product.name')
            ->relationship()
            ->label('Product'),

        DataColumn::make('quantity')
            ->label('Quantity'),

        DataColumn::make('price')
            ->label('Unit Price'),

        DataColumn::make('total')
            ->formatStateUsing(fn ($rowLoop) => $rowLoop->price * $rowLoop->quantity)
            ->label('Total'),
    ]);

Additional Features

Behavior & Customization

You can customize the behavior of the component and the appearance and behavior of the modal used to add, delete, and edit related records:

Disable Actions

Disable the default Add, Delete, and Edit actions on the component:

use Rodrigofs\FilamentMasterDetail\Components\MasterDetail;

// Disable actions statically
MasterDetail::make('items')
    ->addable(false)
    ->editable(false)
    ->removable(false)
    ->schema([
        // Form fields
    ]);

// Disable actions conditionally using closures
MasterDetail::make('items')
    ->addable(fn (): bool => /* condition based on $record, $get, $state, $operation and more... */ false)
    ->editable(fn (...): bool => /* condition based on $record, $get, $state, $operation and more... */ false)
    ->removable(fn (...): bool => /* condition based on $record, $get, $state, $operation and more... */ false)
    ->schema([
        // Form fields
    ]);

Slideover Mode

Display the form inside a Slideover instead of a traditional modal:

use Rodrigofs\FilamentMasterDetail\Components\MasterDetail;

MasterDetail::make('items')
    ->slideover()
    ->schema([
        // Form fields
    ]);

Set Custom Labels

Define the labels for modal actions and headings:

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->addActionLabel('Add Product')
    ->modalHeading('Add Product')
    ->modalDescription('Include a new product in this order.')
    ->modalSubmitActionLabel('Add')
    ->modalSubmitEditActionLabel('Edit')
    ->modalCancelActionLabel('Cancel');

Set Modal Icon and Width

Customize the modal icon and size:

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->modalIcon('heroicon-o-plus')
    ->modalWidth('lg');

Keep Modal Open After Adding

Prevent the modal from closing automatically after adding a record:

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->modalPersistent();

Customize Table Heading

Set a custom heading for the related records table:

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->heading('Order Items');

Preserve Field Values

Prevent specific fields from being cleared after adding a record:

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->formExceptClear(['product_id']);

Manipulate Data Before Adding

Allow data manipulation before the record is added to the table:

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->beforeAddActionExecute(fn ($state, $set) => $set('product_id', $state));

Add Header Actions

Define custom actions in the header of the MasterDetail component:

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->headerActions([
       Action::make('reset')
            ->modalHeading('Are you sure?')
            ->modalDescription('All existing items will be removed from the order.')
            ->requiresConfirmation()
            ->color('danger')
            ->action(fn (Forms\Set $set) => $set('items', [])),
    ]);

There are many additional features available—more than can be covered at once. While I will continue to document them, I encourage you to freely explore all possibilities. Don’t hesitate to open an issue if you encounter any problems or have suggestions.

Full Example

use Rodrigofs\FilamentMasterDetail\Forms\Components\MasterDetail;

MasterDetail::make('items')
    ->relationship()
    ->schema([
        Select::make('product_id')
            ->label('Product')
            ->options(Product::query()->pluck('name', 'id'))
            ->required(),
        TextInput::make('quantity')
            ->numeric()
            ->required(),
    ])
    ->table([
        DataColumn::make('product.name')
            ->relationship()
            ->label('Product'),
        DataColumn::make('quantity')
            ->label('Quantity'),
 
    ])
    ->addActionLabel('Add Product')
    ->modalHeading('Add Product')
    ->modalDescription('Include a new product in this order.')
    ->modalIcon('heroicon-o-plus')
    ->modalWidth('lg')
    ->modalSubmitActionLabel('Add')
    ->modalCancelActionLabel('Cancel')
    ->heading('Order Items')
    ->formExceptClear(['product_id'])
    ->beforeAddActionExecute(fn ($state, $set) => $set('product_id', $state))
    ->headerActions([
        Action::make('reset')
            ->modalHeading('Are you sure?')
            ->modalDescription('All existing items will be removed from the order.')
            ->requiresConfirmation()
            ->color('danger')
            ->action(fn (Forms\Set $set) => $set('items', [])),
    ])
    ->slideOver();

Editing Behavior

The editing feature works for related records defined via the relationship() method on the component.

Important: This feature does not support custom statePath-based implementations that do not use the relationship() method. Relationship-based binding is required for the edit action to resolve the model instance correctly.

FAQ

  1. Do I need to save the parent record before adding related records? No. MasterDetail allows adding and removing related records before persisting the parent model.

  2. Does it support other relationship types besides HasMany? *Currently, only HasMany relationships are supported.* Yes. In addition to HasMany, it is now possible to create records using BelongsToMany (many-to-many) relationships. However, attaching existing related records is not yet supported.

  3. Is there support for editing related records? No. Only adding and removing records is supported at the moment. Yes. You can edit related records through an edit action.

Screenshots

Table View

Table View

Add New Item in Modal

Add New Item

Edit Item in Modal

Edit Item

Remove Item with Confirmation

Remove Item

Show Slideover Mode

Slideover Mode

Video Demo

Video Demo

Changelog

Please see CHANGELOG for more information on what has changed recently.

Contributing

Please see CONTRIBUTING for details.

Security Vulnerabilities

Please review our security policy on how to report security vulnerabilities.

Credits

License

The MIT License (MIT). Please see License File for more information.

rodrigofs/filament-masterdetail 适用场景与选型建议

rodrigofs/filament-masterdetail 是一款 基于 PHP 开发的 Composer 扩展包,目前已累计 31 次下载、GitHub Stars 达 19, 最近一次更新时间为 2025 年 03 月 26 日, 在 PHP 生态内属于活跃度较高的组件。

我们在过去多个企业项目中使用过 rodrigofs/filament-masterdetail 或与其功能相近的方案,如果你在选型或落地过程中遇到问题,例如 版本兼容、二次改造、私有化封装、与内部系统对接、生产 BUG 排查,欢迎联系我们协助评估。

围绕 rodrigofs/filament-masterdetail 我们能提供哪些服务?
定制开发 / 二次开发

基于 rodrigofs/filament-masterdetail 在你已有业务上做功能扩展、字段裁剪、UI 适配、与内部账号 / 权限 / 日志系统的深度对接。

BUG 修复 & 性能优化

线上偶发问题、内存泄漏、慢查询、并发异常等排查修复;针对高流量场景做缓存、队列、索引层面的调优。

项目外包 & 长期维护

承接完整的项目从需求 → 设计 → 开发 → 上线 → 长期运维;也可按月提供技术保姆服务。

yvsm@zunyunkeji.com QQ:316430983 微信:yvsm316 西安尊云信息科技 · 专注 PHP / Go / 分布式系统研发

统计信息

  • 总下载量: 31
  • 月度下载量: 0
  • 日度下载量: 0
  • 收藏数: 21
  • 点击次数: 30
  • 依赖项目数: 0
  • 推荐数: 0

GitHub 信息

  • Stars: 19
  • Watchers: 1
  • Forks: 2
  • 开发语言: PHP

其他信息

  • 授权协议: MIT
  • 更新时间: 2025-03-26