Ask Ben: Print Part Of A Web Page With jQuery

Posted May 21, 2009 at 9:10 PM by Ben Nadel

Tags: Javascript / DHTML, Ask Ben

Ben, great new look!! Quick question, I am implementing a jQuery modal pop-up in my app and I want the users to be able to print only the content of that modal window. Any idea? Thanks!

To be honest, I've never done this before, so I am not sure if the following solution is truly cross browser compliant. The jQuery plugin that I authored below was tested to be working in FireFox, IE 7, Safari, and the latest version of Chrome Beta (although Chrome seemed to have some issues with the images from time to time). Before we get into how it works, take a look at this demo video so you can see what I'm talking about:

 
 
 
 
 
 
 
 
 
 

As you can see, I created a jQuery plugin to handle the print() functionality. This way, we can make anything on the page printable using a jQuery selector. The caveat being that the containing element is not printed - only it's child elements get added to the print document. In the following page, when the DOM is ready, we find our link element and have it print (upon click) any element on the page with the class "printable:"

  • <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  • <html>
  • <head>
  • <title>Print Part of a Page With jQuery</title>
  • <script type="text/javascript" src="jquery-1.3.2.js"></script>
  • <script type="text/javascript" src="jquery.print.js"></script>
  • <script type="text/javascript">
  •  
  • // When the document is ready, initialize the link so
  • // that when it is clicked, the printable area of the
  • // page will print.
  • $(
  • function(){
  •  
  • // Hook up the print link.
  • $( "a" )
  • .attr( "href", "javascript:void( 0 )" )
  • .click(
  • function(){
  • // Print the DIV.
  • $( ".printable" ).print();
  •  
  • // Cancel click event.
  • return( false );
  • }
  • )
  • ;
  •  
  • }
  • );
  •  
  • </script>
  •  
  • <style type="text/css">
  •  
  • body {
  • font-family: verdana ;
  • font-size: 14px ;
  • }
  •  
  • h1 {
  • font-size: 180% ;
  • }
  •  
  • h2 {
  • border-bottom: 1px solid #999999 ;
  • }
  •  
  • .printable {
  • border: 1px dotted #CCCCCC ;
  • padding: 10px 10px 10px 10px ;
  • }
  •  
  • img {
  • background-color: #E0E0E0 ;
  • border: 1px solid #666666 ;
  • padding: 5px 5px 5px 5px ;
  • }
  •  
  • a {
  • color: red ;
  • }
  •  
  • </style>
  • </head>
  • <body>
  •  
  • <h1>
  • Print Part of a Page With jQuery
  • </h1>
  •  
  • <p>
  • <a>Print Bio</a>
  • </p>
  •  
  • <div class="printable">
  •  
  • <h2>
  • Jen Rish
  • </h2>
  •  
  • <p>
  • Jen Rish, upcoming fitness and figure model has some
  • crazy developed legs!
  • </p>
  •  
  • <p>
  • <img
  • src="jen_rish_crazy_legs.jpg"
  • width="380"
  • height="570"
  • alt="Jen Rish Has Amazing Legs!"
  • />
  • </p>
  •  
  • <p>
  • I bet she does some <strong>serious squatting</strong>!
  • </p>
  •  
  • </div>
  •  
  • </body>
  • </html>

And, here is the jQuery plugin, print(), that powers this solution:

  • // Create a jquery plugin that prints the given element.
  • jQuery.fn.print = function(){
  • // NOTE: We are trimming the jQuery collection down to the
  • // first element in the collection.
  • if (this.size() > 1){
  • this.eq( 0 ).print();
  • return;
  • } else if (!this.size()){
  • return;
  • }
  •  
  • // ASSERT: At this point, we know that the current jQuery
  • // collection (as defined by THIS), contains only one
  • // printable element.
  •  
  • // Create a random name for the print frame.
  • var strFrameName = ("printer-" + (new Date()).getTime());
  •  
  • // Create an iFrame with the new name.
  • var jFrame = $( "<iframe name='" + strFrameName + "'>" );
  •  
  • // Hide the frame (sort of) and attach to the body.
  • jFrame
  • .css( "width", "1px" )
  • .css( "height", "1px" )
  • .css( "position", "absolute" )
  • .css( "left", "-9999px" )
  • .appendTo( $( "body:first" ) )
  • ;
  •  
  • // Get a FRAMES reference to the new frame.
  • var objFrame = window.frames[ strFrameName ];
  •  
  • // Get a reference to the DOM in the new frame.
  • var objDoc = objFrame.document;
  •  
  • // Grab all the style tags and copy to the new
  • // document so that we capture look and feel of
  • // the current document.
  •  
  • // Create a temp document DIV to hold the style tags.
  • // This is the only way I could find to get the style
  • // tags into IE.
  • var jStyleDiv = $( "<div>" ).append(
  • $( "style" ).clone()
  • );
  •  
  • // Write the HTML for the document. In this, we will
  • // write out the HTML of the current element.
  • objDoc.open();
  • objDoc.write( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" );
  • objDoc.write( "<html>" );
  • objDoc.write( "<body>" );
  • objDoc.write( "<head>" );
  • objDoc.write( "<title>" );
  • objDoc.write( document.title );
  • objDoc.write( "</title>" );
  • objDoc.write( jStyleDiv.html() );
  • objDoc.write( "</head>" );
  • objDoc.write( this.html() );
  • objDoc.write( "</body>" );
  • objDoc.write( "</html>" );
  • objDoc.close();
  •  
  • // Print the document.
  • objFrame.focus();
  • objFrame.print();
  •  
  • // Have the frame remove itself in about a minute so that
  • // we don't build up too many of these frames.
  • setTimeout(
  • function(){
  • jFrame.remove();
  • },
  • (60 * 1000)
  • );
  • }

The plugin itself is not too complicated - we are creating an IFrame on the fly, writing the target HTML to its body, and then printing it. It's a simple concept, but there were some issues getting it to work in Internet Explorer (IE). The following caveats tripped me up at first:

  • In IE, you have to focus() the IFrame before you print it other wise the top page prints.
  • In IE, I kept getting errors when trying to use jQuery to write the STYLE tags to the IFrame head. As such, I had to write the html() of the STYLE tags as I was writing out the document. The Style tags are crucial to in the document because they will determine the look and feel of the printed content.

Once I got those two issues out of the way, the rest worked pretty smoothly. I am not sure if this is the best technique, but hopefully it will point you in the right direction.



Reader Comments

May 22, 2009 at 1:29 AM // reply »
30 Comments

Ben, do you need the timeout before removing the frame? I did some checking with Safari and FF and found that the code beyond the print() call on the frame does not execute until the user finishes with the print dialog. Haven't had a chance to try this on IE, it's late and I don't feel like starting up my Windows VM :)


May 22, 2009 at 5:34 AM // reply »
29 Comments

That's very clever and makes things so much easier from a developer's perspective.

I used to craft a print.css which makes use of the html media type print and hides all GUI elements on the page among with some other markup changes. It does not work flawlessly with all browsers, though.


May 22, 2009 at 5:48 AM // reply »
211 Comments

I just use jqPrint:
http://plugins.jquery.com/project/jqPrint


May 22, 2009 at 8:06 AM // reply »
11,238 Comments

@Todd,

That plugin looks good. Looking at their code, it is a better solution. I totally forgot about pulling over LINK tags :)

