F
Filament9mo ago
Oi

Can you customise the behaviour of a toggle component?

Is it possible to customise the behaviour of a toggle component in the form builder? When I toggle it I want to execute some arbitrary code.
Solution:
afterStateUpdated works, but i think you need to make your field live 😜
Jump to solution
32 Replies
Oi
OiOP9mo ago
I think I should mention that this toggle isn't linked to any field whatsoever. I tried afterStateUpdated but that didn't work, I assume for the reason that it isn't linked to any field so there was technically nothing to update.
Solution
BlackShadow
BlackShadow9mo ago
afterStateUpdated works, but i think you need to make your field live 😜
Oi
OiOP9mo ago
Thank you, this seems to work! Would you also happen to know why my explictly defined default value isn't being displayed? I pass in a closure to the default call
BlackShadow
BlackShadow9mo ago
Code?
Oi
OiOP9mo ago
->default(function () use ($form) {
/** @var Payment $model */
$model = $form->getModelInstance();

return $model->counterParty->category()->is($model->category);
})
->default(function () use ($form) {
/** @var Payment $model */
$model = $form->getModelInstance();

return $model->counterParty->category()->is($model->category);
})
wait I'll send more
BlackShadow
BlackShadow9mo ago
What field
Oi
OiOP9mo ago
it's on a toggle, that is not bound to any field on the model
Forms\Components\Toggle::make('aaaa')
->label('Sync to Counter Party')
->inline(false)
->live()
->default(function () use ($form) {
/** @var Payment $model */
$model = $form->getModelInstance();

return $model->counterParty->category()->is($model->category);
})
->afterStateUpdated(function ($state) use ($form) {
/** @var Payment $model */
$model = $form->getModelInstance();

$model->counterParty()->update(['category_id' =>
$state ? $model->category_id : null,
]);
}),
Forms\Components\Toggle::make('aaaa')
->label('Sync to Counter Party')
->inline(false)
->live()
->default(function () use ($form) {
/** @var Payment $model */
$model = $form->getModelInstance();

return $model->counterParty->category()->is($model->category);
})
->afterStateUpdated(function ($state) use ($form) {
/** @var Payment $model */
$model = $form->getModelInstance();

$model->counterParty()->update(['category_id' =>
$state ? $model->category_id : null,
]);
}),
BlackShadow
BlackShadow9mo ago
try to set the default to true and then try false, and see if that works. if that works your other logic is wrong 😛
Oi
OiOP9mo ago
I tried just returning true from the closure but it didn't do anything i.e.
->default(function () use ($form) {
return true;
->default(function () use ($form) {
return true;
BlackShadow
BlackShadow9mo ago
Is this on a edit field or create.
Oi
OiOP9mo ago
maybe you just can't use a closure
BlackShadow
BlackShadow9mo ago
page *
Oi
OiOP9mo ago
currently on an edit page
BlackShadow
BlackShadow9mo ago
Default only works on create 😛
Oi
OiOP9mo ago
😭 oh yeah that makes sense actually
BlackShadow
BlackShadow9mo ago
Yea its already set at that point
Oi
OiOP9mo ago
I tried using ->state for this before but I just kept getting the error
Typed property Filament\Forms\Components\Component::$container must not be accessed before initialization
Typed property Filament\Forms\Components\Component::$container must not be accessed before initialization
is it actually possible?
BlackShadow
BlackShadow9mo ago
Mmm
dissto
dissto9mo ago
->afterStateHydrated() maybe?
BlackShadow
BlackShadow9mo ago
Maybe, but i don't see the logic 😛
Oi
OiOP9mo ago
Dennis already solved this part, I just had to add live to it. hmmm
BlackShadow
BlackShadow9mo ago
If should probably do that part in the edit and perhaps something else on create? Not sure what you trying to do.
Oi
OiOP9mo ago
basically just trying to change the initial state of the toggle column, since it isn't bound to a field of any model I have no doubt that what I'm trying to do; I'm doing it wrong, but at this point I just want it to work 😭
BlackShadow
BlackShadow9mo ago
You want to show a field if that is toggled? but you don't want to save that toggle field. Might wanna take a look at:
>afterStateHydrated(function (TextInput $component, string $state) {
$component->state(ucwords($state));
})
>afterStateHydrated(function (TextInput $component, string $state) {
$component->state(ucwords($state));
})
in combination with dehydrated
Oi
OiOP9mo ago
Not really, basically the toggle basically just serves as an action, but on the edit page in the form of a toggle. The toggle is not bound to a field on the model but instead gets it's state and action from arbitrary code in closures. idk how to explain it really I'll try this I thought the other person suggested this for the first problem I had
dissto
dissto9mo ago
you could probably use the mount too if you just want to set the fields value
public function mount(int|string $record): void
{
//parent::mount($record);
$this->form->fill([
'aaa' => true,
]);
}
public function mount(int|string $record): void
{
//parent::mount($record);
$this->form->fill([
'aaa' => true,
]);
}
untested and probably not what you want ^_^
Oi
OiOP9mo ago
afterStateHydrated actually works, but now yet another problem arises. As I said before I don't want to save the aaa field. How do I exclude it from the data? It's only purpose is basically executing some arbitrary code.
dissto
dissto9mo ago
->dehydrated(false)
Oi
OiOP9mo ago
man, you guys are too smart it works thank you so much, both of you @dissto & @CodeWithDennis
dissto
dissto9mo ago
👍🏽
BlackShadow
BlackShadow9mo ago
Yw 🙂
Oi
OiOP9mo ago
(I marked the solution to the original question)
Want results from more Discord servers?
Add your server