It looks like you're on the right track, but there are a few things that might be causing issues with your Livewire component. Let's go through your code and make some adjustments to ensure everything works as expected.
Component Code
-
Initialization of Selected Variables: Ensure that you initialize the
selectedCountry,selectedState, andselectedCityvariables in themountmethod. -
Update Method: Ensure that the
updateValuemethod is called correctly and that thecountryStateCityproperty is updated properly. - Parent Component: Ensure that the parent component is correctly listening for updates from the child component.
Here's a revised version of your component:
use Livewire\Component;
use App\Models\Country;
use App\Models\State;
use App\Models\City;
class CountryStateCity extends Component
{
public $countries;
public $states = [];
public $cities = [];
public $selectedCountry = null;
public $selectedState = null;
public $selectedCity = null;
#[Modelable]
public $countryStateCity;
public function mount()
{
$this->countries = Country::orderBy('name')->get();
$this->updateValue();
}
public function updatedSelectedCity($cityId)
{
$this->updateValue();
}
public function updatedSelectedCountry($countryId)
{
$this->updateValue();
$this->states = State::where('country_id', $countryId)->orderBy('name')->get();
$this->cities = []; // Reset cities when country changes
}
public function updatedSelectedState($stateId)
{
$this->updateValue();
$this->cities = City::where('state_id', $stateId)->orderBy('name')->get();
}
public function updateValue()
{
$this->countryStateCity = collect([
'country_id' => $this->selectedCountry,
'state_id' => $this->selectedState,
'city_id' => $this->selectedCity
]);
}
public function render()
{
return view('livewire.country-state-city');
}
}
Parent Component
Ensure that the parent component is correctly listening for updates from the child component. Here's an example of how you might set this up:
use Livewire\Component;
class ParentForm extends Component
{
public $countryStateCity;
public $city_id;
public $state_id;
public $country_id;
public function updatedCountryStateCity($countryStateCity)
{
$this->city_id = $countryStateCity['city_id'];
$this->state_id = $countryStateCity['state_id'];
$this->country_id = $countryStateCity['country_id'];
}
public function render()
{
return view('livewire.parent-form');
}
}
Blade Templates
Ensure that your Blade templates are set up correctly. Here’s an example of how you might set up the child component:
<!-- resources/views/livewire/country-state-city.blade.php -->
<div>
<select wire:model="selectedCountry">
<option value="">Select Country</option>
@foreach($countries as $country)
<option value="{{ $country->id }}">{{ $country->name }}</option>
@endforeach
</select>
<select wire:model="selectedState">
<option value="">Select State</option>
@foreach($states as $state)
<option value="{{ $state->id }}">{{ $state->name }}</option>
@endforeach
</select>
<select wire:model="selectedCity">
<option value="">Select City</option>
@foreach($cities as $city)
<option value="{{ $city->id }}">{{ $city->name }}</option>
@endforeach
</select>
</div>
And the parent component:
<!-- resources/views/livewire/parent-form.blade.php -->
<div>
<livewire:country-state-city wire:model.live="countryStateCity" />
<div>
<p>Selected Country ID: {{ $country_id }}</p>
<p>Selected State ID: {{ $state_id }}</p>
<p>Selected City ID: {{ $city_id }}</p>
</div>
</div>
Summary
- Ensure that the
selectedCountry,selectedState, andselectedCityvariables are initialized. - Ensure that the
updateValuemethod is called correctly and updates thecountryStateCityproperty. - Ensure that the parent component is correctly listening for updates from the child component.
With these adjustments, your nested component should update as expected.