@Ryan,

I just assumed that you would need a timeout. I didn't actually test to see if it was necessary.


May 22, 2009 at 8:13 AM // reply »
211 Comments

I'm sorry, I linked to the wrong plugin that I use. I use this one atm:
http://plugins.jquery.com/project/jPrintArea

Unfortunately, it looks to have been abandoned by the author.


May 22, 2009 at 8:18 AM // reply »
11,238 Comments

@Todd,

Looks to be basically the same. I think they said that the first one you posted was actually an update to the second one you posted. But I could be making that up.


May 22, 2009 at 8:24 AM // reply »
211 Comments

@Ben: Different authors, but improved upon. Yes, you're correct.


May 22, 2009 at 9:15 AM // reply »
11,238 Comments

@Todd,

Looking at the code, I saw "contentWindow". I've never seen that before. Looks really useful - thanks for helping me learn some cool stuff :)


May 22, 2009 at 9:52 AM // reply »
11,238 Comments

@Todd,

Thanks again man:

http://www.bennadel.com/blog/1592-Getting-IFRAME-Window-And-Then-Document-References-With-contentWindow.htm


Jun 17, 2009 at 5:46 PM // reply »
1 Comments

Dude you just saved me a ton of time! Very nice plugin!

Thanks


Jun 19, 2009 at 7:10 PM // reply »
11,238 Comments

@Trung,

No problem my man!


Jun 28, 2009 at 3:17 AM // reply »
1 Comments

Very cool work on this plugin. Just what I needed. But, is there any way to make this work with an input button instead of a text link?


Jun 28, 2009 at 5:41 AM // reply »
34 Comments

I know this isn't related to jQuery but why not just have the printable version load in a coldfusion created PDF? It would eliminate all that code. Just saying...


Jun 29, 2009 at 8:48 AM // reply »
11,238 Comments

@Jody,

It wouldn't really eliminate code as you would have to create a new CFM page for generating the PDF. This page would also have to know how to trim down the requested HTML to just the target section. I think going to a PDF would actually increase the code you would need.

@Vernon,

You just need to bind the click event to the button rather than the link.


Jul 21, 2009 at 7:28 PM // reply »
1 Comments

I can't believe how easy it is to implement.

Thank you so much, you saved me time.


Aug 28, 2009 at 12:52 PM // reply »
1 Comments

dont undesrstend why but when i`m printing in FF - it prints on two pages and when i`m printing in IE7 it printing all except my conent http://v8.dxloo.com/vehicle/2004/VOLKSWAGEN/PASSAT/GLS/WAGON/WVWVD63B14E220600/FOR-SALE-IN/FORKED_RIVER/NJ/200012184/


Sep 2, 2009 at 9:06 AM // reply »
7 Comments

I am... kind of a Mr. Magoo type web designer...

I have a pretty simple question:
In the .printable style, do I have to include any attributes? Does this style HAVE to put in a dotted line or anything at all?

My design is all set up with borders, etc already.

I wonder if I can just enclose my existing divs (the ones I want to include in the print area) in the .printable div, which I do not want to add any formatting to the doc.

Is this clear?
thanks!
finn


Sep 2, 2009 at 9:10 AM // reply »
11,238 Comments

@Finnerty,

The dotted line I added for the demo. You don't need it. Really, just the "printable" class should be enough for the jQuery script to hook into.


Sep 2, 2009 at 9:14 AM // reply »
7 Comments

OK! :-)
on my way to the code, to try it all out. Thank you amigo!!
I'll let you know...

(...looks to his right and clucks... "Oh that Waldo... always worrying!")

fin


Sep 2, 2009 at 9:51 AM // reply »
7 Comments

