79452655

Date: 2025-02-19 20:13:31
Score: 1
Natty:
Report link

After a lot of experimentation, I found that handling Bootstrap 5.3 modals in multi‑page apps requires some extra care. The key issues were:

I hope this helps anyone facing similar issues with Bootstrap 5 modals in a multi‑page application! If you have a more elegant or reliable solution, please share so we can all learn from one another.

Tested this solution on: Windows: Chrome, Firefox, Android: Chrome, Firefox IOS: Safari

// PreloaderModal.js (JS Module)
export default class PreloaderModal {
    
    /**
     * Initialize the modal.
     */
    constructor() {
        // Define the modal element
        this.modalEl = document.getElementById( "processingModal" );
        
        // Create a new modal instance in Bootstrap
        this.modalInstance = new bootstrap.Modal( this.modalEl, {
            backdrop: 'static',
            focus: true,
            keyboard: false
        } );

        // This flag to determine if the modal should be hidden, defaults to no.
        this.shouldBeHidden = false;

        // Bind event handlers to ensure proper context
        this.onPageShow = this.onPageShow.bind( this );
    }

    /**
     * Show the modal.
     */
    show() {
        // Reset the flag
        this.shouldBeHidden = false;

        // add fade from the classlist, just in case it was removed
        this.modalEl.classList.add( 'fade' );
        
        // Show the modal.
        this.modalInstance.show();

        // Add event listeners.
        window.addEventListener( 'pageshow', this.onPageShow );

        // attach a one-time listener to the modal for the shown event.
        // there's a possibility of a race condition where the modal is shown but should be hidden
        // if that happens, we hide it immediately.
        this.modalEl.addEventListener('shown.bs.modal', () => {
            if ( this.shouldBeHidden ) {
                this._forceHide();
            }
        }, { once: true });
    }

    /**
     * Hide the modal.
     */
    hide() {
        // Set a flag so that if the shown event fires later, we hide immediately.
        this.shouldBeHidden = true;
        this._forceHide()
    }

    /**
     * Force-hide the modal.
     */
    _forceHide() {
        
        // remove fade from the classlist
        this.modalEl.classList.remove( 'fade' );
        
        // Using internal state check if necessary; note _isShown is not public API.
        if (this.modalInstance._isShown) {
            this.modalInstance.hide();
        }
        
        // As a fallback, force-remove the "show" class and backdrop.
        this.modalEl.classList.remove('show');
        const backdrop = document.querySelector('.modal-backdrop');
        if ( backdrop ) {
            backdrop.remove();
        }
    }

    /**
     * When a pageshow event is detected, check to see if it was persisted (user clicked back/forward button)
     * if so, hide the modal
     * @param {*} event 
     */
    onPageShow( event ) {
        if ( event.persisted ) {
            this.hide();
        }
    }
}
// Using the JS Module
import PreloaderModal from "./components/PreloaderModal";

( function() {

    const preloader = new PreloaderModal();

    // ... do form validation etc.

    preloader.show();

    // ... submit the form

})();

Reasons:
  • Whitelisted phrase (-2): I solved
  • Whitelisted phrase (-1): hope this helps
  • RegEx Blacklisted phrase (2.5): please share
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • Me too answer (2.5): facing similar issue
  • Self-answer (0.5):
  • High reputation (-1):
Posted by: Dave L