Dynamic Form Field

Hi, I'm trying to create a component that changes format based on what "mode" the page is on. My logic here works but only after a page reload. Can I make it more reactive in filament? or am I better off going for plain livewire/alpine? cheers.
1 Reply
backtrackjack
backtrackjackOP16mo ago
protected function getFactTopicFormSchema(): array
{
return [
Placeholder::make('activeTopicTitle')
->disableLabel()
->extraAttributes(['class' => 'text-2xl overflow-ellipsis'], true)
->content($this?->activeTopic?->title)
->visible(function () {
return tap($this->courtMode, fn() => $this->emitSelf('refreshComponent'));
}),
TextInput::make('activeTopicTitle')
->visible(function () {
return tap($this->editMode, fn() => $this->emitSelf('refreshComponent'));
})
->columnSpanFull()
->required()
->disableLabel()
->prefix('Fact Topic')
->lazy()
->afterStateUpdated(function ($state) {
$this->validateOnly('activeTopicTitle');
$this->activeTopic->update([
'title' => $state,
]);
}),
];
}
protected function getFactTopicFormSchema(): array
{
return [
Placeholder::make('activeTopicTitle')
->disableLabel()
->extraAttributes(['class' => 'text-2xl overflow-ellipsis'], true)
->content($this?->activeTopic?->title)
->visible(function () {
return tap($this->courtMode, fn() => $this->emitSelf('refreshComponent'));
}),
TextInput::make('activeTopicTitle')
->visible(function () {
return tap($this->editMode, fn() => $this->emitSelf('refreshComponent'));
})
->columnSpanFull()
->required()
->disableLabel()
->prefix('Fact Topic')
->lazy()
->afterStateUpdated(function ($state) {
$this->validateOnly('activeTopicTitle');
$this->activeTopic->update([
'title' => $state,
]);
}),
];
}
ok I realise the refresh component is happening before the mode is actually changed. My new approach is to add a registerListeners() on each field that listens for some 'modeChanged' event.
return [
TextInput::make('activeTopicTitleInput')
->extraAttributes([
'x-show' => 'editMode',
])
->columnSpanFull()
->required()
->disableLabel()
->prefix('Fact Topic')
->lazy()
->afterStateUpdated(function ($state) {
$this->validateOnly('activeTopicTitleInput');
$this->activeTopic->update([
'title' => $state,
]);
}),
Placeholder::make('activeTopicTitlePlaceholder')
->disableLabel()
->extraAttributes(function () {
$attributes = [
'class' => 'text-2xl',
'x-show' => 'courtMode',
];
if ($this->editMode) {
$attributes['style'] = 'display: none;';
}

return $attributes;
})
// value is based on the activeTopicTitleInput form field
->content(fn (Closure $get) => $get('activeTopicTitleInput')),

return [
TextInput::make('activeTopicTitleInput')
->extraAttributes([
'x-show' => 'editMode',
])
->columnSpanFull()
->required()
->disableLabel()
->prefix('Fact Topic')
->lazy()
->afterStateUpdated(function ($state) {
$this->validateOnly('activeTopicTitleInput');
$this->activeTopic->update([
'title' => $state,
]);
}),
Placeholder::make('activeTopicTitlePlaceholder')
->disableLabel()
->extraAttributes(function () {
$attributes = [
'class' => 'text-2xl',
'x-show' => 'courtMode',
];
if ($this->editMode) {
$attributes['style'] = 'display: none;';
}

return $attributes;
})
// value is based on the activeTopicTitleInput form field
->content(fn (Closure $get) => $get('activeTopicTitleInput')),

This was my solution. Couldn't get the filament forms event to work
Want results from more Discord servers?
Add your server