well... it almost works... I saved "snippet_2.txt" as "jquery.print.js" on my server.

I changed the links to both that and the jquery-1.3.2.js file in the head of my doc, and pasted your Head section parts into my Head, including the "initialize print link" stuff.

I put the .printable style into my CSS, changing the border to "none."

I put the div class="printable" tags enclosing what I want to print.

I enclosed a the words "print this page" between the a and /a tags.

OK!

The link does show the "javascript:void (0) that it should (as per the code in the Head) but.. no print.

I'm thinking I am not hooking up to your script correctly in my Head section, or at least, something is not making the connection to the script to do the work.

That's how it goes over here, if you have the time or inclination, maybe the problem is something really obvious, and I just need a nudge... thanks!!


Sep 2, 2009 at 10:09 AM // reply »
7 Comments

OH YEAH!
You MADE MY WEEK!

I stripped out the <!-- comment at the top of "snippet_2 - jquery.print.js" and...
NICE!!!!!

Thank you amigo!!!
finn :-) :-) :-)


Sep 2, 2009 at 10:17 AM // reply »
7 Comments

UH OH.
Now ALL the links on my page want to do the print thing. That has to be as a result of the function "$( "a" )" I assume.

What can I change that to? Can I add an ID or something to both the function and the tag used to call it?

so close...
finn


Sep 2, 2009 at 10:40 AM // reply »
29 Comments

change $("a") to $(".printme a") and add class="printme" to all <a> elemnts which are supposed to initiate the printing routine. (you can have multiple classes assigned to one html element)


Sep 2, 2009 at 11:28 AM // reply »
7 Comments

OK... done... the links on the page go where they are meant to go again.

But now the print link does not work. It isn't communicating the class attribute I guess...

Not sure what's up, unless the fact that the link is also enclosed in a span class... but that doesn't seem like a problem to me...

< span class="archiveLink" >< a class="printme" >print this page< /a >< /span >

I tried switching the $(".printme a") to $("a .printme")but that was a no-go...

I added the .printme class to my stylesheet, with no attributes... nada...

so... I am just bumbling around...
finn


Sep 2, 2009 at 12:39 PM // reply »
29 Comments

Sorry for confusing you. That was my fault.
You can fix it by moving the class attribute printme to the outer span element.
Like this:
< span class="archiveLink" class="printme" >< a >print this page< /a >< /span >

together with this selector:
$(".printme a")


Sep 2, 2009 at 12:47 PM // reply »
29 Comments

Or you can use $("a.printme") (you nearly got it right!) and have the printme class assigned to the a-element instead.

sorry Ben for flooding your blog comments ;)


Sep 2, 2009 at 12:48 PM // reply »
7 Comments

Happy Happy Joy Joy!!!!

I had to make one little adjustment...

I didn't tell you EVERYTHING...

here's what works:

< div id="archiveLinkDiv" class="printme" >
< span class="archiveLink" >< a >print this page< /a >< /span >    |
< /div >

I had the span enclosed in a div... so the "printme" hook is working off of that..

I TOLD you I was a Mr. Magoo!

You are generous and very kind. Thankyou VERY much!
finn


Sep 6, 2009 at 12:04 PM // reply »
11,238 Comments

@Finnerty,

Glad you got it working - yeah, you have to tell the jQuery selector exactly what link to hook up otherwise, it might hook up all of them!

@Martin,

Thanks for jumping in there to help out!


Sep 11, 2009 at 9:04 AM // reply »
1 Comments

Hi,
is it intended to omit
objDoc.write( "<body>" );

Either way, my original page uses <link> tags to it's stylesheet. You know how to get them?

/HW


Sep 12, 2009 at 10:00 PM // reply »
11,238 Comments

@Henrik,

It should be writing the opening body tag in the above example. I'm not sure why that part is not working for you.

As for LINK tags, those should work the same as with the Style tags. You can probably just swap "style" for "link" in the example.


Sep 26, 2009 at 10:39 AM // reply »
1 Comments

Nice plugin it help a lot... thnx....

Do you have some code on how to change the page setup... like changing portrait to landscape?


Sep 29, 2009 at 9:20 AM // reply »
11,238 Comments

@Eljoe,

I do not know of any way to do that, sorry.


Sep 29, 2009 at 9:36 PM // reply »
1 Comments

thanks for the plugin :)

Everything is working great, except, how do I get rid of the URL printed at the top of the page?

thanks


Oct 1, 2009 at 8:16 AM // reply »
11,238 Comments

@Jeff,

I am not sure there is any way to do that, at least not that I know of; that is a function of the browser's printing mechanism itself.


Oct 15, 2009 at 4:44 AM // reply »
5 Comments

Hi,

Do you know of any way I can hide an image from the printed page, without removing it from the underlying page? I've currently got the following which prints without the image, but (obviously) the image flickers when the print dialogue is displayed:

$( "#LeftContent h1 img").css('display', 'none');
$( "#LeftContent" ).print();
$( "#LeftContent h1 img").css('display', 'block');


Oct 15, 2009 at 4:48 AM // reply »
29 Comments

@Darren you can do this via css. search for css media types.

it goes something like this:

@media print {
/* style sheet for print goes here
it only applies to the printed page*/
}


Oct 15, 2009 at 5:13 AM // reply »
5 Comments

Hi Martin,

I do have a print.css file however I don't believe it's referenced when using the print link. If I use File > Print, it prints as intended, using the css file, but not using the javascript link. Is there something glaring that I'm missing?

