Video icon 64
Learning to code? Skill up faster with our practical video courses. Start your free trial today.
Advertisement

Learn How to Style Articles for Print and Email

by

When designing websites, a commonly desired feature is the ability to dynamically print or email any section of a webpage. Unfortunately, this idea is usually scrapped later in the project due to a lack of time or knowledge. Formatting the text for printing is more difficult than it might initially seem. Today, we will use JavaScript to automatically search for certain page elements and format them correctly for a printing.

Objectives:

At the end of this tutorial, we will have accomplished the following:

  • Use jQuery to print or email any section of a page automatically when a certain element is clicked.
  • Format and change the style to optimize for print or email.
  • Add variables to the email version (To, From, Message, etc.)

The Page

Page

What's Wrong With This?

Wow...that page is colorful. I agree - it's not the greatest color scheme in the world. This design was definitely not designed for print. Although the background blue will not print out on most printers, the printer will just make it disappear. This will mess up the rest of the design though because now the bright orange and green text will print on a white background. There is no easy way for a user to print out a nice black and white formatted article from this page, short of copying it into a word processor and formatting it themselves.

Keep The Design, Fix The Problem

One solution might be to provide a print stylesheet, as Tuts+ has done. This would work if there was only one article on a page. Unfortunately, this example is in blog format. This means that there are several articles on a page; and chances are the user only wants to print out one article. We are going to use jQuery to allow the user to click a link after each article that formats the article and allows them to print or email it.

Print Email Buttons

HTML for This Page

The HTML is rather simple for this page. We'll add a couple of standard classes: One to signify a section to be printed/emailed (.printSection), one to signify the area that contains the links to print or email (.printControls), a class for all print links (.printControl), and a class for all email links (.emailControl). Notice how we also linked to Google's minified file. This allows us to use jQuery later.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Print | Email jQuery Plugin</title>
<script type="text/javascript" src="http://jqueryjs.googlecode.com/files/jquery-1.3.2.min.js">
</script>
</head>

<body>
<div class="page-wrap">
	<div class="printSection">
    	<a name="1"></a>
    	<h2>This is a Heading</h2><br />
        <img src="image.jpg" />
        <p>Article Text</p>
        <span class="printControls"><p class="printControl">Print Section</p> | 
		  <p class="emailControl">Email Section</p></span>
    </div><!-- End printSection -->
	<div class="printSection">
        <a name="2"></a>
    	<h2>This is a Different Heading</h2><p>Article Text</p>
        <p>More Article Text</p>

		  <span class="printControls"><p class="printControl">Print Section</p> | 
		<p class="emailControl">Email Section</p></span>
    </div><!-- End printSection -->
	<div class="printSection">
    	<a name="3"></a>
    	<h2>This is Another Heading</h2><p>Article Text</p>
        <p>More Article Text</p>

		<span class="printControls"><p class="printControl">Print Section</p> | 
		<p class="emailControl">Email Section</p></span>
    </div><!-- End printSection -->
	<div class="printSection">
    	<a name="4"></a>
    	<h2>This is a Heading Again</h2><p>Article Text</p>
        <p>More Article Text</p>

		<span class="printControls"><p class="printControl">Print Section</p> | 
<p class="emailControl">Email Section</p></span>
    </div><!-- End printSection -->
</div><!-- End Page Wrap -->
</body>
</html>
 

The CSS

The CSS is pretty simple too.

body{
text-align: center;
font-family: Tahoma, Arial, Helvetica, Sans Serif;
}
h2{
color: #d98841;
font-size: 48px;
padding: 0px;
margin: 0px;
font-weight: normal;
}

.page-wrap{
margin-left: auto;
margin-right: auto;
width: 550px;
background: #10222b;
padding: 15px;
text-align: left;
}
.printSection p{
color: #bdd684;
font-size: 12px;
text-align: justify;
}
p.printControl, p.emailControl, .printControls{
display: inline;
color: #f2ece4;
}
p.printControl, p.emailControl{
cursor: pointer;
}
img{
margin-left: 35px;
}

We'll also add a bit of CSS to increase usability. In case Javascript is disabled, we don't want dead links - so we hide the links:

<noscript>
<style>
.printControls{
display: none;
}
</style>
</noscript>

Script Time

What do we want to accomplish when printing?

  • add a listener to wait for a .printControl or .emailControl to be clicked.
  • change the appearance of the section to be printer friendly
  • grab the parts of the page that we want to print
  • open up a window and size it.
  • put the parts of the page that we grabbed into the window
  • open up the print dialogue box
  • close the window after done printing

How we are going to accomplish these things?

Add the Listener:

