Using Select2 with Laravel Livewire Hello
How use Select2 with Livewire
public $name = '';
public $car_make_id = '';
public function create(){
CarModel::create([
'name' => $this->name,
'car_id' => $this->car_make_id
]);
session()->flash('message', 'Added successfully');
}
<form wire:submit.prevent="create">
<div class="row mb-2">
<div class="col-sm-5">
<select wire:model="car_make_id" class="select2 form-select">
<option value="" selected>Choose Make</option>
@foreach ($makes as $make)
<option value="{{$make->id}}">{{$make->name}}</option>
@endforeach
</select>
@error('car_make_id')<div class="text-danger">{{ $message }}</div>@enderror
</div>
<div class="col-sm-5">
<input type="text" wire:model="name" class="form-control" />
@error('name')<div class="text-danger">{{ $message }}</div>@enderror
</div>
<div class="col-sm-2">
<button wire:loading.remove type="submit" class="btn btn-primary me-sm-2 me-1">Add</button>
</div>
</div>
</form>
I try use , but this not helps
document.addEventListener('livewire:load', function () {
$('.select2').select2();
Livewire.hook('message.processed', function () {
$('.select2').select2();
});
});
change your component. Assuming make id is an integer foreign key
public int $car_make_id;
Wrap your select inside a div with wire:ignore
<div wire:ignore>
<select wire:model="car_make_id" class="select2 form-select">
<option value="" selected>Choose Make</option>
@foreach ($makes as $make)
<option value="{{$make->id}}">{{$make->name}}</option>
@endforeach
</select>
</div>
javascript inside your component view
<script>
$(document).ready(function() {
$('.select2').select2().on('select2:select', function (e) {
@this.set('car_make_id', $('.select2').select2("val"));
});
});
</script>
I would choose a different method of targeting the select element than class of select2 because this will break if you want two selects on the same page.
@Snapey
when make select in log:
The select2('val') method was called on an element that is not using Select2.
And if submit, response The car make id field is required.
also not working
@error('car_make_id')<div class="text-danger">{{ $message }}</div>@enderror
@Snapey
public $name = '';
public int $car_make_id;
public function create(){
$this->validate([
'name' => 'required|string|max:255',
'car_make_id' => 'required|integer'
]);
CarModel::create([
'name' => $this->name,
'car_make_id' => $this->car_make_id
]);
$this->cancel();
session()->flash('message', 'Added successfully');
}
<form wire:submit.prevent="create">
<div class="row mb-2">
<div class="col-sm-5"><div wire:ignore >
<select wire:model="car_make_id" class="select2 form-select">
<option value="" selected>Choose Make</option>
@foreach ($makes as $make)
<option value="{{$make->id}}">{{$make->name}}</option>
@endforeach
</select>
@error('car_make_id')<div class="text-danger">{{ $message }}</div>@enderror
</div></div>
<div class="col-sm-5">
<input type="text" wire:model="name" class="form-control" />
@error('name')<div class="text-danger">{{ $message }}</div>@enderror
</div>
<div class="col-sm-2">
<button wire:loading.remove type="submit" class="btn btn-primary me-sm-2 me-1">Add</button>
</div>
</div>
</form>
<script>
$(document).ready(function() {
$('.select2').select2().on('select2:select', function (e) {
@this.set('car_make_id', $('.select2').select2("val"));
});
});
</script>
only wrap the select element in the div with wire ignore. Do not put it around the @error message
Make sure your component only has one root element
Remove selected from first option.
give your select element an ID and use that instead of the select class
<div class="col-sm-5">
<div wire:ignore >
<select wire:model="car_make_id" class="select2 form-select" id="car_make">
<option value="">Choose Make</option>
@foreach ($makes as $make)
<option value="{{$make->id}}">{{$make->name}}</option>
@endforeach
</select>
</div>
@error('car_make_id')<div class="text-danger">{{ $message }}</div>@enderror
</div>
JS
$(document).ready(function() {
$('#car_make').select2().on('select2:select', function (e) {
@this.set('car_make_id', $('#car_make').select2("val"));
});
});
@Snapey
Use code what you provide and getting
response The car make id field is required.
@Laracast13 add debugging to the javascript
$(document).ready(function() {
$('#car_make').select2().on('select2:select', function (e) {
console.log('value changed');
@this.set('car_make_id', $('#car_make').select2("val"));
});
});
and then check in browser console that the message appears when you choose item
@Snapey
console showing: value changed
Without select2 is saves entry but with select to "The car make id field is required."
@Laracast13 Did you do this
Make sure your component only has one root element
Ie, put the script inside the form, or create a wrapper around the form and the script.
@Snapey
After create how reset selct2 ?
for other vales this works
public function cancel()
{
$this->reset();
$this->resetValidation();
}
@Laracast13 Inside documentReady
@this.on('clearSelect', () => {
$('#car_make').val(null).trigger('change');
});
then emit / dispatch the event 'clearSelect'
@Snapey
In Livewire 3
I dispatch like this and works
@this.on('resetSelect2', function () {
$('#car_make').val(null).trigger('change');
});
also edit this (Typed property App\Livewire\ModelComponent::$car_make_id must not be accessed before initialization)
public ?int $car_make_id = null;
Please sign in or create an account to participate in this conversation.