Thank you for your reply,

Kind regards,

Darren.


Oct 15, 2009 at 7:30 AM // reply »
29 Comments

Hi Darren, does your "temp document DIV" include the print.css, too? It's used for styling the iframe.

# objDoc.open();
# objDoc.write( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" );
# objDoc.write( "<html>" );
# objDoc.write( "<body>" );
# objDoc.write( "<head>" );
# objDoc.write( "<title>" );
# objDoc.write( document.title );
# objDoc.write( "</title>" );
# objDoc.write( jStyleDiv.html() );
# objDoc.write( "</head>" );
# objDoc.write( this.html() );
# objDoc.write( "</body>" );
# objDoc.write( "</html>" );
# objDoc.close();


Oct 15, 2009 at 7:50 AM // reply »
5 Comments

Hi Martin,

Nope, I wasn't referencing the print css file at all... Turns out I was indeed missing something glaringly obvious!

Thank you very much for your help.

Kind regards,

Darren.


Oct 15, 2009 at 8:02 AM // reply »
11,238 Comments

@Martin, @Darren,

Print style sheets are one of those awesome things that I keep forgetting to take any advantage of when I build stuff.


Oct 15, 2009 at 8:02 AM // reply »
5 Comments

Still can't get it to reference the css file, even though it's now included in the temp div (I've tried absolute, and relative links, different locations in the head for the link, and single then no quotes around the attributes...:

objDoc.open();
objDoc.write( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">" );
objDoc.write( "<html>" );
objDoc.write( "<body>" );
objDoc.write( "<head>" );
objDoc.write( "<title>" );
objDoc.write( document.title );
objDoc.write( "</title>" );
objDoc.write( jStyleDiv.html() );
objDoc.write( "<link rel=stylesheet href=/css/print.css type=text/css media=print />" );
objDoc.write( "</head>" );
objDoc.write( this.html() );
objDoc.write( "</body>" );
objDoc.write( "</html>" );
objDoc.close();

Any ideas?

Kind regards,

Darren.


Oct 15, 2009 at 8:16 AM // reply »
29 Comments

Hi Darren, it looks like you're missing the double quotes.

I think this should work:

objDoc.write( "<link rel=\"stylesheet\" href=\"/css/print.css\" type=\"text/css\" media=\"print\" />" );


Oct 15, 2009 at 9:06 AM // reply »
5 Comments

Hi Martin,

Nope, that's not doing it for me either! I got around the image problem by using...

objDoc.write( "<style type=\"text/css\"> img {display:none;}</style> ");

...but haven't been able to reference the css file correctly. Thanks again for all your help though!

Kind regards,

Darren.


Oct 15, 2009 at 11:20 AM // reply »
29 Comments

Hi Darren, nice to read you made it. I've never used the referencing feature myself.
This would be an option as well:
objDoc.write( "<style type=\"text/css\"> @import url(\"./css/print.css\") </style>");

Best Regards
-Martin


Dec 8, 2009 at 9:04 PM // reply »
1 Comments

Nice work. Greets.


Dec 15, 2009 at 3:04 PM // reply »
1 Comments

Cool plugin BUT I'd like to print a dialog that contains a flot graph. The graph is created in a canvas element. Any hints how to print that?
thanks..Sandy


Dec 15, 2009 at 6:07 PM // reply »
11,238 Comments

@Sandy,

Sorry, I have not dealt with canvas elements yet. I assume you are saying they don't print nicely?


Dec 18, 2009 at 9:30 AM // reply »
1 Comments

Hey Ben,

Were you able to ever get this working in IE6? Strangely, you have to click the Print link and then refresh the page to get it to bring up the print dialogue.

Thanks,
Andy


Dec 18, 2009 at 6:13 PM // reply »
1 Comments

I have run across this issue as well. My solution was to tag my header, footer, etc with a no print id like => id="noPrint1", id="noPrint2", etc... Then I use javascript to hide the unwanted elements.

function printCommand() {
document.getElementById("noPrint1").style.display = "none";
document.getElementById("noPrint2").style.display = "none";
document.getElementById("noPrint3").style.display = "none";
document.getElementById("noPrint4").style.display = "none";
document.getElementById("printButton").style.display = "none"
}

Print button is as follows (I'm using an alert after print is done):
<input id="printButton" type="button" value=" PRINT "onclick="printCommand();window.print();setTimeout('alert(\'Finished\')',100); return window.location.reload()" />

The reload function is to retain my GET Vars at the time of printing.

This is just a different approach to solving this issue. It's a simple subtraction method. This may not be exactly what some of you are looking for in it's functionality but the result has worked for me.

Kind Regards,
Tony


l
Dec 30, 2009 at 2:53 PM // reply »
1 Comments

im trying to print a page. it only prints a box and it says plug in content. do you know what i can do?


Jan 5, 2010 at 8:32 AM // reply »
11,238 Comments

@Andy,

I am not sure I ever tested this in IE6.

@Tony,

If you used something like jQuery, you could make that even easier by giving them all a common class name, like "non-printable". Then simply hide/show based on class:

$( ".non-printable" ).hide();

@l,

I have never seen that, sorry.


Jan 15, 2010 at 2:44 PM // reply »
1 Comments

Hi,
this plugin seem to work very differently (in my case its a failure) when the page which i want to print has the following scrollable area.

div style="overflow-y: scroll; overflow-x: auto; height: 50%; width: 90%" id="masterView"

My page has a huge section of information which is listed within a small scrollable section. Once i included the necessary plugin & css, this small section eventhough it's coded for only 50% of the screen, it gets expanded to 100% of height. This completely ruins the UI :-(

Do you have any clues ?


Jan 16, 2010 at 3:59 PM // reply »
11,238 Comments

@Senthil,

I don't have any really good advice on that. I am not sure how you can print an area that has hidden content?


Feb 5, 2010 at 12:53 PM // reply »
1 Comments

Thank you very much! We needed exactly this! JQuery works like a charm! I will post the link of the finish work you for you to see it! Thanks!


Feb 6, 2010 at 5:22 PM // reply »
11,238 Comments

@Daniel,

Great - looking forward to it.


Apr 21, 2010 at 3:45 AM // reply »
1 Comments

it worked for me. greetings @Ben :)


May 14, 2010 at 8:07 AM // reply »
1 Comments

It is a very nice plug-in but it doesn't work in Opera (any versions lower than 10.10). Is there a solution for Opera? thanks :)


May 14, 2010 at 8:48 AM // reply »
29 Comments

@raloocka Todd Rafferty mentioned jqPrint in a comment earlier, which is supposed to work in Opera. http://plugins.jquery.com/project/jqPrint


Jun 4, 2010 at 3:53 AM // reply »
2 Comments

Thanks for the script. This really helped me out.
can you put PDF support as well.


Jun 7, 2010 at 9:34 PM // reply »
11,238 Comments

@Harpreet,

For PDF support, you'd need a server-side language like ColdFusion that was capable of generating PDF... then you'd have to submit to it as well.


Jun 8, 2010 at 2:19 AM // reply »
2 Comments

@Ben Nadel, okay thanks dear...


Jun 10, 2010 at 3:23 PM // reply »
2 Comments

Hey Ben, first off, awesome, well thought out code. I'm using a variant of this method to print the results of a survey from a banner ad. Basically all the same concepts are used, just instead of being selected from the parent window, the html content is generated from flash input, and then injected into the iframe.

The only issue I've seen is in IE7, and IE8, the page prints out scaled down to a smaller size--approximately half the size in fact. This seems to be dependent only on the positioning of the banner itself. Meaning that when the banner's in some places it prints fine, but is scalled down when the banner is in other places. I'm wondering if you have any idea if the placement of content on the page in IE7/8 could affect the print-rendered size of the iframe in some cases. That's the only conclusion I can draw since it's the same code everywhere. I'd love to hear thoughts from the code author's perspective.


Jun 11, 2010 at 11:38 AM // reply »
2 Comments

I actually found a solution that seems to work. For some reason in IE, when you use the document.execCommand function it actually renders the print-page normally with out using any of the auto scaling to fit. It has to be inside a try block because the call throws an error in Firefox. So if it catches an error, or the command doesn't get executed, it prints by the normal means. If you're wondering, I used "exec!=true" because MS spec said it returns true if it executes, but no mention on when it doesn't execute. Not to mention that the code block will sometimes catch an error. Good luck!

objFrame.focus();
try {
var exec = objDoc.execCommand('print',false,null);
}
catch(err)
{
//catch nothing
}
if(exec!=true)
{
objFrame.print();
}


Jun 14, 2010 at 10:56 PM // reply »
11,238 Comments

@Douglas,

I have very little experience with Flash. I like the execCommand() approach; I had never even thought of that - it's been a long time since I even used that command to create bookmarks :)


Jul 12, 2010 at 10:09 AM // reply »
1 Comments

Thank You


Jul 17, 2010 at 10:06 PM // reply »
2 Comments

Hi

Its an awesome code. Wow it worked great.

But I have something more to do, when I am giving a print the length of the controls got changed, I have tables in my code, these tables are having controls like text, textarea when I give a print the text area which I was seeing on the web Page is different from the one which I took print. The difference is the text area size, if some way if I can change the element attributes before printing that would be great, is there any way I can do this.

2) I have a list box with 20 values and size of the listbox is 5, when I give a print its displaying me only 5 values but is there a way where I can increase the size to 20 and print but at the same time my page should have only 5 values displayed

