Search code examples
twitter-bootstrapprintingbootstrap-modal

Same page prints twice when using a bootstrap full screen modal


I have a bootstrap full screen modal with a print button that calls window.print(). When the print preview window pops up the pages are doubled. I am using bootstrap 5.

Here's bootstrap modal:

<div class="modal fade" id="Overlay" tabindex="-1" aria-labelledby="Overlay" aria-hidden="true">
        <div class="modal-dialog modal-fullscreen">
            <div class="modal-content">
                <div class="modal-header">
                    <button type="button" data-bs-dismiss="modal" class="btn btn-outline-secondary me-5 no-print"><i class="fas fa-angle-left"></i> Go Back</button>
                    <h1 class="modal-title" id="Overlay">@Title</h1>
                    <button type="button" class="btn-close no-print" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div class="modal-body instructions-body">
                    ...
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary" onclick="window.print()">Print Instuctions</button>
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>

Any ideas?

Thanks, Justin.


Solution

  • The problem is that the content underlying the modal determines how many pages are printed and if you are trying to print the content of the modal it will print duplicates equaling the number pages in the underlying document.

    I had to hide the modal using @media print stylesheets to hide the body using visibility: hidden; then do some fancy javascript onclick of the print button to clone the parts I wanted to print:

    function printModal() {
      printElement(document.getElementById("printContainer"));
    
      var modThis = document.querySelector("#printSection .print");
      modThis.appendChild(document.createTextNode(" "));
    
      window.print();
    }
    
    function printElement(elem) {
      var domClone = elem.cloneNode(true);
    
      var $printSection = document.getElementById("printSection");
    
      if (!$printSection) {
        var $printSection = document.createElement("div");
        $printSection.id = "printSection";
        document.body.appendChild($printSection);
      }
    
      $printSection.innerHTML = "";
    
      $printSection.appendChild(domClone);
    }
    

    Here' the modal HTML:

        <!-- Modal -->
    <div class="modal fade" id="Overlay" tabindex="-1" aria-labelledby="Overlay" aria-hidden="true">
        <div class="modal-dialog modal-fullscreen">
            <div class="modal-content">
                <div class="modal-header">
                    <h1 class="modal-title align-content-center">@Title</h1>
                    <button type="button" class="btn-close no-print" data-bs-dismiss="modal" aria-label="Close"></button>
                </div>
                <div id="printContainer" class="print modal-body instructions-body">
                    // Stuff to print
                   
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary" @onclick="printModal()">Print Instuctions</button>
                    <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
                </div>
            </div>
        </div>
    </div>
    

    TIP: Use dev tools to emulate print view: Click the 3 dots in the upper right > more tools > rendering, set "emulate css media type" to print. This is not completely accurate but will show you what is going to be hidden and visible to the printer.