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
    Create Namespaced Classes with MooTools

    MooTools has always gotten a bit of grief for not inherently using and standardizing namespaced-based JavaScript classes like the Dojo Toolkit does.  Many developers create their classes as globals which is generally frowned up.  I mostly disagree with that stance, but each to their own.  In any event...

  • By
    CSS 3D Folding Animation

    Google Plus provides loads of inspiration for front-end developers, especially when it comes to the CSS and JavaScript wonders they create. Last year I duplicated their incredible PhotoStack effect with both MooTools and pure CSS; this time I'm going to duplicate...

Incredible Demos

  • By
    Multiple Backgrounds with CSS

    Anyone that's been in the web development industry for 5+ years knows that there are certain features that we should have had several years ago. One of those features is the HTML5 placeholder; we used JavaScript shims for a decade before placeholder came...

  • By
    CSS Kwicks

    One of the effects that made me excited about client side and JavaScript was the Kwicks effect.  Take a list of items and react to them accordingly when hovered.  Simple, sweet.  The effect was originally created with JavaScript but come five years later, our...

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!