Modelable Issues with Parent Child Components
I am trying to create some reusable component with three MaryUI Select components (MaryUI isn't the issue). Source, Status and Owner. From the parent Livewire page I pull possible existing Source Status or Owner if we are viewing the object or leave as blank if we are creating. The issue is where we have a blank Source or Status for example and we have a default value set from the database. User is set on the parent ownerId and works with preselecting the correct user. In the child Livewire component I am doing the following to get the default value but the issue is the parent overwrites the found default value with in my case an empty string.
<?php
namespace App\Livewire\Components\Ui;
use Livewire\Component;
use App\Models\FieldDefinition;
use Livewire\Attributes\Modelable;
use Illuminate\Support\Facades\Log;
class Status extends Component {
public $statuses;
public $object = 'contact';
#[Modelable]
public $statusId;
public function mount($object) {
$this->object = $object;
$this->loadLeadStatuses();
}
private function loadLeadStatuses() {
$def = FieldDefinition::getOptionsForField($this->object, 'status');
if ($this->statusId == '') {
$this->statusId = $def->firstWhere('is_default', true)->id ?? '';
}
$this->statuses = $def->map(function ($option) {
return ['id' => $option->id, 'name' => $option->option_label];
})->toArray();
}
public function render() {
return view('livewire.components.ui.status');
}
}
I did a test where I hard coded statusId in the parent and it populated correctly. It seem there's something that will always override the child property even if the parent property is null/ empty. Is there a work around? I know I can use events and such but that seems hacky! The reason I want it to work like this is that these three inputs are used a lot over the system I am making and not ideal to duplicate the same methods and such possibly 7 or 8 times each.
Parent Class, removed unrelated code:
class Create extends LivewireModal {
public $lead;
public $countries = [];
public $counties = [['id' => '', 'name' => 'Please select a country first']];
public $countryCounty;
public $leadSources = [];
public $leadStatuses = [];
public $sourceId = null;
public $statusId = null;
public $ownerId;
public $users = [];
public $name;
public $company_name;
public $email;
public $phone;
public $website;
public $amount;
public $address;
public $city;
public $country;
public $county;
public $postcode;
public function mount() {
$this->lead = new Lead();
$this->ownerId = auth()->user()->id;
}
public function create() {
abort_if_cannot('create_leads');
$this->validate();
$lead = Lead::create([
'name' => $this->name,
'company_name' => $this->company_name,
'email' => $this->email,
'phone' => $this->phone,
'website' => $this->website,
'amount' => $this->amount,
'source_id' => $this->sourceId,
'status_id' => $this->statusId,
'owner_id' => $this->ownerId,
]);
$address = $lead->addAddress([
'type_id' => $this->getAddressTypeId('other'),
'line_1' => $this->address,
'city' => $this->city,
'county' => $this->county,
'postcode' => $this->postcode,
'country' => $this->country,
'is_primary' => true,
]);
add_user_log([
'title' => 'Lead created: ' . $lead->name,
'link' => route('leads.view', $lead->id),
'id' => $lead->id,
'section' => 'Leads',
'type' => 'created',
]);
$this->dispatch('closeModal');
$this->dispatch('refreshLead');
$this->dispatch('pg:eventRefresh-lead-table');
LivewireAlert::title('Lead created successfully')
->success()
->toast()
->position('top')
->show()
public function render() {
abort_if_cannot('create_leads');
return view('livewire.leads.create');
}
}
Main Blade:
@props([
'object' => 'contact'
])
<div>
<livewire:components.ui.source :object="$object" wire:model="sourceId" />
<livewire:components.ui.status :object="$object" wire:model="statusId" />
<livewire:components.ui.owner :object="$object" wire:model="ownerId" />
</div>
Livewire View:
<div>
<x-ui.field required>
<x-ui.label>Status</x-ui.label>
<x-mary-choices-offline
class="rounded-box"
wire:model="statusId"
:options="$statuses"
placeholder="Select a status..."
clearable
searchable
single
/>
</x-ui.field>
</div>
Please or to participate in this conversation.