MooTools & Printing – Creating a Links Table of Contents

By  on  

One detail we sometimes forget when considering print for websites is that the user cannot see the URLs of links when the page prints. While showing link URLs isn't always important, some websites could greatly benefit from doing so. This tutorial will show you how to create a dynamic link table of contents using MooTools and basic CSS.

The XHTML

<div id="print-content-area">
	<p class="large">MooTools is a <em>compact</em>, <em>modular</em>, <em>Object-Oriented</em> JavaScript framework designed for the intermediate to advanced JavaScript developer. It allows you to write <em>powerful</em>, <em>flexible</em>, and <em>cross-browser</em> code with its elegant, well documented, and <em>coherent API</em>.</p>
	<p class="quiet">MooTools code respects strict standards and doesn't throw any warnings. It's extensively documented and has meaningful variable names: a joy to browse and a snap to understand.</p>
	<div class="block span-8 colborder">
		<h3 class="red"><span>Open Source License</span></h3>
		<p>MooTools is released under the Open Source <a href="http://www.opensource.org/licenses/mit-license.php">MIT license</a>, which gives you the possibility to use it and modify it in every circumstance. </p>
	</div>
	<div class="block span-8 last">
		<h3 class="green"><span>Browser Compatibility</span></h3>
		<p>MooTools is compatible and fully tested with <a href="http://apple.com/safari/">Safari 2+</a>, Internet Explorer 6+, <a href="http://mozilla.com/">Firefox 2+</a> (and browsers based on gecko), <a href="http://opera.com/">Opera 9+</a>.</p>
	</div>
	<div id="thebook" class="block span-8 colborder">
		<h3 class="blue">The MooTools Book</h3>
		<p>Pick up a copy of <a href="http://www.amazon.com/MooTools-Essentials-JavaScript-Development-Firstpress/dp/1430209836">MooTools Essentials</a> from <a href="http://clientside.cnet.com">Aaron Newton</a>, published by <a href="http://apress.com">Apress</a></p>
	</div>
	<div id="links" class="block span-8 last">
		<h3 class="purple"><span>Some applications using MooTools</span></h3>
		<p>
			<a href="http://www.macheist.com/" class="macheist">macheist</a>
			<a href="http://validator.w3.org/" class="w3c">w3c</a>
			<a href="http://cnet.com/" class="cnet">cnet</a>
			<a href="http://joomla.org/" class="joomla">joomla</a>
			<a href="http://quizlet.com/" class="quizlet">quizlet</a>
			<a href="http://vimeo.com/" class="vimeo">vimeo</a>
			<a href="http://powerset.com" class="powerset">powerset</a>
			<a href="http://ubuntu.com/" class="ubuntu">ubuntu</a>
			<a href="http://gamespot.com/" class="gamespot">gamespot</a>
			<a href="http://tv.com/" class="tvdotcom">tv.com</a>
			<a href="http://www.chrysler.com" class="chrysler">chrysler</a>
			<a href="http://www.jeep.com" class="jeep">jeep</a>
			<a href="http://parisenvies.com/" class="parisenvies">paris envies</a>
			<a href="http://netvibes.com/" class="netvibes">netvibes</a>
		</p>
	</div>
</div>

Obviously we don't need to record the links within the navigation menu, header, footer, etc. because they don't have print value (and should be hidden in your stylesheet anyway). I've wrapped the valuable content with a DIV to help us identify that it's important. The sample content has been duplicated from the MooTools homepage.

The CSS

@media all {
	.print-only { display:none; }
}
@media print {
	span.print-only { display:inline; font-size:10px; padding-left:5px; }
	.toc-list	{ page-break-before:always; display:block; padding-left:35px; font-size:10px; }
}

There's very little CSS needed. Obviously the print-only class hides elements we inject so that the user cannot see them on their screen. Be sure to style the toc-list however you'd like.

The MooTools JavaScript

