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
    Camera and Video Control with HTML5

    Client-side APIs on mobile and desktop devices are quickly providing the same APIs.  Of course our mobile devices got access to some of these APIs first, but those APIs are slowly making their way to the desktop.  One of those APIs is the getUserMedia API...

  • By
    How to Create a RetroPie on Raspberry Pi &#8211; Graphical Guide

    Today we get to play amazing games on our super powered game consoles, PCs, VR headsets, and even mobile devices.  While I enjoy playing new games these days, I do long for the retro gaming systems I had when I was a kid: the original Nintendo...

Incredible Demos

  • By
    MooTools Accordion: Mouseover Style

    Everyone loves the MooTools Accordion plugin but I get a lot of requests from readers asking me how to make each accordion item open when the user hovers over the item instead of making the user click. You have two options: hack the original plugin...

  • By
    CSS Vertical Center with Flexbox

    I'm 31 years old and feel like I've been in the web development game for centuries.  We knew forever that layouts in CSS were a nightmare and we all considered flexbox our savior.  Whether it turns out that way remains to be seen but flexbox does easily...

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!