Found this code to print from javascript. But it opens a window with the document to be printed. Is there a way to hide that document?
var element=document.getElementById(element_id);
var newWin=window.open('','Print-Window','width=400,height=400,top=100,left=100');
newWin.document.open();
/* newWin.document.title = "Readings on PageLinks"; */
newWin.document.write('<html><head><title>Readings on PageLinks</title></head><body onload="window.print()">'+element.innerHTML+'</body></html>');
newWin.document.close();
setTimeout(function(){ newWin.close(); },10);
The print is done onload() for that document, so I guess printing could not be done without it. But can it be hidden?
You can accomplish this using a print-specific stylesheet as described in How to print only a selected HTML element? Don't use window.open() at all; use CSS classes (dynamically applied if need be) to specify which elements should/shouldn't be printed.
Add this to your markup:
<iframe id="ifrOutput" style="display:none;"></iframe>
Add the following javascript function:
function printContainer(content, styleSheet) {
var output = document.getElementById("ifrOutput").contentWindow;
output.document.open();
if (styleSheet !== undefined) {
output.document.write('<link href="' + styleSheet + '" rel="stylesheet" type="text/css" />');
}
output.document.write(content);
output.document.close();
output.focus();
output.print();
}
And call it like so:
// with stylesheet
printHtml('<div>Styled markup</div>', 'printStyles.css');
// without stylesheet
printHtml('<div>Unstyled markup</div>');
Related
I generate some telerik reports on a page which I would like to print when the user clicks "Print". I would like to have a popup window which has the same content as the original report with a print dialog. My current approach is to just copy over the head element using document.write. The problem is that since the head element contains script src which loads external script (and also css loads), when the print dialog appears, the pages are blank. I would like to ensure all the content is loaded first on this new page before print dialog is triggered. How can I do this? Below is my code:
function printElem(elem) {
var mywindow = window.open('', 'PRINT', 'height=600,width=800');
mywindow.document.write('<html><head>' + document.head.innerHTML + '</head><body>');
mywindow.document.write('<h1>' + document.title + '</h1>');
mywindow.document.write(document.getElementById(elem).innerHTML);
mywindow.document.write('</body></html>');
mywindow.print();
return true;
}
Unfortunately, there's no way to build up a page that you'll reveal with window.open. You have two options.
First, you could display a loading view that will be hidden once all the other elements have loaded. This is perhaps the most elegant solution if you're committed to opening another popup.
<div id="loader"><img src="loading.gif /></div>
<div id="content" style="display:none">Stuff to print</div>
<script>
<!-- I know jQuery is taboo nowadays, but you get the idea -->
$(function() {
$('#loader').hide();
$('#pagecontent').show();
});
</script>
Another trick is to write the content and close the window immediately afterward. (I'm not certain if this works on all browsers.)
var css = document.getElementById('the-stylesheet');
var content = document.getElementById('the-content');
var mywindow = window.open('', 'PRINT', 'height=600,width=800');
mywindow.document.write(content.innerHTML);
mywindow.document.close();
mywindow.document.head.appendChild(css);
css.addEventListener('load', function () {
mywindow.focus();
mywindow.print();
});
If you're willing to forgo a popup, another trick would be to use print specific styling on the page.
<style>
#media print {
/* Hide everything you don't need here */
}
</style>
You can use onload event on the new window.
function printElem(elem) {
console.log('new window')
var mywindow = window.open('', 'PRINT', 'height=600,width=800');
// Add this function here
function printWindow(){
console.log('loaded my window');
mywindow.print();
}
// call it once the new window is loaded.
mywindow.document.onload = printWindow();
mywindow.document.write('<html><head>' + document.head.innerHTML + '</head><body>');
mywindow.document.write('<h1>' + document.title + '</h1>');
mywindow.document.write(document.getElementById(elem).innerHTML);
mywindow.document.write('</body></html>');
return true;
}
It may help..
I'm working with a CMS, which prevents editing HTML source for <head> element.
For example I want to add the following above the <title> tag:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" />
You can select it and add to it as normal:
$('head').append('<link />');
JavaScript:
document.getElementsByTagName('head')[0].appendChild( ... );
Make DOM element like so:
const link = document.createElement('link');
link.href = 'href';
link.rel = 'rel';
document.getElementsByTagName('head')[0].appendChild(link);
jQuery
$('head').append( ... );
JavaScript:
document.getElementsByTagName('head')[0].appendChild( ... );
You can use innerHTML to just concat the extra field string;
document.head.innerHTML = document.head.innerHTML + '<link rel="stylesheet>...'
However, you can't guarantee that the extra things you add to the head will be recognised by the browser after the first load, and it's possible you will get a FOUC (flash of unstyled content) as the extra stylesheets are loaded.
I haven't looked at the API in years, but you could also use document.write, which is what was designed for this sort of action. However, this would require you to block the page from rendering until your initial AJAX request has completed.
In the latest browsers (IE9+) you can also use document.head:
Example:
var favicon = document.createElement('link');
favicon.id = 'myFavicon';
favicon.rel = 'shortcut icon';
favicon.href = 'http://www.test.com/my-favicon.ico';
document.head.appendChild(favicon);
Create a temporary element (e. g. DIV), assign your HTML code to its innerHTML property, and then append its child nodes to the HEAD element one by one. For example, like this:
var temp = document.createElement('div');
temp.innerHTML = '<link rel="stylesheet" href="example.css" />'
+ '<script src="foobar.js"><\/script> ';
var head = document.head;
while (temp.firstChild) {
head.appendChild(temp.firstChild);
}
Compared with rewriting entire HEAD contents via its innerHTML, this wouldn’t affect existing child elements of the HEAD element in any way.
Note that scripts inserted this way are apparently not executed automatically, while styles are applied successfully. So if you need scripts to be executed, you should load JS files using Ajax and then execute their contents using eval().
Try a javascript pure:
Library JS:
appendHtml = function(element, html) {
var div = document.createElement('div');
div.innerHTML = html;
while (div.children.length > 0) {
element.appendChild(div.children[0]);
}
}
Type:
appendHtml(document.head, '<link rel="stylesheet" type="text/css" href="http://example.com/example.css"/>');
or jQuery:
$('head').append($('<link rel="stylesheet" type="text/css" />').attr('href', 'http://example.com/example.css'));
With jquery you have other option:
$('head').html($('head').html() + '...');
anyway it is working. JavaScript option others said, thats correct too.
I have been working on a project that I just need to print the contents of a hidden div. The below solution works fine, but replaces the page contents with the div then calls the print of the window and then replaces the page with the original contents. This is fine, but when I click on the page after this or try to print again, the page refreshes.
Is there a way, without opening a new window to print the contents of a div and the page still be functional?
$scope.printDiv = function(printable) {
var restorePage = document.body.innerHTML;
var printContent = document.getElementById(printable).innerHTML;
document.body.innerHTML = "<html><head><title></title></head><body>" + printContent + "</body>";
window.print();
document.body.innerHTML = restorePage;
};
I had created a directive that did something much like this. It involves creating a new window, populating it with the HTML you want printed, printing that window, and then finally closing.
The code looks like the following:
$scope.printPage = function() {
var pageToPrint = $window.open('', 'Print Page', 'width=800, height=600');
pageToPrint.document.write(angular.element(pageHtml).html());
pageToPrint.document.close();
pageToPrint.focus();
pageToPrint.print();
pageToPrint.close();
}
This works in all of the browsers and cleanly closes everything out once the user finishes with the print dialog window.
You can do it with CSS: https://stackoverflow.com/a/356123/1516112
When the user click on your button, wrap your entire page inside a div using the .no-print class. Next add your content in another div next to the previous div. Call print() and restore your page. It should works.
See a similar question that I found: AJAX - Print Page Content
It seems the answer of Matt Razza is what You are looking for.
If you're trying to print invisible content you could use two
different css files for the different media (screen vs print) where
you hide/unhide the required content via display: none; and then
spawn the print dialog via window.print().
<link rel="stylesheet" type="text/css" href="theme1.css" media="screen" />
<link rel="stylesheet" type="text/css" href="theme2.css" media="print" />
<div class="hidden_on_page">YOU CAN'T SEE ME BUT YOU CAN PRINT ME!</div>
<div class="on_page">YOU CAN SEE ME BUT YOU CAN'T PRINT ME</div>
Then in theme1.css:
.hidden_on_page { display: none; }
theme 2.css:
.on_page { display: none; }
And you would trigger the print dialog to spawn when required via:
window.print();
I am using a previous question in SO to help me with this "open-in-new-window" javascript function:
Copy div And his style to new window
So my goal is to open an inline div in a new window and then to be able to print the new window (the div I want to open in the new window is a coupon).
I've accomplished styling the div (to look like a coupon) and set the javascript so that the div does indeed open in a new window, but
1) ...I can't get the style sheet to link to the new window,
2) ...and, I can't get the new window to print (instead nothing happens when I click to print the new window - but when I close the new window, the print dialogue box appears.
here is the code I'm using so far, any help is greatly appreciated:
$('#printCoupon').bind('click', function () {
var printContents = new $("#coupon").clone();
var myWindow = window.open("", "popup", "width=600,height=380,scrollbars=yes,resizable=yes," +
"toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0");
var doc = myWindow.document;
doc.open();
$(printContents).find("#printCoupon").remove();
doc.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
doc.write("<html>");
doc.write("<head>");
doc.write("<link href='http://[link-to-css]/css/coupon.css' rel='stylesheet' type='text/css' />"); // your css file comes here.
doc.write("</head>");
doc.write("<body>");
doc.write($(printContents).html());
doc.write("</body>");
doc.write("</html>");
});
and my html:
<div id="couponWrap">
<div id="coupon">
<h3>Coupon Title</h3>
<p>Present this coupon and receive $10 off labor on your first service visit and 2% loyalty points on you next visit.</p>
</div>
Click to print this coupon.
</div>
Thank you,
Cindy
As far as writing, try the following (removed doc.open() and removed popup argument):
$('#printCoupon').bind('click', function () {
var printContents = new $("#coupon").clone();
var myWindow = window.open("", "", "width=600,height=380,scrollbars=yes,resizable=yes," +
"toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0");
var doc = myWindow.document;
$(printContents).find("#printCoupon").remove();
doc.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
doc.write("<html>");
doc.write("<head>");
doc.write("<link href='http://[link-to-css]/css/coupon.css' rel='stylesheet' type='text/css' />"); // your css file comes here.
doc.write("</head>");
doc.write("<body>");
doc.write($(printContents).html());
doc.write("</body>");
doc.write("</html>");
});
Did you check any issues based on whether your styles are element specific or not #media print? Go back to the reference you gave on where you based your example. Someone else commented this - maybe this is your issue:
It depends on the way the div is styled. If the styles are applied
based on the ID or class then you should be fine to just include the
same stylesheet in the new window. However if any of the styles are
based on the element's ancestors then it becomes tricky as you would
have to copy the ancestral elements in order for the exact styles to
be applied.
It sounds like you ought to be using print-specific styles. You can
apply a stylesheet to print only by including the media="screen"
attribute on the stylesheet link. This stylesheet is then responsible
for hiding any elements in the page that you don't want to print and
positioning the ones that you do. This way you are not subject to
popup blockers and give the user one less step to print the document.
Here is my solution thus far - the javascript stripped the divs from the HTML when opening in a new window, so I simply rewrote the div's back into the new window:
(does anyone know how to write the javascript to have multiple inline DIVs open in a new window when the inline DIVs are on the same webpage? I would need to dynamically generate the IDs, I believe in the code below and in the HTML.)
$('#printCoupon').bind('click', function () {
var printContents = new $("#coupon").clone();
var myWindow = window.open("width=600,height=380");
var doc = myWindow.document;
$(printContents).find("#printCoupon").remove();
doc.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">");
doc.write("<html>");
doc.write("<head>");
doc.write("<link href='http://linktocssfile.css' rel='stylesheet' type='text/css' />"); // your css file comes here.
doc.write("</head>");
doc.write("<body>");
doc.write("<div id='coupon'>");
doc.write($(printContents).html());
doc.write("</div>");
doc.write("</body>");
doc.write("</html>");
});
Good day.
I am currently working on a project that prints a desired <div> to a printer.
Here is the code:
var printContents = document.getElementById(id).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
document.body.style.display = "none";
window.print();
document.body.innerHTML = originalContents;
document.body.style.display = "block";
This code works and prints the desired <div>, but after that I need to put back the previous page again so I used this statement:
document.body.innerHTML = originalContents;
document.body.style.display = "block";
This displays the previous page but the functionalities of my buttons are gone?! Can someone explain to me what happened and is there a solution to this problem? Thanks in advance!
This is happening because you've wiped out the old DOM which had events wired up to it, and replaced it with a totally new, different DOM that just happens to have the same HTML.
Presumably you're taking this approach because the printable zone is determined at runtime. A less-destructive solution might be to create a new <iframe> and copy the desired markup into that; then invoke print() on the iframe. Something like:
var printElement = function(element) {
var frame = document.createElement('iframe');
document.appendChild(frame);
frame.contentDocument.innerHTML = element.innerHTML;
frame.contentWindow.print();
document.removeChild(frame);
};
You'll also need to copy over any CSS references into the <iframe>.
(note this is pseudo-code and not tested)
Your code clears the document and then puts back the HTML stored in originalContents, but this variable stores only a string, so all previously registered event handlers are gone.
Why don't you create a print stylesheet and hide everything except the content that you want to print?
<link rel="stylesheet" type="text/css" href="print.css" media="print">
When you reset the innerHTML, you don't get all your event handlers back. They are wiped out when you create entirely new DOM elements.
One idea would be to have two master divs in the body, one that is your normal display and one that is what you want to print. You can then hide whichever one you don't want to display like this:
<body>
<div id="mainContent">main screen content goes here</div>
<div id="printContent">generated print content goes here</div>
</body>
// hide main content
var mainDiv = document.getElementById("mainContent");
mainDiv.style.display = "none";
// put content to print in the print div and show it
var printDiv = document.getElementById("printContent");
printDiv.innerHTML = document.getElementById(id).innerHTML;
printDiv.style.display = "block";
// print
window.print();
// restore visibility
mainDiv.style.display = "block";
printDiv.style.display = "none;
You could also just use the whole body for printing and use a stylesheet with media="print" to control the visibility of the things you do/don't want to print.
You can add a click event to all dives inside your page so that user can click the div.
after that add a class to that div which the class is defined within the print CSS file.
inside css print file use the following code:
`*{display:none}
.printableDiv{display:block}`
to define a print css file use this code :
<link rel="stylesheet" type="text/css" href="print.css" media="print"> (which Rafael has told you ).
good luck