/* when the dom is ready */
window.addEvent('domready',function() {
	/* get the links */
	var links = $$('#print-content-area a');
	/* if there are any */
	if(links.length) {
		/* create toc list */
		var container = new Element('ol',{
			'class': 'print-only toc-list'
		}).inject(document.body,'bottom');
		/* add a heading for the TOC */
		var header = new Element('h2',{
				text: 'Links In This Document'
		}).inject(container,'top');
		/* get links inside the content area */
		links.each(function(a,i) {
			if(a.get('href')){
				/* insert the span reference right after the link */
				new Element('span',{
					text: '[' + (i + 1) + ']',
					'class': 'print-only'
				}).inject(a,'after');
				/* record anchor, put in list */
				new Element('li',{
					text: a.get('href')
				}).inject(container,'bottom');
			}
		});
	}
});

We dynamically tack on another DIV which will be placed on a separate printed page. We add a heading, create a list, and inject all of the links into that list.

You can achieve a similar effect using pure CSS but it wont work in Internet Explorer 6 while the above will. Happy mooing!

Recent Features

  • By
    I&#8217;m an Impostor

    This is the hardest thing I've ever had to write, much less admit to myself.  I've written resignation letters from jobs I've loved, I've ended relationships, I've failed at a host of tasks, and let myself down in my life.  All of those feelings were very...

  • By
    Vibration API

    Many of the new APIs provided to us by browser vendors are more targeted toward the mobile user than the desktop user.  One of those simple APIs the Vibration API.  The Vibration API allows developers to direct the device, using JavaScript, to vibrate in...

Incredible Demos

  • By
    Sexy Album Art with MooTools or jQuery

    The way that album information displays is usually insanely boring. Music is supposed to be fun and moving, right? Luckily MooTools and jQuery allow us to communicate that creativity on the web. The XHTML A few structure DIVs and the album information. The CSS The CSS...

  • By
    Google-Style Element Fading Using MooTools or jQuery

    Google recently introduced an interesting effect to their homepage: the top left and top right navigation items don't display until you move your mouse or leave the search term box. Why? I can only speculate that they want their homepage as...

Discussion

  1. Simple but highly useful! I love it! Oh wait…I wrote it. David Walsh and MooTools FTW!

  2. deef

    Nice feature!

    David, your Sugar & Style Ajax loader is driving me bananas… I keep waiting for it to load.

  3. Isn’t it faster to create the link list via php? Just select the links with a preg_match_all and insert it at the bottom of the page… I’ll make a quick example soon!

  4. Sara

    This is great, except that the part of the page I want to show links from also includes some named anchors for internal page navigation. These show up as blanks in the list of links, since they lack the href attribute. Is there someway to prevent the inclusion of these named anchors in the list of links?

  5. Sara

    I came up with my own solution:

    /* when the dom is ready */
    window.addEvent('domready',function() {
    	/* get the links */
    	var links = $$('#print-content-area a');
    	
    	/* remove from the array named anchors lacking an "href" property */
    	function notNull(a) {
    		return(a.get('href') != undefined);
    	}
    	var filteredLinks = links.filter(notNull);
    
    	/* if there are any */
    	if(filteredLinks.length) {
    		/* create toc list */
    		var container = new Element('ol',{
    			'class': 'print-only toc-list'
    		}).inject(document.body,'bottom');
    		/* add a heading for the TOC */
    		var header = new Element('h2',{
    				text: 'Links In This Document'
    		}).inject(container,'top');
    		/* get links inside the content area */
    		filteredLinks.each(function(a,i) {
    			/* insert the span reference right after the link */
    			/*if(a.get('href') != undefined){*/
    				new Element('span',{
    					text: '[' + (i + 1) + ']',
    					'class': 'print-only'
    				}).inject(a,'after');
    				/* record anchor, put in list */
    				new Element('li',{
    					text: a.get('href')
    				}).inject(container,'bottom');
    			/*}*/
    		});
    	}
    });
    

Wrap your code in <pre class="{language}"></pre> tags, link to a GitHub gist, JSFiddle fiddle, or CodePen pen to embed!