ctyler's avatar

Livewire Bootstrap Modal not closing

Hello, I am having an issue with a recent install (laravel 9). I have added an Users index page with a Bootstrap 5 modal. It pops up correctly. I can add a user and the data is reset. I emit an event and the Modal does not close.

Here is the component method that is working in the UserIndex Component.

public function createNewUser()
    {
        $data = $this->validate([
            'firstname' => ['required', 'string', 'max:255'],
            'lastname' => ['required', 'string', 'max:255'],
            'address' => ['required', 'string', 'max:255'],
            'address2' => ['nullable', 'string', 'max:255'],
            'city' => ['required', 'string', 'max:255'],
            'state' => ['required', 'alpha', 'max:2'],
            'zipcode' => ['required', 'string', 'max:9'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'phone' => ['required', 'digits_between:10,11'],
            'birthdate' => ['required', 'date_format:m-d-Y'],
            'provider' => ['required', 'int'],
        ]);
        $user = User::create([
            'firstname' => $this->firstname,
            'lastname' => $this->lastname,
            'address' => $this->address,
            'address2' => $this->address2,
            'city' => $this->city,
            'state' => $this->state,
            'zipcode' => $this->zipcode,
            'birthdate' => $this->birthdate,
            'email' => $this->email,
            'password' => '',
            'created_by' => auth()->user()->id,
        ]);
        $this->resetInput();
        $this->dispatchBrowserEvent('close-modal');
    }

Here is the Livewire components view button and modal

<div>
                <button type="button"
                        data-bs-toggle="modal"
                        data-bs-target="#createNewUserModal"
                        class="btn btn-success">
                    <i class="fa fa-plus"></i> NEW
                </button>
            </div>

Here is the modal

<div wire:ignore.self class="modal fade" id="createNewUserModal" data-bs-backdrop="static" data-bs-keyboard="false"
         tabindex="-1" aria-labelledby="createNewUserModalLabel" aria-hidden="true">
        <div class="modal-dialog modal-lg">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title" id="createNewUserModalLabel">Create New User</h5>
                    <button type="button" class="btn-close" data-bs-dismiss="modal" wire:click="closeModal" aria-label="Close"></button>
                </div>
                <form wire:submit.prevent="createNewUser">
                    <div class="modal-body">
                        <div class="row">
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="firstname">
                                        First Name:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="firstname" type="text" id="firstname"
                                                          name="firstname"
                                                          value="{{old('firstname')}}"/>
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="lastname">
                                        Last Name:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="lastname" type="text" id="lastname"
                                                          name="lastname"
                                                          value="{{old('lastname')}}"/>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="address">
                                        Address:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="address" type="text" id="address" name="address"
                                                          value="{{old('address')}}"/>
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="address2">
                                        Address 2:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="address2" type="text" id="address2"
                                                          name="address2"
                                                          value="{{old('address2')}}"/>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="city">
                                        City:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="city" type="text" id="city" name="city"
                                                          value="{{old('city')}}"/>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="mb-3">
                                    <x-global.forms.label for="state">
                                        State:
                                    </x-global.forms.label>
                                    <x-global.forms.select wire:model="state" id="state" name="state">
                                        <option value="MI">
                                            Michigan
                                        </option>
                                       
                                    </x-global.forms.select>
                                </div>
                            </div>
                            <div class="col-md-3">
                                <div class="mb-3">
                                    <x-global.forms.label for="zipcode">
                                        Zip Code:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="zipcode" type="text" id="zipcode" name="zipcode"
                                                          value="{{old('zipcode')}}"/>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="phone">
                                        Phone:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="phone" type="text" id="phone" name="phone"
                                                          value="{{old('phone')}}"/>
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="email">
                                        Email:
                                    </x-global.forms.label>
                                    <x-global.forms.input wire:model="email" type="email" id="email" name="email"
                                                          value="{{old('email')}}"/>
                                </div>
                            </div>
                        </div>
                        <div class="row">
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="birthday">
                                        Birthday:
                                    </x-global.forms.label>
                                    <x-global.forms.datepicker
                                            wire:model="birthdate"
                                            name="birthdate"
                                            placeholder="Select date.."
                                            value="{{old('birthdate', $date)}}"
                                    />
                                </div>
                            </div>
                            <div class="col-md-6">
                                <div class="mb-3">
                                    <x-global.forms.label for="provider">
                                        Provider:
                                    </x-global.forms.label>
                                    <x-global.forms.select wire:model="provider" id="provider" name="provider"
                                                           placeholder="Please choose a provider">
                                        @forelse($providers as $provider)
                                            <option value="{{ $provider->id }}" @selected(old('provider') == $provider->id)>
                                                {{ $provider->name }}
                                            </option>
                                        @empty
                                            <option value="">
                                                no providers available
                                            </option>
                                        @endforelse
                                    </x-global.forms.select>
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal" wire:click="closeModal">Cancel</button>
                        <button type="submit" class="btn btn-success">SAVE</button>
                    </div>
                </form>
            </div>
        </div>
    </div>

Here is the blade view

<x-back.layouts.master>
    <x-slot:title>Dashboard</x-slot:title>
    @push('head-scripts')

    @endpush

    @livewire('back.admin.user.user-index')
    @push('footer-scripts')
        <script>
            window.addEventListener('close-modal', event => {
                $('#createNewUserModal').modal('hide');
            })
        </script>
    @endpush
</x-back.layouts.master>

I cannot seem to figure out what the problem is. Any assistance would be appreciated.

0 likes
3 replies
vincent15000's avatar

I think that your code would run correctly if the $('#createNewUserModal') variable had been declared in the same script, then opened in the script and closed in the script.

In your case, I would try something like this.

$('#myModal').on('hidden.bs.modal', function (e) {
  // do something...
})

Taken from the documentation.

https://getbootstrap.com/docs/4.0/components/modal/#via-javascript

ctyler's avatar

@vincent15000 I added jQuery to the application and it worked. However, I thought Bootstrap5 was jQuery independent.

I am going to give your suggestion a try thought. I do not want to add anything the the application unless it is necessary.

1 like
vincent15000's avatar
Level 63

@ctyler You can do the same without jQuery. You just have to use some native selectors from JS, for example like querySelector and attach the event with addEventListener.

1 like

Please or to participate in this conversation.