0

I have found many answers to issues with modal-backdrop not clearing, but none that seems to work in this particular case:

Framework Joomla3 (hence bootstrap v2.x). On the page I have a multiple links to open a modal containing a preview of another page, each link is previewing a different page passing an id in a window variable so that the script can load the correct page into to modal-content using the id in the link query string when the modal is shown.

All works well on the first time the modal is loaded. It can be closed either by clicking a close button in the modal or by clicking the backdrop outside the modal. The modal-backdrop div is removed okay.

The problem rises on the second and subsequent times the modal is loaded. Each time an extra modal-backdrop div is loaded making the background doubly/tripling/four times darker and closing the modal only removes the last one, so the user has to click 1/2/3... more times to remove the spurious backdrops.

Why is bootstrap loading extra backdrops the subsequent times the modal is opened? The original one has been removed when it the modal was closed so why is bootstrap adding extra ones next time? And how to I stop it?

Other related answers have various suggestions for killing a backdrop but none work here; the extra modal-backdrop divs do not seem to be accessible from any code or css on the page.

Page code (simplified to show only the links and modal script loading script.

<!-- make the modal height adjust to size of window and have a scrollbar if necessary -->
<style type="text/css" media="screen">
    .xbpvmodal .modal-content {padding:15px;max-height:calc(100vh - 190px); overflow:scroll; }
</style>

<p>main page content</p>

<?php foreach($items as $item) : ?>
    <a href="" data-toggle="modal" data-target="#ajax-pvmodal" onclick="window.pvid=<?php echo $item->id; ?>;">click for preview item <?php echo $item->id; ?></a><br />
<?php endforeach; ?>

<p>rest of main page content</p>

<script>
jQuery(document).ready(function(){
// Load view with AJAX
    jQuery('#ajax-pvmodal').on('show', function () {
      jQuery(this).find('.modal-content').load('/link.to.page?id='+window.pvid);
    })
});
</script>
<!-- preview modal window -->
<div class="modal fade xbpvmodal" id="ajax-pvmodal" style="max-width:800px">
    <div class="modal-dialog">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true" 
                style="opacity:unset;line-height:unset;border:none;">&times;</button>
             <h4 class="modal-title" style="margin:5px;">Preview</h4>
        </div>
        <div class="modal-content">
            <!-- Ajax content will be loaded here -->
        </div>
    </div>
</div>

So why is this creating extra backdrops on the second and subsequent instances of the modal display? The only way I can find to clear the backdrops is to reload the page when the modal is hidden like this in the document ready script above.

    jQuery('#ajax-pvmodal').on('hidden', function () {
       document.location.reload(true);
    })    

but this is ugly and destroys the page context.

RogerCO
  • 31
  • 1
  • 4
  • https://stackoverflow.com/questions/39588698/bootstrap-multiple-modals-modal-backdrop-issue OR https://stackoverflow.com/questions/28131376/bootstrap-modal-in-mvc-double-backdrop-backdrop-appearing-twice – Alive to die - Anant Feb 07 '23 at 10:04
  • Please tag your Bootstrap version. In the future, show rendered HTML and not backend code. – isherwood Feb 08 '23 at 16:54

1 Answers1

0

Anant... many thanks. The first one of those I had seen and is for the specific case of a modal within a modal and none of the answers there work in this case.

However the second one hadn't popped up in my searching (there are lots of other similar questions) and it contained a suggestion that put me on a track to work around it.

In short by detecting DOMNodeRemoved you can kill all of the spurious ones when the first one gets removed - but you are still left with the backdrop getting progressively darker each time a modal is loaded.

Which got me wondering if there was a corresponding DOMNodeInserted - which there is but you have to bind it to the document and make sure you don't remove the first one. It works thus:

  jQuery(document).bind('DOMNodeInserted', function(e) {
    var element = e.target;
    if (jQuery(element).hasClass('modal-backdrop')) {
       alert('here we are');
    if (jQuery(".modal-backdrop").length > -1) {
            jQuery(".modal-backdrop").not(':first').remove();
        }
    }
})

for completeness here is the simpler remove the rest when any modal-backdrop is removed

jQuery(document).on("DOMNodeRemoved",".modal-backdrop",function(){
    jQuery(".modal-backdrop").remove();
});

Thanks again. All now good.

RogerCO
  • 31
  • 1
  • 4