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
    Introducing MooTools Templated

    One major problem with creating UI components with the MooTools JavaScript framework is that there isn't a great way of allowing customization of template and ease of node creation. As of today, there are two ways of creating: new Element Madness The first way to create UI-driven...

  • By
    5 HTML5 APIs You Didn&#8217;t Know Existed

    When you say or read "HTML5", you half expect exotic dancers and unicorns to walk into the room to the tune of "I'm Sexy and I Know It."  Can you blame us though?  We watched the fundamental APIs stagnate for so long that a basic feature...

Incredible Demos

  • By
    Editable Content Using MooTools 1.2, PHP, and MySQL

    Everybody and their aerobics instructor wants to be able to edit their own website these days. And why wouldn't they? I mean, they have a $500 budget, no HTML/CSS experience, and extraordinary expectations. Enough ranting though. Having a website that allows for...

  • By
    MooTools Wall Plugin

    One of the more impressive MooTools plugins to hit the Forge recently was The Wall by Marco Dell'Anna.  The Wall creates an endless grid of elements which can be grabbed and dragged, fading in elements as they are encountered.  Let me show...

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!