maraet
maraet

Reputation: 277

select2 on Laravel Livewire does not work

I implemente select2 in a select as the official documentation indicates and I can't get it to work in full.

<div>
<div wire:ignore>
    <select class="js-example-basic-single" name="state">
        <option value="AL">Alabama</option>
        <option value="WY">Wyoming</option>
    </select>

    <!-- Select2 will insert it's DOM here. -->
</div>
@push('scripts')
<script>
    $(document).ready(function() {
        $('.js-example-basic-single').select2();
        $('.js-example-basic-single').on('change', function (e) {
            @this.set('foo', e.target.value);
        });
    });
</script>
@endpush

if I remove the following script in the view the select2 component renders fine

$('.js-example-basic-single').on('change', function (e) {
                @this.set('foo', e.target.value);
            });

but of course I lose the desired functionality.

The selct2 add links I use are as follows

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="{{asset('SitioWeb/assets/select2/js/select2.min.js')}}"></script>

what am i missing?

Upvotes: 4

Views: 12227

Answers (4)

Mehedi
Mehedi

Reputation: 76

Recently got this problem and the way I've solved is extracting value from array/object as when debug sometimes I get value in array & sometime object (though not sure why I got both for different cases.) Anyway here is an example:

public function getRules()
{
    // Extract the currency ID if it's a JSON object
    $currencyId = is_array($this->currency) ? $this->currency['value'] : $this->currency;
    $this->currency = is_object($this->currency) ? $this->currency->value : $currencyId;

    // Extract the status value if it's a JSON object
    $status = is_array($this->status) ? $this->status['value'] : $this->status;
    $this->status = is_object($this->status) ? $this->status->value : $status;

    return [
        'currency' => 'required|exists:currencies,id,active,1',
        'status' => 'required|string|in:pending,active,inactive,disabled',
    ];
}

Now validating and create/update data

public function register()
{
    // Validate the form data
    $this->validate($this->getRules());

    // Update the business record
    Business::where('id', $this->business_id)->update([
        'name' => $this->business_name,
        'currency_id' => $this->currency,
        'status' => $this->status,
    ]);

    session()->flash('success', 'Data updated successful!');

    // Redirect to the business index page
    return redirect()->route('admin.superadmin.business.index');
}

Upvotes: 0

Felix Wiafe
Felix Wiafe

Reputation: 21

Due to the way select2 works, livewire's wire:model and wire:change may not work with select2. Livewire's wire:model and wire:change work perfectly with the traditional HTML select control. To use select to with livewire's wire:model and wire:change, write a js code to get the selected value from select2, then use Livewire.emit() to send the selected value to your component and handle it from there. Example js code is as follows:

    $(document).ready(function() {
        $('#id').select2();
        $('#id').on('change', function(e) { 
            Livewire.emit('listenerReferenceHere', 
            $('#id').select2("val"));
        });
    });

Your Livewire component :

...
protected $listeners = ['listenerReferenceHere'];

public function listenerReferenceHere($selectedValue)
{ 
    //Do something with the selected2's selected value here
}

I hope this helps... 😊

Upvotes: 2

ersen
ersen

Reputation: 1

I tried hard to combine livewire with select2 and finally found the solution that way.

UsersComponent.php

class Users extends Component
{
    public $users = [];

    public function mount()
    {
        $this->users= User::all();
    }

    public function render()
    {
        return view('livewire.users');
    }
}

then

users.blade.php

<div class="col-sm-12 col-xl-3 m-b-30" wire:ignore >
    <div >
        <h4 class="sub-title" >USERS</h4>
        <select class="js-example-basic-single form-control-warning" name="states" >

            @foreach ($users as $user)
                <option value="{{ $user->id }}">{{ $user->name}}</option>
            @endforeach

        </select>
    </div>

</div>

index.blade.php

<p>
@livewire(livewire.users)
</p>

Upvotes: 0

Abdulmajeed
Abdulmajeed

Reputation: 580

you can use Bootstrap-select

npm install bootstrap-select

It worked well for me. this my code.

<div class="form-group">
    <label for="permissions">{{ __('role.permissions') }}</label>
    <div class="col-sm-10">
        <div wire:key="UNIQUE_KEY">
            <div wire:ignore>
                <select id="permissions" wire:model="permissions"
                        data-live-search="true"
                        data-actions-box="true"
                        title="{{__('generic.select')}} {{ __('role.permissions') }}"
                        name="permissions[]" data-width="100%"
                        class="selectpicker permissions" multiple>
                    @foreach($list_permission as $permission)
                        <option value="{{ $permission->id }}"
                                data-subtext="{{ $permission->key }} {{ ' -'. $permission->table_name }}">

                            {{ __('permission.'.$permission->key) }}
                        </option>
                    @endforeach
                </select>
            </div>
        </div>
        @error('permissions') <span class="text-danger">{{ $message }}</span> @enderror
    </div>
</div>

in script :

   ....
   @push('scripts')
        <script>
            Livewire.restart();
            $(function () {
                $('.permissions').selectpicker();
            });
        </script>
    @endpush
</div>

in Component

public $permissions = [];
public $old_permissions = [];

public function updatedPermissions()
{
    $filter_arrays = array_filter($this->permissions);
    $unique = array_unique($filter_arrays);
    $this->permissions = $unique;
}

in update :

 if (! empty($this->old_permissions)){
     $updateRole = $this->role->find($this->modelId)->permissions()->detach();
     $updateRole = $this->role->find($this->modelId)->permissions()->sync($validatedData['permissions']);

  }elseif ($this->old_permissions != $this->permissions ){
     $updateRole = $this->role->find($this->modelId)->permissions()->attach($validatedData['permissions']);
   }

Upvotes: 1

Related Questions