Creating new entries for multiple recourses in a single form

TLDR: Need to create multiple new entries in various Resources using a single form. I"m essentially, building an ERM system. When creating an employee, I need to handle creating new records for several different Resources. I've landed on a wizard to be the best way to handle guiding the user through the flow. I think i have a lot of the pieces figured out, but need help understanding how to tie it all together. To keep it simple, I'll just cover the first two steps. Step 1) Select or Create a contact: In this step a user can either select a entry from the Contact Resource that already exists, or enter in all the fields to create a new. Essentially, as the basic information about the 'person' who is the employee is stored here. Preferably, the new contact will only be created at the final step when the wizard is complete. Step 2) Enter Employee information: Here the user will enter things like full time, part time, start date, ect. User submits the form, the new contact is created if needed, and the new employee is created with a relationship to the contact.
My biggest issue is the Contact step. My first pass at this, I was using a select with relationship and "getCreateOptionActionForm" but I worry opening up another model in this situation might end up being confusing. So I went with the code below (next message). With this, a user can select an existing contact and the new contact form is hidden. If they do not select a contact, the form is shown. I also wanted to reuse the form from my contact resource, so i am referencing my form class ContactResource::formSchema() Using a wizard on my "CreateEmployee.php" page for my EmployeeResource, what is the best way to pass an array of contact data into the handleRecordCreation() function. Preferably using my ContactResource::formSchema() as a scheme?
8 Replies
karpadiem
karpadiemOP6mo ago
Below is some of my work so far.
Step::make('Personal Information')
->description('Enter the employee\'s personal information, or attach to an existing contact in the system',)
->schema([
//select to choose an existing contact.
Select::make('contact_id')
->label('Contact')
//todo: refactor to exclude any contacts that already have an employee relationship
->getOptionLabelFromRecordUsing(fn (Model $record) => "{$record->first_name} {$record->last_name}")
->searchable()
->placeholder("New Contact")
->preload()
->live()
->native(false),
//embed edit form from contact resource

//reuse the contact resource form schema
Fieldset::make()
->relationship('contact')
//reuse the contact resource form schema
->schema(
ContactResource::formSchema()
)
->live()
->hidden(function(Get $get, $operation){

//get the current operation
//if page is edit show the form
if($get('contact_id') !== null){
return true;
}else{
return false;
}
})

]),
Step::make('Personal Information')
->description('Enter the employee\'s personal information, or attach to an existing contact in the system',)
->schema([
//select to choose an existing contact.
Select::make('contact_id')
->label('Contact')
//todo: refactor to exclude any contacts that already have an employee relationship
->getOptionLabelFromRecordUsing(fn (Model $record) => "{$record->first_name} {$record->last_name}")
->searchable()
->placeholder("New Contact")
->preload()
->live()
->native(false),
//embed edit form from contact resource

//reuse the contact resource form schema
Fieldset::make()
->relationship('contact')
//reuse the contact resource form schema
->schema(
ContactResource::formSchema()
)
->live()
->hidden(function(Get $get, $operation){

//get the current operation
//if page is edit show the form
if($get('contact_id') !== null){
return true;
}else{
return false;
}
})

]),
As far as an interface, this is working exactly how I would like it. However, if add dd($data); to protected function handleRecordCreation(array $data):Model None of the information from that part of the form is there.
array:7 [▼ // app/Filament/Company/Resources/EmployeeResource/Pages/CreateEmployee.php:78
"contact_id" => null
"employee_number" => null
"start_date" => null
"end_date" => null
"status" => "terminated"
"seasonal" => "1"
"part_time" => "0"
]
array:7 [▼ // app/Filament/Company/Resources/EmployeeResource/Pages/CreateEmployee.php:78
"contact_id" => null
"employee_number" => null
"start_date" => null
"end_date" => null
"status" => "terminated"
"seasonal" => "1"
"part_time" => "0"
]
However, if i make the whole step use ContactResource::formSchema() it does pass the information i want, except not packaged in a array of 'contact.fields'. This option also keeps me from using a select that would allow the user to pick an existing contact.
array:11 [▼ // app/Filament/Company/Resources/EmployeeResource/Pages/CreateEmployee.php:40
"first_name" => "sdfsd"
"middle_name" => null
"last_name" => "sdfsd"
"nick_name" => null
"preferred_name" => null
"employee_number" => null
"start_date" => null
"end_date" => null
"status" => "active"
"seasonal" => "0"
"part_time" => "0"
]
array:11 [▼ // app/Filament/Company/Resources/EmployeeResource/Pages/CreateEmployee.php:40
"first_name" => "sdfsd"
"middle_name" => null
"last_name" => "sdfsd"
"nick_name" => null
"preferred_name" => null
"employee_number" => null
"start_date" => null
"end_date" => null
"status" => "active"
"seasonal" => "0"
"part_time" => "0"
]
I just feel like Im not understanding the proper way to do something here and want to make sure I get on the right path before hammering it much harder. 🙂 Thanks!
toeknee
toeknee6mo ago
I would just ensure you have the relationships setup and then on each step you can make sure they are a relationship ->relationship() then once the form is completed, the primary record in this case and then the employee etc is created.
karpadiem
karpadiemOP6mo ago
I guess this is where Im struggeling. How do I properly assign the relationship() to all fields in ->schema(ContactResource::formShcema()) ? Is it possible to assign a relationship to a Group, Fieldset, or Section?
awcodes
awcodes6mo ago
Yes, the layout components support relationships.
karpadiem
karpadiemOP6mo ago
Ok, I seem to be getting closer. I think i was expecting to have the full data show in the dd(data) of handleRecordCreation(array $data) and was debugging that way. I see how that the employee record would be created first, and then the contact record. Follow up question, ContactResource::formShcema()) has a repeater for email addresses. It's using the Contact Model's email_addresses relationship. This works properly on the Contact Creation page, edit page, view page, as well as the employee view page and edit page. However, the values of the repeater seem to be trashed in this create employee wizard. Are repeaters nested in a relationship supported when creating a new entry, or am i doing something else wrong?
awcodes
awcodes6mo ago
Honestly, I don’t have a solid answer for you. As long as the relationships are set up correctly and the nesting in the form is correct, I would expect it still work.
karpadiem
karpadiemOP6mo ago
Ok, that's fair! As long as that is the expected behaviour I'll keep tinkering with what I got. Thanks!
Want results from more Discord servers?
Add your server