Thank You for your code


Jul 18, 2010 at 11:16 AM // reply »
11,238 Comments

@Malla,

I am not sure how well forms print. If you really need things to change in nature (such as a list box), you might want to consider just creating a print-version of the page.


Jul 22, 2010 at 12:05 AM // reply »
2 Comments

Thank You for your reply, yeah I need to look into that like creating a new page for printing, I can also modify this.html by assigning to var and change the contents of the var, I will take a look into this later. Can I use selectors on var I mean some thing below var x this.html().Can I use jquery selectors on x now.

I am new to JQuery.

Once again Thank you


Jul 22, 2010 at 9:59 PM // reply »
11,238 Comments

@Malla,

Once you have your jQuery object, you can definitely access the html using the .html() method. You can also use things like .find() and .filter() to gather parts of that collection.


Jul 26, 2010 at 1:29 AM // reply »
1 Comments

HI Ben,

Wonderful script. I just have one issue. There are a menu links on the same page where i have my print link. All the other links are becoming as print option. How I can avoid this problem. I want the menu to work as it is and the print option to do what you have done in your script.

Thank you in advance.


Sep 7, 2010 at 4:19 PM // reply »
1 Comments

Excellent module!

FYI, you have some bugs in your HTML markup. You can't put the head tag within the body tag.

Also, writing is fairly slow in general so you could optimize your html by creating a string first and writing once instead of multiple writes.

Here's fixed markup that I have used includes some other optimizations for propagating the body css classes and for including non-inline css:

