Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Laracast13's avatar

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();
        });
    });
1 like
15 replies
Snapey's avatar

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.

1 like
Laracast13's avatar

@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
Laracast13's avatar

@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>
Snapey's avatar

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"));
                });
            });
Laracast13's avatar

@Snapey

Use code what you provide and getting

response The car make id field is required.

Snapey's avatar

@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

1 like
Laracast13's avatar

@Snapey console showing: value changed Without select2 is saves entry but with select to "The car make id field is required."

Snapey's avatar
Snapey
Best Answer
Level 122

@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.

2 likes
Laracast13's avatar

@Snapey After create how reset selct2 ?

for other vales this works

    public function cancel()
    {         
        $this->reset();
        $this->resetValidation();    
    }
Snapey's avatar

@Laracast13 Inside documentReady

            @this.on('clearSelect', () => {
                $('#car_make').val(null).trigger('change');
            });

then emit / dispatch the event 'clearSelect'

1 like
Laracast13's avatar

@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 or to participate in this conversation.