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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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 »
10,743 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.



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
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
May 16, 2012 at 8:18 PM
Best Of ColdFusion 10 Contest Entry - HTML Email Utility
Just found this, looks good! I'm trying to run it on local, it's the 64bit version and I'm experiencing horrible lag. On average the generate.cfm processes the content change in 60-90 seconds. I've ... read »
May 16, 2012 at 6:40 PM
Maintaining Sessions Across Multiple ColdFusion CFHttp Requests
I am trying to integrate this CFHTTPsession into an application that will log into zeekrewards.com to post ads and I am not having any luck. The code works perfectly for logging into other websites, ... read »
May 16, 2012 at 2:44 PM
Creating A Sometimes-Fixed-Position Element With jQuery
Thank you, very useful technique! Worked like a charm. ... read »
May 16, 2012 at 1:58 PM
Movies As A Religious Experience
Acting can, in a way, ruin the movie-goer's experience. I used to be able to get so caught up in movies and their plots, and totally engaged. But lately, I haven't been able to as much with a lot o ... read »
May 16, 2012 at 1:52 PM
The Science Of Optimal Post-Exercise Nutrition
children of this age eat very less vegetables so u can opt for salads they will like it also carrot ,cucumber,onion and as far as pulses are concerned u can boil them ,give him along with mashed rice ... read »
May 16, 2012 at 1:34 PM
Strange ColdFusion JRUN Stack Overflow Error
Hey, Recently I updated my jrun4 using the latest updater 7 and now i am having memory issues :(:(:( any help is appreciated ... read »
May 16, 2012 at 9:56 AM
ColdFusion 10 Beta, Apache Tomcat, And Symbolic Links On Mac OSX
Hi, Now that ColdFusion 10 is out I have stumbled over this as well and I cannot figure out the proper solution. We're running virtual hosts via Apache2; the ColdFusion-applications store their fil ... read »
May 15, 2012 at 6:03 PM
Movies As A Religious Experience
@Ben, I don't know whether you'd consider this a religious observation, but it seems to me, in a sense, movies multiply how many lives we get to have. Each movie is like a little extra life we get ... read »