YUI Simple LightBox using SimpleDialog

There does not seem to be many options for lightbox functionality when it comes to YUI. I’ve come across two so far and they both are great but they are also a bit heavier than I wanted. I really enjoy working with YUI, especially as my understanding of the framework grows. I wanted a lightbox that had a small footprint, was easy to maintain and is as unabtrusive as possible. The YUI container family of components makes it quite easy to build your own lightbox by extending them as needed. I chose the SimpleDialog container for the foundation of my Simple Lightbox.

SimpleDialog extends Dialog and behaves like an operating system dialog (modal or non-modal). The look and feel of a SimpleDialog instance is similar to that of a Panel, but with SimpleDialog the user responds to a question with a single answer - OK/Cancel, Yes/No, and so on. Event handlers are attached to the buttons in a SimpleDialog instance to enable your script to respond to whatever choice the user has made.

To be as unobtrusive as possible I decided to use the Bubbling library, created by Caridy Patino.

Javascript Bubbling Library is a set of plugins, behaviors and widgets, for building event-driven web applications using the bubble-up technique. The Bubbling Library also includes several plugins that can be used to extend the YUI Library to manage dynamic areas which are closely related with the event-driven philosophy. All components in the Bubbling Library have been released as open source under a BSD license and are free for all uses.

The Simple Lightbox code is under 4K uncompressed and less than 2.5K compressed. There are some basic requirements, HTML code wise, to allow thumbnail images to be gathered and displayed on a page. They very basic though and should be easy enough to implement on your own pages. In order for Simple Lightbox to use display your thumbnails you will need to have them wrapped with A tags with HREF attribute values linking to the larger image. These links also need to have a class value of “slbLink” so that they can be identified by the Bubbling library. Visitors without Javascript support will still be able to view the larger images so this degrades rather nicely. If the thumbnail image has an ALT attribute it will be used as the header for the large image display.

<a href=”/path/to/larger/image.jpg” class=”slbLink”>
<img src=”/path/to/smaller/image.jpg” alt=”the big picture” />
</a>

Here is a small demonstration:

At The Lights by %3Ca href=%22http://flickr.com/photos/petecarr/475437514/%22%3Epetecarr%3C/a%3E City Hall Building by %3Ca href=%22http://flickr.com/photos/hleung/490031147/%22%3Ehkmpua%3C/a%3E Drowning Off Of Thoughts by %3Ca href=%22http://flickr.com/photos/tjetjep/2536735879/%22%3ETeeJe%3C/a%3E Her World by %3Ca href=%22http://flickr.com/photos/zachstern/744774862/%22%3Ezachstern%3C/a%3E Sunset At The Beach by %3Ca href=%22http://flickr.com/photos/hotair2112/156351908/%22%3Ems4jah%3C/a%3E The Edge Of The Storm by %3Ca href=%22http://flickr.com/photos/slack12/1087014722/%22%3Eslack12%3C/a%3E The Sun Sets On Chateau de Chillon by %3Ca href=%22http://flickr.com/photos/pearbiter/566128230/%22%3Epear biter%3C/a%3E Weekend Inspiration by %3Ca href=%22http://www.flickr.com/photos/muha/1061897539/%22%3Emuha%3C/a%3E

And here is the code:

