Search code examples
laravel-livewirelivewires

Bootstrap select2 in livewire keeps disappearing when I submit the form


I have a problem with my code the select2 is displaying only once when I refresh the page but it disappears when I submit the form or if there was a validation error it will disappear too. I tried wire:ignore The select2 doesn't disappear but it stops working properly and the form considered it like if it doesn't exist. I use laravel 8, livewire 2 and turbolinks. Any help would be appreciated I've been stuck for almost 2 weeks. Here is my code :

Blade:

 <form wire:submit.prevent="submit">
            {{ csrf_field() }}
            <div class="form-group row">
                <label for="to" class="col-form-label col-md-1">à :</label>
                <div class="col-md-11" >
                    <select  class="form-control mul-select" wire:model.lazy="id_to" name="id_to[]" multiple="multiple">
                        <option value="test@gmail.com">test@gmail.com</option>
                        <option value="test5@gmail.com">test5@gmail.com</option>
                    </select>
                    <div class="text-danger">
                        @error('id_to')
                            <span>
                                <strong>{{ $message }}</strong>
                            </span>
                        @enderror
                    </div>
                </div>
            </div>
            <div class="form-group row">
                <label for="cc" class="col-form-label col-md-1">Cc :</label>
                <div class="col-md-11">
                    <input type="text" class="form-control" wire:model.lazy="cc" name="cc" placeholder="Cc">
                    <div class="text-danger">
                        @error('cc')
                            <span>
                                <strong>{{ $message }}</strong>
                            </span>
                        @enderror
                    </div>
                </div>
            </div>
            <div class="form-group row">
                <label for="sujet" class="col-form-label col-md-1">Sujet :</label>
                <div class="col-md-11">
                    <input type="text" class="form-control" wire:model.lazy="sujet" name="sujet" placeholder="Sujet">
                    <div class="text-danger">
                        @error('sujet')
                            <span>
                                <strong>{{ $message }}</strong>
                            </span>
                        @enderror
                    </div>
                </div>
            </div>
            <div class="form-group row">
                <label for="message" class="col-form-label col-md-1">Message :</label>
                <div class="col-md-11">
                    <textarea class="form-control" name="message" wire:model.lazy="message" rows="8"></textarea>
                    <div class="text-danger">
                        @error('message')
                            <span>
                                <strong>{{ $message }}</strong>
                            </span>
                        @enderror
                    </div>
                </div>
            </div>
           {{-- <div class="email-editor">
                <textarea class="form-control" id="summary-ckeditor" name="summary-ckeditor" wire:model.lazy="message"></textarea>
                <div class="text-danger">
                    @error('message')
                        <span>
                            <strong>{{ $message }}</strong>
                        </span>
                    @enderror
                </div>
             </div> --}}
                <div class="email-action mt-3">
                    <button class="btn btn-primary" type="submit">Envoyer</button>
                    <button class="btn btn-warning" wire:click="resetForm">Reset</button>
                </div>
        </form>



<script type="text/javascript">

        document.addEventListener("livewire:load", function (event) {
           $(document).ready(function() {
               $('.mul-select').select2();
           });
          });
  
</script>

Component:

  public $id_to, $id_from, $sujet, $cc, $message;

public $rules=[

    'id_to' => 'required',
    'id_from' => '',
    'cc' => '',
    'sujet' => 'required|max:30',
    'message' => 'required|max:155',

];
    public function render()
{
    return view('livewire.admin.messages.messages');
}

public function submit()
{
    $validateData=$this->validate();
    $to_email=User::where('email', $validateData['id_to'])->first();


             Mail::send(array(), array(), function ($message) {
            $validateData=$this->validate();
            $emails=$validateData['id_to'];

            foreach($emails as $email)
            {
            $message->to($email)
              ->subject($validateData['sujet'])
              ->from(Auth::user()->email, 'ADMIN')
              ->setBody($validateData['message']);
            }
          });

    $validateData['id_from']=Auth::user()->id;
    $validateData['id_to']= implode(",", $to_email->id);
    SendMessage::create($validateData);

    session()->flash('success', 'data has been sent successfully');
    $this->resetForm();
}
public function resetForm()
{
    $this->id_to = '';
    $this->cc = '';
    $this->sujet = '';
    $this->message = '';
}

Solution

  • Here is a simple way to achieve that

    <div class="col-md-11">
        <div wire:ignore> // this will make sure to ignore DOM changes
            <select
                class="form-control"
                id="mul-select"
                name="id_to[]"
                multiple="multiple"
             >
                 <option value="test@gmail.com">test@gmail.com</option>
                 <option value="test5@gmail.com">test5@gmail.com</option>
            </select>
        </div>
        <div class="text-danger">
            @error('id_to')
                <span>
                    <strong>{{ $message }}</strong>
                </span>
            @enderror
        </div>
    </div>
    

    And then outside of your component root tag make sure you push this script to your layout

    @push('scripts')
    <script>
        $(document).ready(function () {
            $('#mul-select').select2();
    
             $(document).on('change', '#mul-select', function (e) {
                 //when ever the value of changes this will update your PHP variable 
                @this.set('id_to', e.target.value);
            });
        });
    </script>
    @endpush
    

    Finally, on your layout file append the pushed script like this just before closing your body tag

        @stack('scripts')
    </body