var printContents = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">" +
"<html>" +
"<head><title>" + document.title + "</title>" +
jStyleDiv.html() +
"</head>" +
bodyStartTag +
this.html() +
"</body></html>";

objDoc.write(printContents);


Sep 9, 2010 at 2:08 PM // reply »
11,238 Comments

@Jaxley,

Oh wow, good point! I can't believe I inverted those. Excellent catch.


Oct 4, 2010 at 11:31 AM // reply »
3 Comments

I've been using this piece of code for awhile, to print a page, and all of the sudden it (and many other jQuery plugins) just stopped working. Now when I try to run the code:

  • $("#printableContent").print();

it returns '$("#printableContent").print is not a function'... Any ideas? I've search around and can't seem to find any other records of this happening. But, it's happened to three of the plugins I use, so far...

Thanks for any assist...

--Charles...


Oct 4, 2010 at 12:16 PM // reply »
3 Comments

Okay, after playing around I found a solution...

Not sure why it works but I changed:

  • $("#printableContent").print();

to this:

  • print("#printableContent");

An now it works fine again... Anyone have any thoughts on why that changed? Maybe it can help anyone else who stumbles on this issue...

Thanks..
--Charles...


Oct 4, 2010 at 9:29 PM // reply »
11,238 Comments

@Charles,

Very weird! It looks like the context of the execution is being manipulated... maybe? I don't really have any insight on that one.


Oct 25, 2010 at 2:22 AM // reply »
1 Comments

Hi everyone,

Running into problems with jqprint, I am considering switching to your snippet.

Does anyone have a revised version of the snippet that includes all the fixes from jaxley and others ?

Thanks in advance,

Jonathan

P.S. Thanks for your blog Ben


Oct 26, 2010 at 5:12 PM // reply »
1 Comments

Hi Ben,

Great work you been doing! I've learned a lot with your great articles.

I noticed a weird issue, don't know why and when, but suddenly the plugin stop working in chrome, I recently updated it to the latest version but i don't know if it has anything to do.... the true is that with FF works just fine and in chrome used to work and now ...pufff!

Any ideas what might happen? Anyone reported you some similiar issue?

Thanks a lot for you time.

Greetings from Portugal.

Tiago Teixeira


Nov 1, 2010 at 9:55 PM // reply »
11,238 Comments

@John,

You might run into problems with the new stylesheet not having time to load. You might look into using a "media query" to get an existing stylesheet to provide print-time styles.

@Tiago,

I don't know sorry. Take a look through the comments - I believe that some people have provided links to more robust jQuery plugins that do this same kind of stuff. I haven't really maintained this at all.


Nov 29, 2010 at 11:23 PM // reply »
2 Comments

where the src of jquery-1.3.2.js ??


Nov 29, 2010 at 11:23 PM // reply »
2 Comments

where the src jquery-1.3.2.js ??


Nov 30, 2010 at 8:50 AM // reply »
3 Comments

You can google.load the code... Here's a link to the info:

http://code.google.com/apis/libraries/devguide.html#jquery


Dec 22, 2010 at 5:54 AM // reply »
1 Comments

Hey Ben,

Thank You very much.., it is being very useful for the beginners like me..

suresh


Jan 6, 2011 at 3:26 PM // reply »
3 Comments

Nice solution that worked for me very well. Thanks!


Jan 31, 2011 at 2:42 AM // reply »
1 Comments

Dear all,
I'm trying to update the html of the printable div by the result of an ajax request. But when i'm trying to print it the print function goes in error ($("#printtable1").print is not a function). So anybody have a solution of this.


Feb 8, 2011 at 1:10 PM // reply »
1 Comments

Thanks! That worked really well...


Feb 9, 2011 at 9:01 AM // reply »
1 Comments

Thank you very much! Just what i need!


Feb 16, 2011 at 1:06 PM // reply »
1 Comments

Thx for this code ;)


Feb 26, 2011 at 9:28 AM // reply »
1 Comments

Just a problem with Twetter's Widget.
It steal not working on IE 7 - 8
Well, I've taken an other way to solve the problem.


Mar 13, 2011 at 5:04 PM // reply »
1 Comments

just got this running, tested on IE 9 & Google Chrome. thanks Ben!


Mar 18, 2011 at 6:26 AM // reply »
1 Comments

Hi Ben!

Nice solution you got here. I actually created a widget for Yii framework so they can print whatever they want to be printed in their page, which can be downloaded at http://www.yiiframework.com/extension/mprint/, and I used your js.

I have enhanced your code (I hope you won't get mad) to make it more fitting to users, and included the insights contributed by jaxley and douglas.

I so have many TODOs for your code, like adding a debug feature. Many thanks to you man. :)

BTW, as of the moment I have it licensed under GNU Lesser GPL. I want to know your opinion, since you are the main man behind my widget. :)


Apr 1, 2011 at 10:58 AM // reply »
1 Comments

In IE 8 i cant reference the DOM (var objDoc = objFrame.document;)

doesn´t anybody has that problem. It just say "document is null or not an
object". ????


Apr 16, 2011 at 3:07 AM // reply »
1 Comments

Thanks a ton!


Apr 22, 2011 at 3:48 PM // reply »
1 Comments

Hy ben, nice plugin..

btw, i'm having a problem because the page that i'd like to print is added dynamically using javascript. is there any way to work around this? thanks a bunch in advance.


ban
May 17, 2011 at 3:08 PM // reply »
1 Comments

