Vito Andolini
Vito Andolini

Reputation: 109

Using Livewire with multi Select2 multiple input

in one page I have to list the name of the all rooms in a loop and assign employees to the rooms. Some employees uses more than one room. I decided use Livewire for the first time. So I don't have experience with Livewire. I'm using Select2 to choose employees.

My structure is this:

Livewire View

<div>
    @foreach(\App\Models\Room::all() as $room)
        <div class="row">
            <div class="col-2">
                <div class="fw-bold">{{$room->room_code}}</div>
                <div>
                    <p>{{$room->name}}</p>
                </div>
            </div>
            <div class="col-8">
                <div class="row">
                    <div class="col-10">
                        <select class="multiple-select" wire:model="employee.employee" data-placeholder="Choose employee" multiple="multiple">
                            @foreach(\App\Models\Employee::where('status', 1)->get() as $employee)
                                <option value="{{$employee->id}}">{{$employee->first_name." ".$employee->last_name}}</option>
                            @endforeach
                        </select>
                    </div>
                    <div class="col-1">
                        <button class="btn btn-danger" wire:click="assignSave({{$room->id}})"><i class="fa-solid fa-floppy-disk icon-center"></i></button>
                    </div>
                    <div class="col-1 text-success font-22">
                        <i class="fa-solid fa-check icon-center"></i>
                    </div>
                </div>
            </div>
        </div>
    @endforeach
</div>

Livewire Controller

<?php

namespace App\Http\Livewire;

use Livewire\Component;

class RoomAssign extends Component
{
    public $employee = [];
    
    public function render()
    {
        return view('livewire.room-assign');
    }

    public function assignSave($room){
        dd($this->employee);
    }
}

This is the blade

@section('sub-page-content')
    <h6 class="mb-0 text-uppercase">Room Assign</h6>
    <hr/>
    <div class="card">
        <div class="card-body">
            <livewire:room-assign />
        </div>
    </div>

@endsection
@section('customjs')
    <script src="{{asset('assets/plugins/select2/js/select24.min.js')}}"></script>
    <script src="{{asset('assets/js/form-select2.js')}}"></script>

    <script>
        $('.multiple-select').on('change', function (){
            alert('asdasd');
        })
    </script>
@endsection

Idea is simple. Take room id and employee id and save to a pivot table both information. But I can't evet take employees array. In every loop I have a save button for that room to save records and I want to inform user is process is successful. For information I left a div to show a simple "green tick". Can you help me about taking the employee ids and notify the user?

Save Notification

Upvotes: 0

Views: 3142

Answers (2)

Ray C
Ray C

Reputation: 310

Need to add wire:ignore for select2. I would also change the $employeevariable in your foreach since you're using it in your Livewire component as well and is more than likely causing a conflict. Use something like $employeeInfo instead for the foreach

<div class="col-10" wire:ignore>
    <select class="multiple-select" wire:model="employee" id="employee" data-placeholder="Choose employee" multiple="multiple">
        @foreach(\App\Models\Employee::where('status', 1)->get() as $employeeInfo)
            <option value="{{$employeeInfo->id}}">{{$employeeInfo->first_name." ".$employeeInfo->last_name}}</option>
        @endforeach
    </select>
</div>

When using Livewire with select2 you need to setup a listener for the select

public $employee = [];

protected $listeners = [
    'employee',
];

public function employee($value)
{
    $this->employee = $value;
}

And in your script tag:

$(document).ready(function() {
    window.initSelectDrop=()=>{
        $('#employee').select2({
        placeholder: '{{ __('locale.Select ....') }}',
        allowClear: true});
    }
    initSelectDrop();
    $('#employee').on('change', function (e) {
        livewire.emit('employee', e.target.value)
    });
});

I had this same issue, when Livewire re-renders the component it will break select2 drop downs. Using this approach select2 will act as expected.

Upvotes: 3

Moayad Abukhadra
Moayad Abukhadra

Reputation: 1

  public function storeRoomEmployees(Room $room){
    
       $room->employees()->attach($this->employees)
    
    }

/* some suggestions on Your code 
 1. instead of this @foreach(\App\Models\Room::all() as $room) in your 
    blade, define a variable in Livewire Controller public $rooms.

 2. add mount function 


 public function mount(){
    $this->rooms = Room::all();
  }
    
// mount function runs before the content load

@foreach(\App\Models\Room::all() as $room) -> @foreach($rooms as $room)

*/
   

Upvotes: 0

Related Questions