Laravel11+FilamentPHP3:如何在Info List Builder中实现行内编辑?
在Filament 3的Info List中实现行内编辑(Laravel 11)
方案一:用Filament内置Editable字段(推荐,Filament 3.1+)
如果你的Filament版本是3.1及以上,直接替换原有TextEntry为Editable组件即可,无需额外自定义:
use Filament\Infolists\Components\Editable; public function infolist(Infolist $infolist): Infolist { return $infolist ->schema([ Section::make('Basic Information') ->schema([ Editable::make('name') ->label(new HtmlString('<h2 class="text-base underline font-medium">Name</h2>')) ->columnSpanFull() // 保存后刷新Info List ->saveAction(fn () => $this->refreshInfolist()), Editable::make('definition') ->label(new HtmlString('<h2 class="text-base underline font-medium">Definition</h2>')) ->html() ->columnSpanFull() ->saveAction(fn () => $this->refreshInfolist()), Editable::make('meaning') ->label(new HtmlString('<h2 class="text-base underline font-medium">Meaning</h2>')) ->html() ->columnSpanFull() ->saveAction(fn () => $this->refreshInfolist()), ]) ->columns(2), ]); }
方案二:给TextEntry添加编辑按钮触发模态框(适配所有Filament 3版本)
如果你的Filament版本低于3.1,或者需要更自定义的编辑界面,可给TextEntry添加编辑按钮,通过Filament内置的Action打开模态框编辑:
use Filament\Actions\EditAction; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Textarea; use Filament\Infolists\Components\TextEntry; public function infolist(Infolist $infolist): Infolist { return $infolist ->schema([ Section::make('Basic Information') ->schema([ TextEntry::make('name') ->label(new HtmlString('<h2 class="text-base underline font-medium">Name</h2>')) ->columnSpanFull() ->action(function (Competency $record) { return EditAction::make('editName') ->record($record) ->form([TextInput::make('name')->required()]) ->after(fn () => $this->refreshInfolist()); }), TextEntry::make('definition') ->label(new HtmlString('<h2 class="text-base underline font-medium">Definition</h2>')) ->html() ->columnSpanFull() ->action(function (Competency $record) { return EditAction::make('editDefinition') ->record($record) ->form([Textarea::make('definition')->required()->html()]) ->after(fn () => $this->refreshInfolist()); }), // meaning字段参照上述逻辑添加 ]) ->columns(2), ]); }
方案三:修复自定义Livewire组件的实现
如果坚持用自定义Livewire组件,需确保组件适配Filament上下文,以下是可运行的实现:
- 创建Livewire组件:
// app/Filament/Components/InlineTextEdit.php namespace App\Filament\Components; use Filament\Forms\Components\TextInput; use Filament\Forms\Components\Textarea; use Filament\Forms\Concerns\InteractsWithForms; use Filament\Forms\Contracts\HasForms; use Livewire\Component; class InlineTextEdit extends Component implements HasForms { use InteractsWithForms; public $record; public $field; public $isHtml = false; public $value; public function mount() { $this->value = $this->record->{$this->field}; $this->form->fill(['value' => $this->value]); } protected function getFormSchema(): array { $component = $this->isHtml ? Textarea::make('value')->html() : TextInput::make('value'); return [$component->required()]; } public function save() { $data = $this->form->getState(); $this->record->update([$this->field => $data['value']]); $this->dispatch('infolist-refreshed'); $this->form->close(); } public function render() { return view('filament.components.inline-text-edit'); } }
- 创建组件视图:
{{-- resources/views/filament/components/inline-text-edit.blade.php --}} <div class="inline-flex items-center"> @if(!$this->form->isOpen()) <span wire:click="form.open" class="cursor-pointer hover:text-primary-600"> {!! $isHtml ? $value : e($value) !!} </span> @else <div class="flex items-center gap-2"> {{ $this->form }} <button wire:click="save" class="filament-button filament-button-size-sm inline-flex items-center justify-center py-1 px-3 text-sm font-medium rounded-lg border border-transparent bg-primary-600 text-white hover:bg-primary-700 focus:outline-none focus:ring-2 focus:ring-primary-500 focus:ring-offset-2 transition duration-200"> Save </button> <button wire:click="form.close" class="filament-button filament-button-size-sm inline-flex items-center justify-center py-1 px-3 text-sm font-medium rounded-lg border border-gray-300 bg-white text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-gray-500 focus:ring-offset-2 transition duration-200"> Cancel </button> </div> @endif </div>
- 在Info List中使用组件并添加事件监听:
use App\Filament\Components\InlineTextEdit; use Livewire\Livewire; class ViewCompetency extends ViewRecord { protected static string $resource = CompetencyResource::class; // 监听组件的刷新事件 protected function getListeners(): array { return ['infolist-refreshed' => '$refresh']; } public function infolist(Infolist $infolist): Infolist { return $infolist ->schema([ Section::make('Basic Information') ->schema([ Livewire::make(InlineTextEdit::class, [ 'record' => $this->record, 'field' => 'name', 'isHtml' => false, ]) ->label(new HtmlString('<h2 class="text-base underline font-medium">Name</h2>')) ->columnSpanFull(), Livewire::make(InlineTextEdit::class, [ 'record' => $this->record, 'field' => 'definition', 'isHtml' => true, ]) ->label(new HtmlString('<h2 class="text-base underline font-medium">Definition</h2>')) ->columnSpanFull(), // meaning字段参照上述逻辑添加 ]) ->columns(2), ]); } }
注意事项
- 所有方案都需确保当前用户有编辑
Competency模型的权限,可通过->visible(fn () => auth()->user()->can('update', $this->record))添加权限控制。 - 方案一的
Editable组件仅在Filament 3.1及以上版本可用,若版本较低请升级或使用方案二/三。
内容的提问来源于stack exchange,提问作者theihasan
相关产品推荐
相关产品推荐

