Laravel Livewire: Bootstrap Select-Picker unable to render

509 views Asked by At

I want to load categories and multiple sub categories according to all the categories that are selected, inside a multi-step form at step 4, but I am not able to select multiple categories using bootstrap selectpicker (multiple selects) library inside livewire component. The issue with using Bootstrap-Select with Livewire is that both of these libraries use JavaScript to update the page dynamically, which is probably causing conflicts. If I try accessing the same without livewire, it works perfectly fine, but with livewire I am unable to render it.

form.blade

@section('content')
    <livewire:multi-step-form />
@endsection

@push('before-styles')
    <link rel="stylesheet prefetch" href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.1/css/bootstrap-select.css" />
@endpush
@push('before-scripts')
    <script rel="javascript prefetch" src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.1/js/bootstrap.bundle.min.js"></script>
    <script rel="javascript prefetch" src="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/js/bootstrap-select.min.js" integrity="sha512-yDlE7vpGDP7o2eftkCiPZ+yuUyEcaBwoJoIhdXv71KZWugFqEphIS3PU60lEkFaz8RxaVsMpSvQxMBaKVwA5xg==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
@endpush

multi-step-form.blade

<select wire:model="categories" name="categories[]" class="selectpicker form-control" multiple data-live-search="true" required id="categories" title="{{ trans('select category') }}">
    @foreach($categories as $category)
        <option value="{{$category->id}}" {{ (collect(old('categories'))->contains($category->id)) ? 'selected' : '' }}>
            {{$category->category}}
        </option>
    @endforeach
</select>

Some Failed Attempts

Inside livewire component

Attempt 1

<script>
    document.addEventListener('livewire:load', function () {
        $('.selectpicker').selectpicker();
    });
</script>

This works well but only once, i.e. at the start when livewire was loaded. This doesn't work, after the livewire component is updated by some input. So I added a code right below it:

Attempt 2

<script>
    document.addEventListener('livewire:load', function () {
        $('.selectpicker').selectpicker();
        $('.selectpicker').selectpicker('render');
    });
</script>

This didn't work too. Some few articles had render separated in updated script so I did that too.

Attempt 3

<script>
    document.addEventListener('livewire:load', function () {
        $('.selectpicker').selectpicker();
    });

    document.addEventListener('livewire:updated', function () {
        $('.selectpicker').selectpicker('render');
    });
</script>

Unfortunately this didn't work either.

I have tried adding the same scripts to my app.js too later, but am not sure where am I going wrong, and how can I make this working.

Attempt 4 Kept the scripts as is, and added wire:ignore in parent div

<div wire:ignore class="form-group">
    <select wire:model="categories" name="categories[]" class="selectpicker form-control" multiple data-live-search="true" required id="categories" title="{{ trans('select category') }}">
        @foreach($categories as $category)
            <option value="{{$category->id}}" {{ (collect(old('categories'))->contains($category->id)) ? 'selected' : '' }}>
                {{$category->category}}
            </option>
        @endforeach
    </select>
</div>

As suggested in livewire/livewire/issues/45, but this didn't work as well.

1

There are 1 answers

0
Stanley Richter On

You haven't been that far off. Use Livewires Javascript lifecycle hooks documented here.

document.addEventListener("DOMContentLoaded", () => {
        Livewire.hook('component.initialized', (component) => {
            $('.selectpicker').selectpicker();
            $('.selectpicker').selectpicker('render');
        })
    });