flowbite
flowbite copied to clipboard
Closing modal keeps backdrop
Describe the bug When I close a modal using javascript, the backdrop remains.
To Reproduce Steps to reproduce the behavior:
- Close a modal using javascript
Expected behavior The modal should completely close.
Screenshots
Desktop (please complete the following information):
- OS: Fedora 40
- Chrome
- 128.0.6613.137
Additional context Here's my code: https://gist.github.com/alec-jensen/80a7b28aa8302cb36fa1a2a62a581eee
Hey @alec-jensen,
Are you sure this is the only instance of the modal?
Check window.FlowbiteInstances.
Reminder for myself: need to check instance creation for modals
I'm not sure if this will help, I had a similar situation this afternoon.
After trying for several hours, I found out it was because I was using data-modal-toggle mixed with modal.hide().
Therefore I removed data-modal-toggle and used modal.show(), and it worked 🎊 , the backdrop disappeared automatically.
Here are my code (I am using Angular 18 & TypeScript):
<!-- Parent template -->
<button type="button" data-modal-target="visit-edit-modal" (click)="showModal()">Open Modal</button>
<app-visit-edit-modal [app]="app" (appChange)="updateApp($event)" (modalEvent)="onModalReceived($event)"></app-visit-edit-modal>
// Parent component
// ...
modalInstance!: Modal;
onModalReceived(e: any): void {
this.modalInstance = e;
}
showModal(): void {
if (this.modalInstance) {
this.modalInstance.show();
}
}
updateApp(e: any) {
console.log('updated data', e)
}
// ...
<!-- app-visit-edit-modal template -->
<app-modal [modalName]="'visit-edit-modal'" [modalHeader]="'入館申請修改'" (modalEvent)="onModalReceived($event)">
<form>
<!-- Labels and inputs ... -->
<div class="flex justify-end mt-2">
<button type="button" (click)="submitForm()">Confirm</button>
</div>
</form>
</app-modal>
// app-visit-edit-modal component
// ...
@Input({ required: true }) app!: Application;
@Output() appChange = new EventEmitter<any>();
modal!: Modal;
@Output() modalEvent = new EventEmitter<Modal>();
onModalReceived(modal: Modal) {
this.modal = modal;
this.modalEvent.emit(this.modal);
}
submitForm(): void {
this.appChange.emit(this.fg.value);
this.modal.hide();
}
// ...
<!-- modal template -->
<div [id]="modalName()" tabindex="-1" aria-hidden="true" #myModal
class="hidden overflow-y-auto overflow-x-hidden fixed top-0 right-0 left-0 z-50 justify-center items-center w-full md:inset-0 h-[calc(100%-1rem)] max-h-full">
<div class="relative p-4 w-full {{size()}} max-h-full">
<!-- Modal content -->
<div class="relative bg-white rounded-lg shadow dark:bg-gray-700">
<!-- Modal header -->
<div class="flex items-center justify-between p-4 md:p-5 border-b rounded-t dark:border-gray-600">
<h3 class="text-xl font-semibold text-gray-900 dark:text-white">{{modalHeader()}}</h3>
<button type="button" [attr.data-modal-hide]="modalName()"
class="end-2.5 text-gray-400 bg-transparent hover:bg-gray-200 hover:text-gray-900 rounded-lg text-sm w-8 h-8 ms-auto inline-flex justify-center items-center dark:hover:bg-gray-600 dark:hover:text-white">
<svg class="w-3 h-3" aria-hidden="true" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 14 14">
<path stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="m1 1 6 6m0 0 6 6M7 7l6-6M7 7l-6 6" />
</svg>
<span class="sr-only">Close modal</span>
</button>
</div>
<!-- Modal body -->
<div class="p-4 md:p-5 max-h-[calc(100vh-8rem)] overflow-y-auto">
<ng-content></ng-content>
</div>
</div>
</div>
</div>
// modal component
// ...
@ViewChild('myModal') myModal!: ElementRef<HTMLElement>;
modal!: Modal;
modalOptions: ModalOptions = {
placement: 'bottom-right',
backdrop: 'dynamic',
backdropClasses: 'bg-gray-900/50 dark:bg-gray-900/80 fixed inset-0 z-40',
closable: true,
onHide: () => {
console.log('modal is hidden');
},
onShow: () => {
console.log('modal is shown');
},
onToggle: () => {
console.log('modal has been toggled');
},
};
instanceOptions: InstanceOptions = {
id: 'modalEl',
override: true
};
@Output() modalEvent = new EventEmitter<Modal>();
ngAfterViewInit(): void {
if (this.myModal) {
this.instanceOptions.id = this.modalName();
this.modal = new Modal(this.myModal.nativeElement, this.modalOptions, this.instanceOptions);
this.modalEvent.emit(this.modal);
}
}
// ...
@sammiehsieh Thank you for sharing the solution. Removing 'data-modal-toggle' worked for me too. I guess this was the bug.