We put the print listener inside the DOM reading function:

$(document).ready(function(){
	$('.printControl').click(function(){
		//Here we will put the printing code
    });
});

Change the Appearance

We need to change the colors from the colorful scheme, to black and white. There are several ways we can accomplish this task. The method we'll use is to add a class temporarily to the affected section, take the code to print, and then immediately remove the class again. We add the class by using jQuery's CSS selector to select the divs, and then add a class to all elements inside with the children() command.

$(document).ready(function(){
	$('.printControl').click(function(){
		$('.printSection').children().addClass('printversion');		
		$('.printSection').children().removeClass('printversion');	
    });
});

We also must add some more styling for the elements with printversion:

h2.printversion, p.printversion{
color: #333333;
text-align: left;
}
.printControls.printversion{
display: none;
}

Grabbing the Section

We are now going to grab the section and put it in a variable. We are going to put this after we add the class but before we remove it, so that the version in the variable is with the added class. We grab the HTML in the head to get the styling info and concatenate it with the section's HTML. The "this" allows us to only select the section that was clicked instead of all of them. Then we go up to levels from the print button and grab that.

$(document).ready(function(){
	$('.printControl').click(function(){
		$('.printSection').children().addClass('printversion');	
        var printContent= $('head').html() + $(this).parent().parent().html();	
		$('.printSection').children().removeClass('printversion');	
    });
});

Opening the Window

We now need to put the variable somewhere. But first, we need to open up a new window. These lines aren't very important and are just plain JavaScript - no jQuery in this step. Basically, we open up a window, assign a unique name, and give it some basic parameters.

$(document).ready(function(){
	$('.printControl').click(function(){
		$('.printSection').children().addClass('printversion');	
        var printContent= $('head').html() + $(this).parent().parent().html();	
		$('.printSection').children().removeClass('printversion');	
        var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'PrintSection' + uniqueName.getTime();
		 var printWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600,height=1000');
    });
});

Fill the Window

We now need to fill the window with what we grabbed earlier. We basically just write to the window the variable's value.

$(document).ready(function(){
	$('.printControl').click(function(){
		$('.printSection').children().addClass('printversion');	
        var printContent= $('head').html() + $(this).parent().parent().html();	
		$('.printSection').children().removeClass('printversion');	
        var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'PrintSection' + uniqueName.getTime();
		 var printWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600,height=1000');
         printWindow.document.write(printContent);
    });
});

Print and Close

We need to add a few more lines before we're finished. First, we need to focus the window and then open up the print dialogue box. Then we close the window after the dialogue box has been closed.

$(document).ready(function(){
	$('.printControl').click(function(){
		$('.printSection').children().addClass('printversion');	
        var printContent= $('head').html() + $(this).parent().parent().html();	
		$('.printSection').children().removeClass('printversion');	
        var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'PrintSection' + uniqueName.getTime();
		 var printWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600,height=1000');
         printWindow.document.write(printContent);
          printWindow.document.close();
		 printWindow.focus();
		 printWindow.print();
		 printWindow.close();
    });
});

That's it. We should now have a functional print button after every article. Good job, but we're not finished yet. Now we got to make the email button function correctly.

Print

What must we accomplish when emailing?

  • add a listener to wait for a .printControl or .emailControl to be clicked.
  • We need the email address they're sending it to.
  • We need their name.
  • We need their email.
  • We need a short message to be sent with.
  • put all of this info into variables through the use of prompts.
  • change the appearance of the section to be email friendly
  • We need the URL of the page, including an anchor tag to skip right to the article.
  • put all of this information into one variable.
  • put this into a new window.

Things we've already done when printing

There's no need to go over all of these steps again. We can skip the ones that we covered with printing:

$(document).ready(function(){
		$('.emailControl').click(function(){
		$('.printSection').children().addClass('printversion');	
		$('.printSection').children().removeClass('printversion');		
		var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'emailSection' + uniqueName.getTime();
		 var emailWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600');
		 emailWindow.document.write(printContent);
		 emailWindow.document.close();
		 emailWindow.focus();
	});
});

Getting the Information

For this example, we don't need anything fancy for retrieving the required information. We're just going to raise several prompts that store the information in variables.

$(document).ready(function(){
		$('.emailControl').click(function(){
        var sendTo = prompt('Please type who you would like to send this to');
		var fromWho = prompt('And What is Your Name?');
		var fromWhoEmail = prompt('And What is Your Email?');
		var fromMessage = prompt('Do You have a Message?');
		$('.printSection').children().addClass('printversion');	
		$('.printSection').children().removeClass('printversion');		
		var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'emailSection' + uniqueName.getTime();
		 var emailWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600');
		 emailWindow.document.write(printContent);
		 emailWindow.document.close();
		 emailWindow.focus();
	});
});
InfoInfoInfoInfoInfo