<script type="text/javascript">
/*
Copyright (c) 2009, Dave Lozier
Code licensed under the BSD License:
http://davelozier.com/bsd/license.txt
version: 1.0
*/
YAHOO.namespace("simpleLightbox");
var myLightbox = function () {
	var Event = YAHOO.util.Event, Dom = YAHOO.util.Dom, currentThumb, slbActive = false, slbDisplay;
	var slblinks = Dom.getElementsByClassName('slbLink', 'a');

	var fadeIn = function() {
		var ani = new YAHOO.util.Anim(slbDisplay , { opacity: {from: 0, to: 1 } }, .5, YAHOO.util.Easing.easeOut);
		ani.animate();
	}

	var showImage = function (obj,header) {
		var vpw = Dom.getViewportWidth() - 50;
		var vph = Dom.getViewportHeight() - 100;
		if (obj.width > vpw || obj.height > vph){
			var objRatio = obj.width / obj.height;
			var vpRatio = vpw / vph;
			if (objRatio <= vpRatio) {
				obj.height = vph;
				obj.width = obj.width * (vph / obj.height);
			} else {
				obj.width = vpw;
				obj.height = obj.height * (vpw / obj.width);
			}
		}
		YAHOO.simpleLightbox.photoViewer.cfg.setProperty('width', (obj.width + 20)  + 'px');
		YAHOO.simpleLightbox.photoViewer.setHeader(unescape(header));
		Dom.setStyle(slbDisplay,'width', obj.width+'px');
		Dom.setStyle(slbDisplay,'height', obj.height+'px');
		Dom.setStyle(slbDisplay,'background', 'url('+obj.src+') no-repeat');
		YAHOO.simpleLightbox.photoViewer.center();
		if (slbActive == false) {
			slbActive = true;
			YAHOO.util.Dom.setStyle(slbDisplay, 'opacity', '1');
			YAHOO.simpleLightbox.photoViewer.show();
		} else {
			fadeIn();
		}
	}

	var fadeOut = function(obj,header) {
		if (slbActive == true) {
			var ani = new YAHOO.util.Anim(slbDisplay , { opacity: {from: 1, to: 0 } }, .5, YAHOO.util.Easing.easeOut);
			ani.animate();
			ani.onComplete.subscribe(function(){showImage(obj,header)});
		} else {
			showImage(obj,header);
		}
	}

	var loadImage = function(el) {
		if (el.src && el.src != '') {
			currentThumb = el.src;
			var imageSrc = el.parentNode.href;
			var header = (el.alt != null) ? el.alt : '';
			var objImage = new Image();
			Event.on(objImage, 'load', function(){fadeOut(objImage,header);});
			objImage.src = imageSrc;
		}
	}

	var prevThumb = function() {
		for (i=0; i<slblinks.length; i++) {
			if (slblinks[i].firstChild.src == currentThumb) {
				if (i == 0) {
					i = slblinks.length-1;
				} else {
					i = i - 1;
				}
				loadImage(slblinks[i].firstChild);
				break;
			}
		}
	}

	var nextThumb = function() {
		for (i=0; i<slblinks.length; i++) {
			if (slblinks[i].firstChild.src == currentThumb) {
				if (i == slblinks.length-1) {
					i = 0;
				} else {
					i = i + 1;
				}
				loadImage(slblinks[i].firstChild);
				break;
			}
		}
	}

	var hideMe = function() {
		slbActive = false;
		this.hide();
	}

	YAHOO.simpleLightbox.photoViewer = new YAHOO.widget.SimpleDialog("photoViewer",{
		width: "300px",
		fixedcenter: true,
		visible: false,
		draggable: false,
		close: false,
		modal: true,
		text: '<div id="slbDisplay"></div>',
		constraintoviewport: true,
		effect: [ {effect:YAHOO.widget.ContainerEffect.FADE,duration:0.5} ],
		buttons: [ { text:"Prev", handler:prevThumb },{ text:"Next", handler:nextThumb },{ text:"Close", handler:hideMe, isDefault:true } ]
	});

	YAHOO.simpleLightbox.photoViewer.setHeader('Simple Lightbox');
	YAHOO.simpleLightbox.photoViewer.render("container");
	slbDisplay = Dom.get('slbDisplay');

	YAHOO.Bubbling.addDefaultAction('slbLink',
		function (layer, args) {
			loadImage(args[1].target);
			return true;
		}
	);
}
YAHOO.util.Event.addListener(window, "load", myLightbox);
</script>

View this demo on a new page or download the demo and use on your own pages. Enjoy!

Posted by Dave on July 14, 2009 in YUI

Write a Comment on YUI Simple LightBox using SimpleDialog

Subscribe

Follow comments by subscribing to the YUI Simple LightBox using SimpleDialog Comments RSS feed.

More

Read more posts by Dave

PHP 5.3 Released!