I am new to laravel livewire and I am trying to create a 2 level dropdown menu (Country and capital) with livewire Components but with no luck I am not getting the resault I want.
This is my CountryDropdown.php
code:
class CountryDropdown extends Component
{
public $selectedCountry;
public function render()
{
$countries = Wilaya::all();
return view('livewire.country-dropdown', compact('countries'));
}
public function updatedSelectedCountry($id){
$this->emit('countrySelected', $id);
}
}
and this is my CapitalDropdown.php
code:
class CapitalDropdown extends Component
{
public $selectedCountry;
public $capitals;
protected $listeners = ['countrySelected' => 'render'];
public function render()
{
//dd($this->selectedCountry);
if($this->selectedCountry){
$this->capitals = Commune::where('wilaya_id', $this->selectedCountry)->get();
} else {
$this->capitals = [];
}
return view('livewire.capital-dropdown');
}
}
As you can see I am getting all countries in the CountryDropdown.php
and it's working fine but whenever I Choose A country I don't get it's capital.
This is my country-dropdown.blade.php
code
<div>
<div class="form-group row">
<select id="wilaya" wire:model="selectedCountry" class="w-full dropdown-toggle items-center justify-between rounded-lg border border-jacarta-100
bg-white py-3 px-3 dark:border-jacarta-600 dark:bg-jacarta-700 dark:text-jacarta-300">
<option value="" selected>---Choisir---</option>
@foreach ($countries as $wilaya)
<option value="{{ $wilaya->id }}">{{ $wilaya->nom }}</option>
@endforeach
</select>
</div>
</div>
and this is my capital-dropdown.blade.php
code :
<div>
<div class="form-group row">
<div class="col-md-6">
<select class="w-full dropdown-toggle items-center justify-between rounded-lg border border-jacarta-100
bg-white py-3 px-3 dark:border-jacarta-600 dark:bg-jacarta-700 dark:text-jacarta-300">
<option value="">Choisissez la commune</option>
@foreach($capitals as $commune)
<option value="{{ $commune->id }}">{{ $commune->nom }}</option>
@endforeach
</select>
</div>
</div>
</div>
I haven't tried anything since I am new to livewire and I still don't understand what is the issues ? So Please feel free to help.
Thanks.
If you are using Livewire 3, you must apply some changes because your code is made for Livewire 2.
In Livewire 3 wire:model is deferred by default, so you must add the live modifier to it. Also instead of emit() you must use dispatch().
In country-dropdown.blade.php apply this change:
<select id="wilaya" wire:model.live="selectedCountry" ....
and I suppose that you will also add a wire:model to the capital-dropdown.
CountryDropdown.php
class CountryDropdown extends Component
{
public $selectedCountry;
public function updatedSelectedCountry($id) {
$this->dispatch('countrySelected', countryId: $this->selectedCountry);
}
public function render()
{
$countries = Wilaya::all();
return view('livewire.country-dropdown', compact('countries'));
}
}
CapitalDropdown.php
class CapitalDropdown extends Component
{
protected $selectedCountry = null;
public $capitals;
protected $listeners = ['countrySelected' => 'setCountry'];
public function setCountry($countryId)
{
$this->selectedCountry = $countryId;
}
public function render()
{
$this->capitals = Commune::where('wilaya_id', $this->selectedCountry)->get();
return view('livewire.capital-dropdown');
}
}
Instead of $listeners you can also use the #[On] php attribute:
.....
use Livewire\Attributes\On;
class CapitalDropdown extends Component
{
.....
#[On('countrySelected')]
public function setCountry($countryId)
{
$this->selectedCountry = $countryId;
}
.....