How do we remove the url link at top right corner from the print page...... any idea
or code snippet or is it possible at all....

btw cool plugin...pretty handy.


May 30, 2011 at 4:22 AM // reply »
1 Comments

Thank you very much for this tutorial..
:)


Jul 15, 2011 at 12:24 PM // reply »
1 Comments

Very useful plugin!

I've seen here someone had problems with printing forms.

The problem is that the plugin prints the default values of the input fields not the values at the moment of printing.

A solution to this could be storing the default values in a array, replace the default values with the current values and then write the data using that object. After the data has been written and printed we will replace back the default values with the values stored in that array.

This code could go inside the print function:

  • var arr=[];
  • $(":input").not(":button, :submit, :reset, :hidden").each( function(index) {
  • arr[index]=this.defaultValue;
  • this.defaultValue = this.value;
  • });
  •  
  • --- code for write the object and print the element ---
  •  
  •  
  • $(":input").not(":button, :submit, :reset, :hidden").each( function(index) {
  • this.defaultValue=arr[index];
  •  
  • });


Jul 17, 2011 at 3:31 PM // reply »
1 Comments

Just want to say thank you for sharing this simple but effective piece :)


Jul 26, 2011 at 1:55 PM // reply »
8 Comments

Ben, once again, you've saved my bacon! Thanks! :)


Aug 12, 2011 at 1:03 PM // reply »
1 Comments

does this work inside a window.open function in javascript??? because i tried it in it and it doesn't print


Aug 22, 2011 at 6:42 PM // reply »
1 Comments

Ben, this is the first plugin I've found that prints the entire contents of a jquery dialog!
This is the only code I needed:
dialogButtons.Print = function(){
$( ".registration-terms-container" ).print();
return( false );
};

Thanks!


Sep 14, 2011 at 11:45 AM // reply »
1 Comments

Hi Ben,
I have tried using your JQuery print plugin in order to print only a div content list on my page.
Added a printable style sheet to your code because it was missing.
It works well in IE6 an Firefox in winXP but not in IE8 under Win7. IE8 prints the actual page instead of just the "printable" class content. As if it ignores the newly created printable iframe and only prints what is on the actual page. No errors just prints the page instead of the designated printable content.
I haven't tested it in IE7 but it is possible that will share the same issue.
Is there any idea or solution which would make this print plugin code work in IE8 and/or IE7? Ideally this print functionality would need to work in every major browser.
Thanks, Attila


Sep 23, 2011 at 2:43 PM // reply »
5 Comments

We have some restrictions on implementing new plug-ins on our corporate website, so I came up with a different approach - hide the body and only show the content to print, print, then show all content again. attach this to the print button:

function printdiv(){
bodyHtml=$('body').html();
printHtml=$('#report_content').html();
$('body').html(printHtml);
window.print();
$('body').html(bodyHtml);
}

(div "report-content" is the div we want to print).


Nov 1, 2011 at 12:53 PM // reply »
2 Comments

Hi guys,

I was very interested in the potential of the jqPrint plug-in library that Todd shared, however, my current work environment limits us to the Prototype JS framework. Has anybody come across a similar library to jqPrint but utilizing Prototype instead.

Thanks!

Rick


Dec 5, 2011 at 1:03 PM // reply »
1 Comments

simple and effective plugin thanks so much.

One thing though... The area I am printing is a deposit form that has very specific formatting requirements. How can set the <hr> tag and the "print" link not to print?


Zeh
Dec 8, 2011 at 9:05 AM // reply »
1 Comments

Hi Ben!

First of all, congratulations Dude! U rule!

Just one question Ben, is that possible to set up the edges of the page using JS? I'm trying to use @page by Css, but it seems that just on browsers that support webkit.

Any ideas?

Tks!


Dec 26, 2011 at 3:26 PM // reply »
1 Comments

