How do I print the indicated div (without manually disabling all other content on the page)?
I want to avoid a new preview dialog, so creating a new window with this
If you only want to print this div, you must use the instruction:
@media print{
*{display:none;}
#mydiv{display:block;}
}
Here is a general solution, using CSS only, which I have verified to work.
@media print {
body * {
visibility: hidden;
}
#section-to-print, #section-to-print * {
visibility: visible;
}
#section-to-print {
position: absolute;
left: 0;
top: 0;
}
}
Alternative approaches aren't so good. Using display
is tricky because if any element has display:none
then none of its descendants will display either. To use it, you have to change the structure of your page.
Using visibility
works better since you can turn on visibility for descendants. The invisible elements still affect the layout though, so I move section-to-print
to the top left so it prints properly.
Could you use a print stylesheet, and use CSS to arrange the content you wanted printed? Read this article for more pointers.
printDiv(divId): A generalized solution to print any div on any page.
I had a similar issue but I wanted (a) to be able to print the whole page, or (b) print any one of several specific areas. My solution, thanks to much of the above, allows you to specify any div object to be printed.
The key for this solution is to add an appropriate rule to the the print media style sheet so that the requested div (and its contents) will be printed.
First, create the needed print css to suppress everything (but without the specific rule to allow the element you want to print).
<style type="text/css" media="print">
body {visibility:hidden; }
.noprintarea {visibility:hidden; display:none}
.noprintcontent { visibility:hidden; }
.print { visibility:visible; display:block; }
</style>
Note that I have added new class rules:
Then insert three JavaScript functions. The first merely toggles the print media style sheet on and off.
function disableSheet(thisSheet,setDisabled)
{ document.styleSheets[thisSheet].disabled=setDisabled; }
The second does the real work and the third cleans up afterward. The second (printDiv) activates the print media style sheet, then appends a new rule to allow the desired div to print, issues the print, and then adds a delay before the final housekeeping (otherwise the styles can be reset before the print is actually done.)
function printDiv(divId)
{
// Enable the print CSS: (this temporarily disables being able to print the whole page)
disableSheet(0,false);
// Get the print style sheet and add a new rule for this div
var sheetObj=document.styleSheets[0];
var showDivCSS="visibility:visible;display:block;position:absolute;top:30px;left:30px;";
if (sheetObj.rules) { sheetObj.addRule("#"+divId,showDivCSS); }
else { sheetObj.insertRule("#"+divId+"{"+showDivCSS+"}",sheetObj.cssRules.length); }
print();
// need a brief delay or the whole page will print
setTimeout("printDivRestore()",100);
}
The final functions deletes the added rule and sets the print style again to disabled so the whole page can be printed.
function printDivRestore()
{
// remove the div-specific rule
var sheetObj=document.styleSheets[0];
if (sheetObj.rules) { sheetObj.removeRule(sheetObj.rules.length-1); }
else { sheetObj.deleteRule(sheetObj.cssRules.length-1); }
// and re-enable whole page printing
disableSheet(0,true);
}
The only other thing to do is to add one line to your onload processing so that the print style is initially disabled thereby allowing whole page printing.
<body onLoad='disableSheet(0,true)'>
Then, from anywhere in your document, you can print a div. Just issue printDiv("thedivid") from a button or whatever.
A big plus for this approach it provides a general solution to printing selected content from within a page. It also allows use of existing styles for elements that are printed - including the containing div.
NOTE: In my implementation, this must be the first style sheet. Change the sheet references (0) to the appropriate sheet number if you need to make it later in the sheet sequence.
The printDiv() function came out a few times, but in that case, you loose all your binding elements and input values. So, my solution is to create a div for everything called "body_allin" and another one outside the first one called "body_print".
Then you call this function:
function printDiv(divName){
var printContents = document.getElementById(divName).innerHTML;
document.getElementById("body_print").innerHTML = printContents;
document.getElementById("body_allin").style.display = "none";
document.getElementById("body_print").style.display = "";
window.print();
document.getElementById("body_print").innerHTML = "";
document.getElementById("body_allin").style.display = "";
document.getElementById("body_print").style.display = "none";
}
I'm very late to this party, but I'd like to pitch in with yet another approach. I wrote a tiny JavaScript module called PrintElements for dynamically printing parts of a webpage.
It works by iterating through selected node elements, and for each node, it traverses up the DOM tree until the BODY element. At each level, including the initial one (which is the to-be-printed node’s level), it attaches a marker class (pe-preserve-print
) to the current node. Then attaches another marker class (pe-no-print
) to all siblings of the current node, but only if there is no pe-preserve-print
class on them. As a third act, it also attaches another class to preserved ancestor elements pe-preserve-ancestor
.
A dead-simple supplementary print-only css will hide and show respective elements. Some benefits of this approach is that all styles are preserved, it does not open a new window, there is no need to move around a lot of DOM elements, and generally it is non-invasive with your original document.
See the demo, or read the related article for further details.