Getting the URL and Anchor Tag

Now, we need to store the current URL and article number (via the anchor tag) in variables. We will combine them later.

$(document).ready(function(){
		$('.emailControl').click(function(){
        var sendTo = prompt('Please type who you would like to send this to');
		var fromWho = prompt('And What is Your Name?');
		var fromWhoEmail = prompt('And What is Your Email?');
		var fromMessage = prompt('Do You have a Message?');
		$('.printSection').children().addClass('printversion');	
        var emailID=$(this).parent().parent().find('a').attr('name');
		var currentURL= window.location.href;
		$('.printSection').children().removeClass('printversion');		
		var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'emailSection' + uniqueName.getTime();
		 var emailWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600');
		 emailWindow.document.write(printContent);
		 emailWindow.document.close();
		 emailWindow.focus();
	});
});

Putting Everything Together

First we combine the URL together with the anchor tag and put it in a nice string of text. Then we combine that with everything else we need in a variable called emailContent.

$(document).ready(function(){
		$('.emailControl').click(function(){
        var sendTo = prompt('Please type who you would like to send this to');
		var fromWho = prompt('And What is Your Name?');
		var fromWhoEmail = prompt('And What is Your Email?');
		var fromMessage = prompt('Do You have a Message?');
		$('.printSection').children().addClass('printversion');	
        var emailID=$(this).parent().parent().find('a').attr('name');
		var currentURL= window.location.href;
        var emailLink='<p><b>Source:</b> <a href="' + currentURL + '#' + emailID + '">' + currentURL + '#' + emailID +'</a></p>';	
		var emailContent= $('head').html() + '<div style="text-align:left;"><p><b>To:</b>' + sendTo + '</p>' + '<p><b>From(Name):</b>' + fromWho + '</p>' + '<p><b>From(Email):</b>' + fromWhoEmail + '</p>' + '<p><b>Message:</b>' + fromMessage + '</p>' + emailLink + '</div>' + $(this).parent().parent().html();
		$('.printSection').children().removeClass('printversion');		
		var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'emailSection' + uniqueName.getTime();
		 var emailWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600');
		 emailWindow.document.write(printContent);
		 emailWindow.document.close();
		 emailWindow.focus();
	});
});

Finished Code

$(document).ready(function(){
	$('.printControl').click(function(){
		$('.printSection').children().addClass('printversion');		
		var printContent= $('head').html() + $(this).parent().parent().html();
		$('.printSection').children().removeClass('printversion');		
		var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'PrintSection' + uniqueName.getTime();
		 var printWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600,height=1000');
		 printWindow.document.write(printContent);
		 printWindow.document.close();
		 printWindow.focus();
		 printWindow.print();
		 printWindow.close();
	});
	$('.emailControl').click(function(){
		var sendTo = prompt('Please type who you would like to send this to');
		var fromWho = prompt('And What is Your Name?');
		var fromWhoEmail = prompt('And What is Your Email?');
		var fromMessage = prompt('Do You have a Message?');
		$('.printSection').children().addClass('printversion');	
		var emailID=$(this).parent().parent().find('a').attr('name');
		var currentURL= window.location.href;
		var emailLink='<p><b>Source:</b> <a href="' + currentURL + '#' + emailID + '">' + currentURL + '#' + emailID +'</a></p>';	
		var emailContent= $('head').html() + '<div style="text-align:left;"><p><b>To:</b>' + sendTo + '</p>' + '<p><b>From(Name):</b>' + fromWho + '</p>' + '<p><b>From(Email):</b>' + fromWhoEmail + '</p>' + '<p><b>Message:</b>' + fromMessage + '</p>' + emailLink + '</div>' + $(this).parent().parent().html();
		$('.printSection').children().removeClass('printversion');		
		var windowUrl = 'about:blank';
		 var uniqueName = new Date();
		 var windowName = 'emailSection' + uniqueName.getTime();
		 var emailWindow = window.open(windowUrl, windowName, 'left=500,top=000,width=600');
		 emailWindow.document.write(emailContent);
		 emailWindow.document.close();
		 emailWindow.focus();
	});
});

We're Done

We now have an automatic way to print and email sections of a web site that degrades when JavaScript is disabled. Good job! If you enjoyed this tutorial, stay tuned; in a future tutorial, we'll cover how to turn this into a jQuery plugin. Meanwhile, if you have any questions or comments, be sure to leave them below. I'd love to hear from you!

Advertisement