Resize DIV with JavaScript to Fit on Page (To print) - javascript

So I'm trying to resize two Div's that I'd like to print.
Here's the function:
function printDiv(printMe) {
var printContents = document.getElementById(printMe).innerHTML + $('#printMe2').html();
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
This function is being called with a button onClick.
There are Two Divs in total, One of them is a calendar, and the other one is a table. The size is a bit messed up tho. It looks like this:
Original DIV
Print Version:
I'm not so great with JavaScript, so I couldn't try too much. I've searched for relevant things, but sadly no (good) result.
Thanks in advance!

I would create a different css file for print, its much simpler then manipulating html with javascript. here is how you do it:
<link rel="stylesheet" href="print-style.css" type="text/css" media="print" />
or
#media print body {}
here is a good tutorial for print-css
http://edutechwiki.unige.ch/en/CSS_for_print_tutorial

Related

Javascript overwrites data on screen and refreshes page

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();

Generate HTML-page dynamically using Javascript

I have a list of elements where I want the user to be able to print just the clicked element, and not the whole surrounding page. The elements looks as follows:
<div class="element" id="#element1">Element 1</div>
<div class="element" id="#element2">Element 2</div>
<div class="element" id="#element3">Element 3</div>
To be able to print just the element the user clicks, I use this code to fetch whatever element is clicked:
jQuery(document).ready(function($) {
$( '.element' ).click(function() {
var clickedEl = $(this).attr('id');
printDiv( clickedEl );
return false;
});
});
The id of the clicked element is then passed on to a function, creating a very simple HTML-page for print:
function printDiv(id) {
var printContents = document.getElementById(id).innerHTML;
var printContentsBefore = '<html><head>\
<link rel="stylesheet" href="/css/blabla_print.css" type="text/css" />\
</head><body><table><tr>';
var printContentsAfter = '</tr></table></body></html>';
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContentsBefore + printContents + printContentsAfter;
//document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
The code sort of works, but I'm having two problems:
The print window that pops up contains the data of the clicked element about half of the times. The other half the window is empty. How can that be, and how do I solve it?
In the generated page I'm trying to load a CSS-file to format the way the content looks, but without any luck. Is what I'm trying to do here at all possible, and if so how?
And in case it's relevant; the code is being used on a WordPress-based page.
Thanks!
I will never understand why people waste so much effort getting an element's ID, only to then use getElementById to get the element that they already had again...
$(".element").on("click",function() {
printDiv(this);
});
function printDiv(elem) {
var before = '...',
after = '...',
result = before + elem.innerHTML + after;
// now do stuff
}
It's worth noting that window.print() does not necessarily fire immediately. It's not synchronous. It just tells the browser that it should bring up the Print box. Therefore, resetting originalContents back on your content may or may not mess it up, as you have seen.
You may wish to have a "Cancel" button, styled with
#media print {
.cancelbutton {display:none}
}
Which does the actual reset.
Another note is that you are nuking the innerHTML of the page. Any event handlers that you may have will be completely annihilated, except on the body element itself. Just be aware of that.
Personally I would suggest a different method, one that would involve opening a new window/tab with just the content to be printed (you can open a window and document.write to it, for example).

Opening inline div in new window with javascript

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>");
});

Refresh a div on the same page after using click function

I'm using a JavaScript print function that print's the predefined div of a page on click. The function is as following:
<head>
<script type="text/javascript">
function printDiv(any printable div) {
var printContents = document.getElementById(any printable div).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
</script>
</head>
The printer form input method and printable div are as following:
<body>
<input type="button" class="button" onclick="printDiv('any printable div')" name="print" value="print" />
<div id = "any printable div"> On button click contents here are printed </div>
</body>
I'm also using a jQuery text marquee / scroller on the same page that performs it task based on the function:
$(document).ready(function(){
All works fine independently. The problem is that the text marquee / scroller stops scrolling the text when the print button is clicked. The scroller can't scroll the text until the page is refreshed. So I'm using html meta refresh but that may be an annoying experience to the visitors. I don't want to use the scroller in an iframe too.
I've tried some jQuery and JavaScript based solution by this time. The scripts refresh (Just fades in and out the whole block of texts) the div where the scroller is silently but actually can't keep the text scrolling.
Is there any good jQuery or JavaScript based solution available that refreshes the scroller div silently based on the situation I explained above in a given period of time?
You cannot have spaces in your variable name. function printDiv(any printable div) is a syntax error.
Try instead:
function printDiv(elId) {
var printContents = document.getElementById(elId).innerHTML;
var originalContents = document.body.innerHTML;
document.body.innerHTML = printContents;
window.print();
document.body.innerHTML = originalContents;
}
I assume from what you've stated that the intention here is to be able to print only a certain div, rather than an entire page. If that is the case then you are really going to extremes here to perform this function.
If you just want to make a prettier version of the page to print (one without menus, etc) look at How can I have different CSS when I print or print preview?. That question will show how to use a different set of css for printing, so you can set display:none; to anything that you don't want to display when printing.
If you want to print only a single div then you could look at the jQuery print element plugin. This is a simple js file that you link in your html then call
$([selector]).printElement();
to print just that element. Eg you could rewrite your method as so:
function printDiv(anyPrintableDiv) {
$('#' + anyPrintableDiv).printElement();
}

javascript nullifies when setting the document.body.innerHTML

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

Categories

Resources