Hey, I have multiple form components that all form one big form in the end, e.g. text inputs, some dropdowns and a image upload. when I fill in my text inputs and hit the save button, the text inputs will be uploaded and the model will be saved to the database.
But if I fill in the dropdowns and then hit save, a new animal model will be added instead of updating the newly created one.
I know why it’s not working (I think), every component has a new animal being created in it’s mount function like so.
public function mount()
{
$this->animal = new Animal();
}
This means that every component has a different animal, instead of a shared animal which they will update.
Is it possible to somehow create a shared animal model that can be used by my components?
This is the main page, where all my components are called
<x-slot name="title">
Add animal
</x-slot>
<div>
<section>
<div
class="py-10 mx-auto max-w-7xl sm:px-6 lg:px-8">
<div class="mt-10 sm:mt-0">
@livewire('animal.general-information-form')
<x-jet-section-border/>
</div>
<div class="mt-10 sm:mt-0">
@livewire('animal.selected-breed-form')
<x-jet-section-border/>
</div>
<div class="mt-10 sm:mt-0">
@livewire('animal.details-form')
<x-jet-section-border/>
</div>
<div class="mt-10 sm:mt-0">
@livewire('utilities.image-uploader')
<x-jet-section-border/>
</div>
</div>
</section>
</div>
In e.g. the general-information-form
I have this
<x-jet-form-section submit="updateAnimalProfile">
<x-slot name="title">
{{ __('Profile Information') }}
</x-slot>
<x-slot name="description">
{{ __('Lets start with some basic information about your animal.') }}
</x-slot>
<x-slot name="form">
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="name" value="{{ __('Name') }}"/>
(required)
<x-jet-input id="name" type="text" class="block w-full mt-1" wire:model.defer="animal.name"
autocomplete="name"/>
<x-jet-input-error for="name" class="mt-2"/>
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="chip_number" value="{{ __('Chip number') }} "/>
(optional)
<x-jet-input id="chip_number" type="text" class="block w-full mt-1" wire:model.defer="animal.chip_number"
autocomplete="chip_number"/>
<x-jet-input-error for="chip_number" class="mt-2"/>
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="passport_url" value="{{ __('Passport url') }}"/>
(optional)
<x-jet-input id="passport_url" type="text" class="block w-full mt-1" wire:model.defer="animal.passport_url"
autocomplete="passport_url"/>
<x-jet-input-error for="passport_url" class="mt-2"/>
</div>
<div class="col-span-6 sm:col-span-4">
<x-jet-label for="birth_date" value="{{ __('Birth date') }}"/>
(optional)
<x-jet-input id="birth_date" type="date" class="block w-full mt-1" wire:model.defer="animal.birth_date"/>
<x-jet-input-error for="birth_date" class="mt-2"/>
</div>
<div class="col-span-6 sm:col-span-4">
<label for="bio">{{__('Bio')}} (optional)</label>
<textarea
class="block w-full mt-1 border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm"
wire:model.defer="animal.bio" name="bio" id="bio" cols="30" rows="10">
</textarea>
</div>
</x-slot>
<x-slot name="actions">
<x-jet-action-message class="mr-3" on="saved">
{{ __('Saved.') }}
</x-jet-action-message>
<x-jet-button wire:loading.attr="disabled" wire:target="photo">
{{ __('Save') }}
</x-jet-button>
</x-slot>
</x-jet-form-section>
And the backend side
<?php
namespace App\Http\Livewire\Animal;
use App\Actions\Utilities\createNewAnimal;
use App\Models\Animal;
use Livewire\Component;
class GeneralInformationForm extends Component
{
/**
* The animal to be created.
*
* @var Animal
*/
public Animal $animal;
protected array $rules = [
'animal.name' => ['nullable', 'string', 'max:12'],
'animal.chip_number' => ['nullable', 'string', 'max:28'],
'animal.passport_url' => ['nullable', 'string', 'max:28'],
'animal.birth_date' => ['nullable', 'date'],
'animal.bio' => ['nullable', 'string', 'max:256'],
];
public function mount()
{
$this->animal = new Animal();
}
public function render()
{
return view('livewire.animal.general-information-form');
}
public function updateAnimalProfile(createNewAnimal $updater)
{
$this->validate();
$animalArray = $this->animal->toArray();
$updater->create(input: $animalArray);
}
}
The rest of the components are almost identical.