I am using Filament for my application, and I have a form with a Select field. This Select field lists Contact records, each related to a User.
We are allowing users to add new contacts using the createOptionForm and createOptionUsing methods. With this setup, both a Contact and the related User record are created successfully. However, when trying to edit an existing contact using the editOptionForm, it only updates the Contact record and does not update the related User record.
What I'm trying to achieve: I want to edit both the Contact and the associated User when a contact is selected from the Select field and the editOptionForm is opened. The current implementation only updates the Contact record and not the User associated with it.
This is what I tried doing. I tried using Save, Mutate
and other methods but they don't work in Filament/Forms/Form
Forms\Components\Select::make('contact_id')
->label(__('Contact'))
->relationship('contacts', 'id', function ($query): void {
$query->whereHas('user', function ($query): void {
$query->where('userable_type', Contact::class);
});
})
->required()
->columnSpanFull()
->createOptionForm(function (Form $form) {
return ContactResource::form($form);
})
->createOptionUsing(function (array $data): int {
$contact = Contact::create([
'phone' => $data['phone'] ?? null,
'language' => $data['language'],
'contact_source_id' => $data['contact_source_id'] ?? null,
'receive_quote_emails' => $data['receive_quote_emails'] ?? false,
'receive_project_emails' => $data['receive_project_emails'] ?? false,
'receive_task_emails' => $data['receive_task_emails'] ?? false,
'meeting_date' => $data['meeting_date'] ?? null,
'bant_budget' => $data['bant_budget'] ?? null,
'bant_authority' => $data['bant_authority'] ?? null,
'bant_need' => $data['bant_need'] ?? null,
'bant_timing' => $data['bant_timing'] ?? null,
'bant_average' => $data['bant_average'] ?? null,
'profile_photo_path' => $data['profile_photo_path'] ?? null,
]);
$user = User::create([
'first_name' => $data['user']['first_name'],
'last_name' => $data['user']['last_name'],
'email' => $data['user']['email'],
'language' => $data['language'],
'password' => bcrypt('password'),
'userable_type' => Contact::class,
'userable_id' => $contact->id,
]);
$contact->update(['user_id' => $user->id]);
return $contact->id;
})
->editOptionForm(function (Form $form, $record) {
return ContactResource::form($form);
})
->getOptionLabelFromRecordUsing(fn (Contact $record) => "{$record->user->first_name} {$record->user->last_name}"),
This code creates a Select
field with a relationship
to contacts
. It uses createOptionForm
and createOptionUsing
for creating new contacts and related users. It also configures the label for the select option based on the contact's associated user. However, it lacks the logic to edit the user record in the editOptionForm
.
I am using Filament for my application, and I have a form with a Select field. This Select field lists Contact records, each related to a User.
We are allowing users to add new contacts using the createOptionForm and createOptionUsing methods. With this setup, both a Contact and the related User record are created successfully. However, when trying to edit an existing contact using the editOptionForm, it only updates the Contact record and does not update the related User record.
What I'm trying to achieve: I want to edit both the Contact and the associated User when a contact is selected from the Select field and the editOptionForm is opened. The current implementation only updates the Contact record and not the User associated with it.
This is what I tried doing. I tried using Save, Mutate
and other methods but they don't work in Filament/Forms/Form
Forms\Components\Select::make('contact_id')
->label(__('Contact'))
->relationship('contacts', 'id', function ($query): void {
$query->whereHas('user', function ($query): void {
$query->where('userable_type', Contact::class);
});
})
->required()
->columnSpanFull()
->createOptionForm(function (Form $form) {
return ContactResource::form($form);
})
->createOptionUsing(function (array $data): int {
$contact = Contact::create([
'phone' => $data['phone'] ?? null,
'language' => $data['language'],
'contact_source_id' => $data['contact_source_id'] ?? null,
'receive_quote_emails' => $data['receive_quote_emails'] ?? false,
'receive_project_emails' => $data['receive_project_emails'] ?? false,
'receive_task_emails' => $data['receive_task_emails'] ?? false,
'meeting_date' => $data['meeting_date'] ?? null,
'bant_budget' => $data['bant_budget'] ?? null,
'bant_authority' => $data['bant_authority'] ?? null,
'bant_need' => $data['bant_need'] ?? null,
'bant_timing' => $data['bant_timing'] ?? null,
'bant_average' => $data['bant_average'] ?? null,
'profile_photo_path' => $data['profile_photo_path'] ?? null,
]);
$user = User::create([
'first_name' => $data['user']['first_name'],
'last_name' => $data['user']['last_name'],
'email' => $data['user']['email'],
'language' => $data['language'],
'password' => bcrypt('password'),
'userable_type' => Contact::class,
'userable_id' => $contact->id,
]);
$contact->update(['user_id' => $user->id]);
return $contact->id;
})
->editOptionForm(function (Form $form, $record) {
return ContactResource::form($form);
})
->getOptionLabelFromRecordUsing(fn (Contact $record) => "{$record->user->first_name} {$record->user->last_name}"),
This code creates a Select
field with a relationship
to contacts
. It uses createOptionForm
and createOptionUsing
for creating new contacts and related users. It also configures the label for the select option based on the contact's associated user. However, it lacks the logic to edit the user record in the editOptionForm
.
2 Answers
Reset to default 0Use editOptionUsing method. you have defined an editOptionForm
, but there's no corresponding editOptionUsing
method to handle updating both the Contact
and the User
You can use updateOptionUsing method to customize the updating process, for example
->updateOptionUsing(function (array $data, Form $form) {
$record = $form->getRecord();
$record->update($data); // change it to how you update contact record
$user = $record->user;
if($user) {
$user->update($data['user']); // change it to how you update user record
}
})