Laravel Livewire Select2 Not Working with Wizard Form

By Hardik Savani December 16, 2024 Category : Laravel

In this tips, I will show you solution of select2 not working with wizard form in laravel livewire.

If you are using Livewire, you might face issues when reloading JavaScript libraries like Select2, Datepicker, or Tooltip, especially in step-by-step wizard forms. If these are not working for you, I have a solution.

We will use the morphed hook to reinitialize Select2 in Livewire. The morphed hook runs after all child elements in the component are updated.

Here is a simple example code:

Livewire Class

<?php

use Livewire\Component;

class StepComponent extends Component
{
    public $currentStep = 1;
    public $select1;
    public $options = [];

    public function mount()
    {
        $this->options = [
            ['id' => 1, 'name' => 'Option 1'],
            ['id' => 2, 'name' => 'Option 2'],
            ['id' => 3, 'name' => 'Option 3'],
        ];
    }

    public function updateSelectValue($data)
    {
        $this->select1 = $data['value'];
    }

    public function render()
    {
        return view('livewire.step-component');
    }
}

Livewire Component File

<div>
    @if($currentStep == 1)
        <div wire:ignore>
            <label for="select1">Select an option:</label>
            <select id="select1" class="form-control" style="width: 100%;">
                <option value="">-- Choose an option --</option>
                @foreach($options as $option)
                    <option value="{{ $option['id'] }}"
                        @if($select1 == $option['id']) selected @endif>
                        {{ $option['name'] }}
                    </option>
                @endforeach
            </select>
        </div>

        <div class="mt-3">
            <strong>Selected Value:</strong> {{ $select1 }}
        </div>
    @else
        <div>Step 2 content</div>
    @endif
</div>

<script>
    document.addEventListener('livewire:init', () => {
        // Function to initialize Select2
        function initializeSelect2() {
            $('#select1').select2();

            // Dispatch Livewire event on change
            $('#select1').on('change', function () {
                const selectedValue = $(this).val();

                @this.set('select1', selectedValue);
            });
        }

        initializeSelect2();

        Livewire.hook('morphed',  ({ el, component }) => {
            // Runs after all child elements in `component` are morphed
            console.log($('#select1').html());
            initializeSelect2();
        })
    });
</script>

I hope it can help you...

Tags :
Shares