I was experiencing what @Charles and @Nebras were complaining about, namely, the "Uncaught TypeError: Property '$' of object [object DOMWindow] is not a function" error, when I realized that I needed to wrap the jQuery script accordingly, as per http://docs.jquery.com/Using_jQuery_with_Other_Libraries For example, changing:

  • jQuery.fn.print = function(){

to

  • (function($) {
  • $.fn.print = function(){

and closing with

  • };
  • })(jQuery);

and now the script works great. Thanks!


Jan 30, 2012 at 2:32 AM // reply »
1 Comments

You saved my arse.

Thank you!!!


Feb 22, 2012 at 6:00 AM // reply »
4 Comments

Hey Ben,

First of all, great code there!
However, I had a some issue with your code in IE7, since it kept printing the parent document instead of iframe. the cause of it was that the content of iframe were not loaded at the print command was executed, which made IE think iframe is empty and that it should switch to printing the parent document. This is the change I did to make it work, and it works now for IE7

instead of

objFrame.focus();
objFrame.print();

i used

jQuery("[name="+strFrameName+"]").load(
function() {
window.frames[strFrameName].focus();
window.frames[strFrameName].print();
}
);


Mar 22, 2012 at 7:05 AM // reply »
1 Comments

Aleks,

COuld you please share your complete code, I am a beginner and was having hard time implementing Ben's code.


Mar 22, 2012 at 8:16 AM // reply »
4 Comments

@Snagy, I copied the code from the post, and added the repalced part of the code.
http://jsfiddle.net/NgnA9/2/
Hope this link is visible.


Mar 22, 2012 at 8:21 AM // reply »
4 Comments

@Snagy, or this version:
https://sites.google.com/site/renestocodeplayground/files


Apr 13, 2012 at 8:22 AM // reply »
4 Comments

Hi guys,

I have got my printable section printing out now, but my external style sheets are being completely ignored.

When I click print, and look at the iframe in Firebug, the css files are being brought in correctly, but the styles themselves are not being applied to any of the classes in the body of the iframe, so I get a completely downscale print out with no imagery (alot of the images are coming from background: styles)

Has anybody had this problem before? Any ideas?

Thanks!


Apr 13, 2012 at 8:40 AM // reply »
4 Comments

@Chris, this inheritance of the styling used within this text didnt really worked some wonders for me, so I used specific css just for this case, called, *-printer-friendly.css
Take care to write them in the that new iframe generated for printing, and not the printable div, as they are not the same things.


Apr 13, 2012 at 9:05 AM // reply »
4 Comments

@Aleks - Thanks for your response. Are you actually including an external style sheet, or are you writing your styles within the page that you are printing?

I am using Martin Madler's suggestion of importing the css using something like this in the jQuery print plugin:

objDoc.write( "<link rel=\"stylesheet\" href=\"/css/print.css\" type=\"text/css\" media=\"print\" />" );

As I say, it is locating the style sheet - I can see the file upon inspection, however none of the classes in the iFrame have got the styles from the style sheet.

For example, my print.css has the following:

  • .red {color:#e30707}

However <div class="red">Hello</div> is coming out black as though it has no style assigned to it.


Jun 21, 2012 at 2:56 AM // reply »
1 Comments

Hi Mr Ben
hope to be fine and doing will
....
i am working as database developer in php codIgniter frame work...and i have a little problem if you could help me..
1.when i am inserting data into database i want to preview the element or current page using pop up window or taking the content page as picture and then show as print preview is it possible

thank in advance

kindest regard

Nimatullah


Aug 30, 2012 at 9:54 AM // reply »
2 Comments

Hey Ben. The function seems to work just fine printing normal data.
but if i try to use in on a cfchart flash format then IE 8 chokes and throws an error i am unable to catch.

any ideas what i should look at?


Aug 30, 2012 at 11:33 AM // reply »
2 Comments

nm...
Just had to write out a jpg copy of the flash and call that back to the print area.
thank you!


Aug 30, 2012 at 4:07 PM // reply »
1 Comments

Super cool. I tried a plugin and had trouble, but your stuff works like a charm. Thanks for taking the time to help others.


Sep 13, 2012 at 5:22 PM // reply »
1 Comments

First of all, great work. Your plugin worked almost perfectly for me. I had to make a few changes. One was already noted here, which is to move the order in which to "write" the body and head opening tags. The other was to not call focus and print until the document finishes loading.

So, I changed this line:

objDoc.write("<body>");

to this:

objDoc.write("<body onload='this.focus();this.print();'>");

and commented out these two lines:

objFrame.focus();
objFrame.print();

The original code did not work in IE9 but this does. I also verified that it works in Firefox 15.0.1, IE 9.0.8112.16421, Chrome 21.0.1180.89, and Safari 5.1.5 (Windows)


Jim
Nov 29, 2012 at 4:28 PM // reply »
1 Comments

Whenever my code hits this line it just freezes

objDoc.write( this.html() );

Never able to step to the next line..


Nov 29, 2012 at 7:08 PM // reply »
2 Comments

that all i need ! thanks


Bob
Feb 3, 2013 at 7:27 AM // reply »
2 Comments

Thank you very much. Works great!


Bob
Feb 3, 2013 at 4:05 PM // reply »
2 Comments

One more comment. I had the same problem as Douglas above, namely that IE was printing the font-size in half and so I implemented his solution and it now prints the same size font in both Firefox and IE. Safari too. I reprint his code here:

objFrame.focus();
try {
var exec = objDoc.execCommand('print',false,null);
}
catch(err)
{
//catch nothing
}
if(exec!=true)
{
objFrame.print();
}


Mar 18, 2013 at 3:57 AM // reply »
1 Comments

Thanks Ben, good resource for my html printing.

Just one issue I am having is background color cannot populate correctly.

For example, I got the class for lend for my td as following, The background color cannot printed out.

Anyone could help or facing same issue? Thanks.

  • <style type="text/css">
  • .legend {
  • background-color: #F0400A;
  • color: white;
  • text-align: center;
  • width: 5%;
  • }
  • </style>


May 3, 2013 at 5:07 PM // reply »
2 Comments

Hello Ben, Thanks for the printer plugin to print only the content area needed from a page.
I've thinking this for quite sometime now, it is possible for you to you make a tutorial on how to attach another plugin here to create a pdf file from the print view? Here are some librarias that can be usefull: (http://www.ajaxline.com/10-best-libraries-for-generating-pdf) but not quite sure which one to choose from and would fit best for attaching only the print preview content and generate a pdf file from a buttom, since i'm not a quite a good programmera as well.
Hope you can help, that would be awesome, and a real usefull plugin too! :)

Thanks.


May 15, 2013 at 11:36 AM // reply »
2 Comments

I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again):

On jquery.print.js
After:

  • // Print the document.
  • objFrame.focus();
  • objFrame.print();

Add:

  • parent.location.reload(true); // Refresh parent page (otherwise it'll contain only the print section)



Post A Comment

Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 19, 2013 at 2:31 PM
My Experience With AngularJS - The Super-heroic JavaScript MVW Framework
It's funny really just how well that image describes the way I would imagine most people that go with angular for some project is. I have had a similar roller-coaster ride with it as well, but not qu ... read »
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools