Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at TechCrunch Disrupt (New York, NY) with:

Ask Ben: Print Part Of A Web Page With jQuery

By Ben Nadel on

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.

Tweet This Deep thoughts by @BenNadel - Ask Ben: Print Part Of A Web Page With jQuery Thanks my man — you rock the party that rocks the body!

Looking For A New Job?

100% of job board revenue is donated to Kiva. Loans that change livesFind out more »

Reader 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 :)

Reply to this Comment

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.

Reply to this Comment

@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.

Reply to this Comment

@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.

Reply to this Comment

@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 :)

Reply to this Comment

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?

Reply to this Comment

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...

Reply to this Comment

@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.

Reply to this Comment

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

Reply to this Comment

@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.

Reply to this Comment

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

Reply to this Comment

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!!

Reply to this Comment

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 :-) :-) :-)

Reply to this Comment

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

Reply to this Comment

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)

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

@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!

Reply to this Comment

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

Reply to this Comment

@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.

Reply to this Comment

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

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

Reply to this Comment

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

Reply to this Comment

@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.

Reply to this Comment

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

Reply to this Comment

@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*/
}

Reply to this Comment

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.

Reply to this Comment

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

Reply to this Comment

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.

Reply to this Comment

@Martin, @Darren,

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

Reply to this Comment

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.

Reply to this Comment

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\" />" );

Reply to this Comment

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.

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

@Sandy,

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

@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.

Reply to this Comment

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 ?

Reply to this Comment

@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?

Reply to this Comment

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!

Reply to this Comment

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 :)

Reply to this Comment

@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.

Reply to this Comment

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.

Reply to this Comment

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

Reply to this Comment

@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 :)

Reply to this Comment

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

Reply to this Comment

@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.

Reply to this Comment

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

Reply to this Comment

@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.

Reply to this Comment

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.

Reply to this Comment

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

Reply to this Comment

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...

Reply to this Comment

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...

Reply to this Comment

@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.

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

@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.

Reply to this Comment

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.

Reply to this Comment

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.

Reply to this Comment

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. :)

Reply to this Comment

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". ????

Reply to this Comment

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.

Reply to this Comment

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.

Reply to this Comment

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];
  •  
  • });

Reply to this Comment

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

Reply to this Comment

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!

Reply to this Comment

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

Reply to this Comment

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).

Reply to this Comment

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

Reply to this Comment

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?

Reply to this Comment

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!

Reply to this Comment

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!

Reply to this Comment

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

Reply to this Comment

Aleks,

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

Reply to this Comment

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!

Reply to this Comment

@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.

Reply to this Comment

@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.

Reply to this Comment

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

Reply to this Comment

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?

Reply to this Comment

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

Reply to this Comment

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

Reply to this Comment

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)

Reply to this Comment

Whenever my code hits this line it just freezes

objDoc.write( this.html() );

Never able to step to the next line..

Reply to this Comment

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

Reply to this Comment

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>

Reply to this Comment

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.

Reply to this Comment

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)

Reply to this Comment

@angelo,

If i'm not wrong, that depends on the web browser configuration, does not apply to the plugin or jquery itself.

Reply to this Comment

I keep getting "SCRIPT438: Object doesn't support this property or method" error on this line of code "var jFrame = $( "<iframe name='" + strFrameName + "'>" );"

It works fine in Chrome but it gives this error in IE and does nothing. I tried to change the name to see if it was a conflict with the name in maybe another script but it still gave me that same error.

Reply to this Comment

Hi Ben,

There are so many comment, I could not go through all of them to make sure my tip hasn't been suggested yet, but the "issue" you have with the stylesheets can be solved easily.

I am using your plugin and changed it slightly. It now accepts

  • jQuery.fn.print = function (options)

and this goes into

  • var stylesheet = options.stylesheet;

Then I replaced the

  • objDoc.write( jStyleDiv.html() );

with <code>objDoc.write('<link href="' + stylesheet + '" rel="stylesheet" type="text/css" />');<code> and also removed the relevant code that is now redundant.

Now when you want to print, you simply send the stylesheet location to the pluging and Bob's your uncle.

This way it's more maintainable and easier to use. (Think of what happens when your styles are in your pages and you decide to change your website's style)

Kind regards
Eben

Reply to this Comment

Seems when I run this in IE (11 or 10) the browser locks up and nothing happens. I have to close the browser since nothing is happening. Seems that when I run this in Chrome it works fine so not sure what's the issue.

I am trying to print a div that is inside a hide() element.

Reply to this Comment

BAsed on the last Comment "Nov 29, 2013 at 12:30 PM" from Andy.

Whats the solution for IE 11 or 10. I am experiencing the same thing.

I have change this:

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

to

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

For your reply, Thanks.

Reply to this Comment

Nice job! I've been struggling with implementing a solution that is cross-browser compatible and your code does the trick. I made a few modifications as suggested by others and a couple small tweaks of my own and it works great. Thanks again for sharing and making a video. It was very helpful.

Reply to this Comment

@Angelo,
Struggling with the same thing. But seems like @Alex is right. Depends of the browsers settings.
@Angelo, did you find a workaround?
This is not relevant here. Ben, sorry :) Thanks a lot for your plugin. Works fine

Reply to this Comment

Actually I am developing an POS application for my own shop in web.

Now for that in billing section have features like select the products and print bill. only two steps.

but while click on print then its appearing print setup window.. which is very annoying.

think, if i am using that application in counter, customers are standing in a line. so i must to do the billing as fast as possible to make customer happy. now for this window takes time for each bill, and every time i am using same printer. so i don't think this is necessary for me.

and ultimately time === money.

so i need this technical help.. please help if you can

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
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.