MutateBeforeSave with Standalone Forms, model(), and statePath()

I am doing something like
public function form(Form $form): Form
{
return $form
->schema([
Checkbox::make('managed')
->reactive()
->afterStateUpdated(function (Set $set, $state) {
if ($state === false) {
$set('housing_locator', []);
$set('intermediaryContacts', []);
}
}),
Select::make('housing_locator')
->visible(fn($get) => $get('managed'))
->relationship('housingLocators', 'name')
->reactive()
->afterStateUpdated(function($set) {
// set contacts in repeater)
}),
Repeater::make('intermediaryContacts')
->relationship('intermediaryContacts'),
])
->statePath('data')
->model($this->property ?? Property::class);
}
public function form(Form $form): Form
{
return $form
->schema([
Checkbox::make('managed')
->reactive()
->afterStateUpdated(function (Set $set, $state) {
if ($state === false) {
$set('housing_locator', []);
$set('intermediaryContacts', []);
}
}),
Select::make('housing_locator')
->visible(fn($get) => $get('managed'))
->relationship('housingLocators', 'name')
->reactive()
->afterStateUpdated(function($set) {
// set contacts in repeater)
}),
Repeater::make('intermediaryContacts')
->relationship('intermediaryContacts'),
])
->statePath('data')
->model($this->property ?? Property::class);
}
So everything is just saving directly through the model. Its working fine for adding information, but I am having an issue emptying the select and repeater when the managed field is changed back to false. Don't think simply setting them to an empty array will delete those relational entries. Thoughts?
17 Replies
Mark Chaney
Mark ChaneyOP14mo ago
ok, so the issue is that they dont save because they are hidden
cheesegrits
cheesegrits14mo ago
Was just typing to the effect that are you sure you are just setting the repeater to an empty array, or is there code not shown which hides stuff.
Mark Chaney
Mark ChaneyOP14mo ago
@Hugh Messenger well i do have ->visible(fn($get) => $get('managed')) as you can see above on the housing_locator select its on the repeater as well, but i was having the issue with both
cheesegrits
cheesegrits14mo ago
Oh yeah, duh. Long day. So yeah. One of those things about Filament, if it's "hidden" it won't get submitted / saved. I've always though 'hidden' in this context is a misnomer. It's not hidden, it doesn't exist. To me "hidden" means it's on the form, just not visible. But in Filament ... hidden means it doesn't exist.
Mark Chaney
Mark ChaneyOP14mo ago
ok, so if i cant do it that way, how should i do it when using ->model()?
cheesegrits
cheesegrits14mo ago
I've had similar issues, where I need to add mutateOnSave / lifecycle hooks to empty stuff out, based on the state of the form.
Mark Chaney
Mark ChaneyOP14mo ago
but i dont have the same options with standalone filament do i?
cheesegrits
cheesegrits14mo ago
Nope. So in all my standalone stuff I use my own save() method.
Mark Chaney
Mark ChaneyOP14mo ago
fml
cheesegrits
cheesegrits14mo ago
Or rather, "nope, not that I know of". I don't think the form itself has life cycle hooks, only the fields. Which isn't helpful if the field doesn't exist. How do you actually submit your forms? Or is this in a modal?
Mark Chaney
Mark ChaneyOP14mo ago
it is not, but this does appear to work
if ($data['managed_internally'] === false) {
$this->property->housingLocators()->sync([]);
$this->property->intermediaryContacts()->delete();
}
if ($data['managed_internally'] === false) {
$this->property->housingLocators()->sync([]);
$this->property->intermediaryContacts()->delete();
}
I do have a save method, it just wasnt handling any of the relationships
cheesegrits
cheesegrits14mo ago
Ah. Any particular reason? So you call getState() in your save method? I would do it there rather than on the form when they hit a checkbox. Just check the state of the 'managed' checkbox in there. In theory getState() itself should handle the relationships, but I'm sure skips that handling if the repeater component is not visible.
Mark Chaney
Mark ChaneyOP14mo ago
but yes, in the save method, $data = $this->form->getState();
cheesegrits
cheesegrits14mo ago
Yeah, so just check $data['managed'] after the getState, if it's false do your sync() and delete() on the record there.
Mark Chaney
Mark ChaneyOP14mo ago
yep, i pasted that above 😛
cheesegrits
cheesegrits14mo ago
Oh, I thought you were doing that on the form. OK, n/m. As you were. Carry on. Imma go walk the dogs.
Mark Chaney
Mark ChaneyOP14mo ago
sorry, i guess i should have been more clear when i figured it out. 😛
Want results from more Discord servers?
Add your server