Twitter Bootstrap: Print content of modal window

Another solution

Here is a new solution based on Bennett McElwee answer in the same question as mentioned below.

Tested with IE 9 & 10, Opera 12.01, Google Chrome 22 and Firefox 15.0.
jsFiddle example

1.) Add this CSS to your site:

@media screen {
  #printSection {
      display: none;
  }
}

@media print {
  body * {
    visibility:hidden;
  }
  #printSection, #printSection * {
    visibility:visible;
  }
  #printSection {
    position:absolute;
    left:0;
    top:0;
  }
}

2.) Add my JavaScript function

function printElement(elem, append, delimiter) {
    var domClone = elem.cloneNode(true);

    var $printSection = document.getElementById("printSection");

    if (!$printSection) {
        $printSection = document.createElement("div");
        $printSection.id = "printSection";
        document.body.appendChild($printSection);
    }

    if (append !== true) {
        $printSection.innerHTML = "";
    }

    else if (append === true) {
        if (typeof (delimiter) === "string") {
            $printSection.innerHTML += delimiter;
        }
        else if (typeof (delimiter) === "object") {
            $printSection.appendChild(delimiter);
        }
    }

    $printSection.appendChild(domClone);
}​

You're ready to print any element on your site!
Just call printElement() with your element(s) and execute window.print() when you're finished.

Note: If you want to modify the content before it is printed (and only in the print version), checkout this example (provided by waspina in the comments): http://jsfiddle.net/95ezN/121/

One could also use CSS in order to show the additional content in the print version (and only there).


Former solution

I think, you have to hide all other parts of the site via CSS.

It would be the best, to move all non-printable content into a separate DIV:

<body>
  <div class="non-printable">
    <!-- ... -->
  </div>

  <div class="printable">
    <!-- Modal dialog comes here -->
  </div>
</body>

And then in your CSS:

.printable { display: none; }

@media print
{
    .non-printable { display: none; }
    .printable { display: block; }
}

Credits go to Greg who has already answered a similar question: Print <div id="printarea"></div> only?

There is one problem in using JavaScript: the user cannot see a preview - at least in Internet Explorer!


Here's an option using a JQuery extension I made based on the code by waspinator in the comments of the accepted answer:

jQuery.fn.extend({
    printElem: function() {
        var cloned = this.clone();
        var printSection = $('#printSection');
        if (printSection.length == 0) {
            printSection = $('<div id="printSection"></div>')
            $('body').append(printSection);
        }
        printSection.append(cloned);
        var toggleBody = $('body *:visible');
        toggleBody.hide();
        $('#printSection, #printSection *').show();
        window.print();
        printSection.remove();
        toggleBody.show();
    }
});

$(document).ready(function(){
    $(document).on('click', '#btnPrint', function(){
        $('.printMe').printElem();
    });
});

JSFiddle: http://jsfiddle.net/95ezN/1227/

This can be useful if you don't want to have this applied to every single print and just do it on your custom print button (which was my case).


With the currently accepted solution you cannot print the page which contains the dialog itself anymore. Here's a much more dynamic solution:

JavaScript:

$().ready(function () {
    $('.modal.printable').on('shown.bs.modal', function () {
        $('.modal-dialog', this).addClass('focused');
        $('body').addClass('modalprinter');

        if ($(this).hasClass('autoprint')) {
            window.print();
        }
    }).on('hidden.bs.modal', function () {
        $('.modal-dialog', this).removeClass('focused');
        $('body').removeClass('modalprinter');
    });
});

CSS:

@media print {
    body.modalprinter * {
        visibility: hidden;
    }

    body.modalprinter .modal-dialog.focused {
        position: absolute;
        padding: 0;
        margin: 0;
        left: 0;
        top: 0;
    }

    body.modalprinter .modal-dialog.focused .modal-content {
        border-width: 0;
    }

    body.modalprinter .modal-dialog.focused .modal-content .modal-header .modal-title,
    body.modalprinter .modal-dialog.focused .modal-content .modal-body,
    body.modalprinter .modal-dialog.focused .modal-content .modal-body * {
        visibility: visible;
    }

    body.modalprinter .modal-dialog.focused .modal-content .modal-header,
    body.modalprinter .modal-dialog.focused .modal-content .modal-body {
        padding: 0;
    }

    body.modalprinter .modal-dialog.focused .modal-content .modal-header .modal-title {
        margin-bottom: 20px;
    }
}

Example:

<div class="modal fade printable autoprint">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title">Modal title</h4>
      </div>
      <div class="modal-body">
        <p>One fine body&hellip;</p>
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
        <button type="button" class="btn btn-primary" onclick="window.print();">Print</button>
      </div>
    </div><!-- /.modal-content -->
  </div><!-- /.modal-dialog -->
</div><!-- /.modal -->