<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Google Closure Tutorials</title>
	<atom:link href="http://googleclosuretutorials.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://googleclosuretutorials.wordpress.com</link>
	<description>A great place to learn about Google&#039;s Closure library, with examples and source</description>
	<lastBuildDate>Thu, 19 Nov 2009 11:53:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='googleclosuretutorials.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Google Closure Tutorials</title>
		<link>http://googleclosuretutorials.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://googleclosuretutorials.wordpress.com/osd.xml" title="Google Closure Tutorials" />
	<atom:link rel='hub' href='http://googleclosuretutorials.wordpress.com/?pushpress=hub'/>
		<item>
		<title>SlideShow tutorial</title>
		<link>http://googleclosuretutorials.wordpress.com/2009/11/19/slideshow-tutorial/</link>
		<comments>http://googleclosuretutorials.wordpress.com/2009/11/19/slideshow-tutorial/#comments</comments>
		<pubDate>Thu, 19 Nov 2009 11:33:40 +0000</pubDate>
		<dc:creator>googleclosuretutorials</dc:creator>
				<category><![CDATA[Animation]]></category>
		<category><![CDATA[Closure Code]]></category>
		<category><![CDATA[DOM]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://googleclosuretutorials.wordpress.com/?p=42</guid>
		<description><![CDATA[LOOKING FOR SOURCE? Zip containing all the required files, and a copy of this tutorial. For my next tutorial, I&#8217;m going to look into building a SlideShow. There is a Slide object in goog.fx.dom that we could use, but I really wanted to have a look at goog.fx.Animation so I&#8217;ve used that instead. If you&#8217;ve [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=42&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>LOOKING FOR SOURCE? <a href="http://dl.dropbox.com/u/2741750/SlideShow.zip">Zip containing all the required files, and a copy of this tutorial</a>.</strong></p>
<p>For my next tutorial, I&#8217;m going to look into building a SlideShow. There is a Slide object in goog.fx.dom that we could use, but I really wanted to have a look at <strong>goog.fx.Animation</strong> so I&#8217;ve used that instead. If you&#8217;ve not read the InlinePopup tutorial, now would be a good time as I&#8217;ll be skipping over some of the more basic concepts that I explained last time.</p>
<p>First up, let&#8217;s define our namespace and <strong>require</strong>s:</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">goog.provide( &#8216;neame.ui.SlideShow&#8217; );</p>
<p>goog.require( &#8216;goog.events&#8217; );<br />
goog.require( &#8216;goog.dom&#8217; );<br />
goog.require( &#8216;goog.dom.query&#8217; );<br />
goog.require( &#8216;goog.style&#8217; );<br />
goog.require( &#8216;goog.fx.Animation&#8217; );<br />
goog.require( &#8216;goog.array&#8217; );</p></div>
<p>You should be able to tell what sort of things we&#8217;ll be working with from that (events, DOM, inline styles, animation and some array methods). Next up is the largest method of our SlideShow object &#8211; the constructor:</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/**<br />
 * SlideShow constructor<br />
 * @args slideshow:String &#8211; ID of the slideshow container<br />
 *       speed:int &#8211; how long in ms it should take to slide<br />
 *       axis:char &#8211; &#8216;x&#8217; or &#8216;y&#8217;<br />
 *       automated:bool &#8211; if true, it will slide by itself until &#8216;stop&#8217; method called<br />
 *       pause_ms &#8211; how long it should pause when sliding automagically<br />
 * All arguments are optional except slideshow<br />
 */<br />
neame.ui.SlideShow = function( slideshow , speed , axis , automated , pause_ms ){</p>
<p>	// set vars from arguments passed, or default<br />
	this.automated = automated || false;<br />
	this.pause_ms = !isNaN( pause_ms ) ? pause_ms : 8000;<br />
	this.speed = speed || 750;<br />
	this.axis = axis || &#8216;x&#8217; ;</p>
<p>	// get useful slide information &#8211; all based on first list, then first list item<br />
	this.slidecontainer = goog.dom.query( &#8216;#&#8217; + slideshow + &#8216; &gt; ul&#8217; )[ 0 ];<br />
	this.slides = goog.dom.query( &#8216;#&#8217; + slideshow + &#8216; &gt; ul &gt; li&#8217; );</p>
<p>	// get dimension and length of slides &#8211; making the assumption all are the same size<br />
	this.slideSize = goog.style.getBorderBoxSize( this.slides[ 0 ] );<br />
	this.numslides = this.slides.length;</p>
<p>	// set float by mapping the array according to axis<br />
	if( axis == &#8216;x&#8217; )<br />
		goog.array.map( this.slides , function( slide ){ goog.style.setFloat( slide , &#8216;left&#8217; ); } );<br />
	else<br />
		goog.array.map( this.slides , function( slide ){ goog.style.setFloat( slide , &#8216;none&#8217; ); } );</p>
<p>	// make global reference<br />
	this.id = neame.ui.SlideShow.Instances.length;<br />
	neame.ui.SlideShow.Instances[ this.id ] = this;</p>
<p>	// not currently sliding<br />
	this.sliding = false;<br />
	this.timer = null;</p>
<p>	if( this.automated )<br />
		this.nextSlide();</p>
<p>};</p></div>
<p>We start off the constructor by defining our object variables. The first 4 lines should be pretty self-explanatory &#8211; all we&#8217;re doing here is looking for the arguments this instance was called with and if not present, falling back to some sensible default values.</p>
<p>The next 2 lines are a bit more interesting &#8211; here you can see 2 calls to <strong>goog.dom.query</strong>. If you&#8217;re looking for an equivalent to jQuery&#8217;s $() method, you&#8217;ve just found it. Since <strong>goog.dom.query</strong> returns an array of matched Elements, we can just pull off the first matching UL for the slidecontainer by adding <strong>[ 0 ]</strong> after the method call.</p>
<p>Now that we have references to the container and slides, we can get the dimensions of the slides with a call to <strong>goog.style.getBorderBoxSize</strong>. Note here again I&#8217;m just pulling the first Element from the slides array (I&#8217;m assuming all slides are of a regular width and height).</p>
<p>Ok so we&#8217;ve done plenty of gets so far&#8230; Time for a couple of sets. By calling <strong>goog.array.map</strong>, we can apply a function to every element in the array, which in this case is every slide. All we are doing here is explicitly setting the float of every slide to &#8216;left&#8217; or &#8216;none&#8217; depending on the axis passed when the object was instantiated.</p>
<p>Next, we add a global reference to the slide (required for setTimeout later), set some initial variables (not sliding, timer is null) and finally, if automated, call nextSlide. And what does nextSlide do, you ask? Well, let&#8217;s have a look&#8230;</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/**<br />
 * nextSlide<br />
 * calculates the position of the next slide and calls slideFromTo<br />
 */<br />
neame.ui.SlideShow.prototype.nextSlide = function(){</p>
<p>	// if we are already sliding then exit<br />
	if( this.sliding ) return;<br />
	// get container position<br />
	var containerPos = goog.style.getPosition( this.slidecontainer );<br />
	// calculate next slide position based on axis<br />
	if( this.axis == &#8216;x&#8217; ){<br />
		// calculate target x position<br />
		var tx = ( Math.abs( containerPos.x &#8211; this.slideSize.width ) / this.numslides &lt; this.slideSize.width ) ? ( containerPos.x &#8211; this.slideSize.width ) : 0;<br />
		// slide from current x to tx<br />
		this.slideFromTo( [ containerPos.x , 0 ] , [ tx , 0 ] );<br />
	}else{<br />
		// calculate target y position<br />
		var ty = ( Math.abs( containerPos.y &#8211; this.slideSize.height ) / this.numslides &lt; this.slideSize.height ) ? ( containerPos.y &#8211; this.slideSize.height ) : 0;<br />
		// slide from current y to ty<br />
		this.slideFromTo( [ 0 , containerPos.y ] , [ 0 , ty ] );<br />
	}</p>
<p>};</p></div>
<p>nextSlide is pretty simple &#8211; first off, if we are already sliding, then just return straight away &#8211; don&#8217;t execute any of the other logic. If we get to the next line, then we aren&#8217;t sliding and so we need to calculate the position of the next slide and make a call to slideFromTo, which moves the slideshow from one position to another. I&#8217;m not going to go into the longer lines too much, but all they are saying is &#8216;if the next slide is off the end of the list of slides, then go back to 0. Otherwise the co-ordinates for the next slide are the same as the current position minus one slide&#8217;s width (or height)&#8217;.</p>
<p>prevSlide is exactly the same as nextSlide but it does it the other way around &#8211; <em>plus</em> one slide&#8217;s width (or height). I won&#8217;t include it here but it&#8217;s in the source file.</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/**<br />
 * slideFromTo<br />
 * @args    oc:Array(2) &#8211; origin co-ordinates<br />
 *          tc:Array(2) &#8211; target co-ordinates<br />
 */<br />
neame.ui.SlideShow.prototype.slideFromTo = function( oc , tc ){</p>
<p>	// create animation object<br />
	this.anim = new goog.fx.Animation( oc ,  tc , this.speed , this.animationAcceleration );</p>
<p>	// array of animation events we want to capture<br />
	var animationevents = [ goog.fx.Animation.EventType.BEGIN,<br />
	                        goog.fx.Animation.EventType.ANIMATE,<br />
	                        goog.fx.Animation.EventType.END ];<br />
	// bind listeners<br />
	goog.events.listen( this.anim , animationevents , this.tick , false, this );<br />
	goog.events.listen( this.anim , goog.fx.Animation.EventType.END , this.animationDone , false , this );</p>
<p>	// Start animation<br />
	this.anim.play( false );<br />
	this.sliding = true;</p>
<p>};</p></div>
<p>slideFromTo is one of the most interesting methods. The first thing we do is create an Animation object provided by <strong>goog.fx.Animation</strong>, passing it the origin co-ordinates, target co-ordinates, time that the animation should take and an easing function (defined later).</p>
<p>Next we create an array of animation events we would like to listen for (I have to say, I was pleasantly surprised when I found out you can pass arrays to goog.events.listen &#8211; you could probably live without the BEGIN and END listeners but for the sake of this tutorial I&#8217;ll leave them in). We then bind <strong>this.tick</strong> to these events, so that every time BEGIN, ANIMATE or END are dispatched our tick method will be called. We also bind <strong>this.animationDone</strong> to the END event so we can do some extra things once the animation is complete.</p>
<p>Then we just have to start the Animation object with <strong>this.anim.play</strong> and set <strong>this.sliding</strong> to true, so that any calls to nextSlide or prevSlide will be ignored until this flag is removed. When this.anim.play is called, the BEGIN event is dispatched and then ANIMATE is dispatched every time the Animation object starts a new &#8216;frame&#8217;.</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/**<br />
 * tick<br />
 * @args    e:Event &#8211; Animation Event<br />
 */<br />
neame.ui.SlideShow.prototype.tick = function( e ){<br />
	if( this.axis == &#8216;x&#8217; )<br />
		goog.style.setPosition( this.slidecontainer , e.x );<br />
	else<br />
		goog.style.setPosition( this.slidecontainer , 0 , e.y );<br />
};</div>
<p><strong>tick</strong>, as mentioned above, is the method that is called on every &#8216;frame&#8217; in the animation. It&#8217;s pretty simple but there&#8217;s one thing you should note here &#8211; we are setting the position of the slidecontainer with the <em>event</em> ordinates. Since the event being passed to <strong>tick</strong> is an Animation Event, the constants x and y refer to the position that the slidecontainer should be at, at that time. So it&#8217;s a simple check of axis and then a call to <strong>goog.style.setPosition</strong>. Next up, we need to think about what to do when the animation is complete:</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/**<br />
 * animationDone<br />
 * @args    e:Event &#8211; Animation Event<br />
 */<br />
neame.ui.SlideShow.prototype.animationDone = function( e ){<br />
	// ok to slide<br />
	this.sliding = false;<br />
	if( this.automated ) this.timer = setTimeout( &#8216;SlideShow_Instances[' + this.id + '].nextSlide()&#8217; , this.pause_ms );<br />
};</div>
<p>This method is pretty simple and a little bit ugly&#8230; We set <strong>this.sliding</strong> to false so that we can move the slideshow again and then &#8211; if the SlideShow is automated &#8211; make a call to setTimeout to fire nextSlide() on the current object in <strong>this.pause_ms</strong> ms time. I&#8217;m sure there&#8217;s a neater way to do this but I&#8217;ve relied on a global variable <strong>SlideShow_Instances</strong> (see constructor) to make the call. We now have every method we need to automate the slideshow, except a method to make it start and to make it stop:</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/***<br />
 * stop<br />
 * stops the slideshow if automated<br />
 */<br />
neame.ui.SlideShow.prototype.stop = function(){<br />
	this.automated = false;<br />
	clearTimeout( this.timer );<br />
};</p>
<p>/***<br />
 * go<br />
 * starts automated slideshow<br />
 */<br />
neame.ui.SlideShow.prototype.go = function(){<br />
	this.automated = true;<br />
	clearTimeout( this.timer );<br />
	this.nextSlide();<br />
};</p></div>
<p>These two methods are pretty simple &#8211; <strong>stop</strong> sets automated to false and halts the timer, whereas <strong>go</strong> sets automated to true, halts the timer and then starts sliding. There&#8217;s only one method we haven&#8217;t covered now, which is <strong>animationAcceleration</strong>. I have to admit I hit a bit of a snag here &#8211; there&#8217;s an easeOut method in goog.fx.easing, but for some reason I couldn&#8217;t get it to work with my script. I could <strong>require()</strong> the package with no errors, but then I would get errors telling me the method was not available. So in the end I just looked up the source and copied it into my own method, seeing as it&#8217;s so short anyway:</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/***<br />
 * animationAccelleration<br />
 * ease out function<br />
 */<br />
neame.ui.SlideShow.prototype.animationAcceleration = function( t ) {<br />
  return 1 &#8211; Math.pow( 1 &#8211; t , 3 );<br />
};</div>
<p>And last but not least, we need to instantiate our global array (to hold references to each slide in, required for automated animation) and export symbols to the document. Since there is a good chance our method names will be changed when the code is compiled, <strong>exportSymbol</strong> ensures that we always have a reference to them, even if their names change.</p>
<div style="background:#eee;border:1px solid #333;white-space:pre;font-family:Courier;font-size:11px;padding:10px;">/***<br />
 * make Instances array and export symbols<br />
 */<br />
neame.ui.SlideShow.Instances = new Array();<br />
// export symbols<br />
goog.exportSymbol( &#8216;SlideShow_Instances&#8217; , neame.ui.SlideShow.Instances );<br />
goog.exportSymbol( &#8216;SlideShow&#8217; , neame.ui.SlideShow );</div>
<p>Now that we have <strong>exportSymbol</strong>&#8216;d our constructor and instances array, <strong>neame.ui.SlideShow</strong> will be available as &#8216;SlideShow&#8217;. This means we can make new slideshows by calling <strong>new SlideShow( id )</strong> rather than <strong>new neame.ui.SlideShow( id )</strong>. Note that in <strong>animationDone</strong> we refer to <strong>neame.ui.SlideShow.Instances</strong> as <strong>SlideShow_Instances</strong>.</p>
<p>And that&#8217;s it! Make sure you grab a copy of the source and have a look at how the XHTML is structured. The SlideShow object requires an unordered list of list items, wrapped in a div element. The CSS in the .html file is also required, though SlideShow *will* overwrite any float declarations on the list items.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/googleclosuretutorials.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/googleclosuretutorials.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/googleclosuretutorials.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/googleclosuretutorials.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/googleclosuretutorials.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/googleclosuretutorials.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/googleclosuretutorials.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/googleclosuretutorials.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/googleclosuretutorials.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/googleclosuretutorials.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/googleclosuretutorials.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/googleclosuretutorials.wordpress.com/42/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/googleclosuretutorials.wordpress.com/42/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/googleclosuretutorials.wordpress.com/42/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=42&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://googleclosuretutorials.wordpress.com/2009/11/19/slideshow-tutorial/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1d1fe746b0171382bfa14106342b481?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">googleclosuretutorials</media:title>
		</media:content>
	</item>
		<item>
		<title>JSON Tutorial &#8211; Displaying Friendfeed items</title>
		<link>http://googleclosuretutorials.wordpress.com/2009/11/14/json-tutorial-displaying-friendfeed-items/</link>
		<comments>http://googleclosuretutorials.wordpress.com/2009/11/14/json-tutorial-displaying-friendfeed-items/#comments</comments>
		<pubDate>Sat, 14 Nov 2009 16:08:27 +0000</pubDate>
		<dc:creator>googleclosuretutorials</dc:creator>
				<category><![CDATA[DOM]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://googleclosuretutorials.wordpress.com/?p=35</guid>
		<description><![CDATA[There&#8217;s an interesting tutorial at lahosken.san-francisco.ca.us for retrieving and displaying Friendfeed items using Google Closure&#8217;s Jsonp class. It&#8217;s great for seeing how to handle JSON requests with Closure, as well as covering some useful methods in goog.array and a number of DOM manipulation methods in goog.dom. Well worth running through.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=35&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s an interesting tutorial at lahosken.san-francisco.ca.us for <a href="http://lahosken.san-francisco.ca.us/frivolity/prog/closure_ffdemo/">retrieving and displaying Friendfeed items using Google Closure&#8217;s Jsonp class</a>. It&#8217;s great for seeing how to handle JSON requests with Closure, as well as covering some useful methods in goog.array and a number of DOM manipulation methods in goog.dom.<br />
Well worth running through.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/googleclosuretutorials.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/googleclosuretutorials.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/googleclosuretutorials.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/googleclosuretutorials.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/googleclosuretutorials.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/googleclosuretutorials.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/googleclosuretutorials.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/googleclosuretutorials.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/googleclosuretutorials.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/googleclosuretutorials.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/googleclosuretutorials.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/googleclosuretutorials.wordpress.com/35/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/googleclosuretutorials.wordpress.com/35/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/googleclosuretutorials.wordpress.com/35/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=35&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://googleclosuretutorials.wordpress.com/2009/11/14/json-tutorial-displaying-friendfeed-items/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1d1fe746b0171382bfa14106342b481?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">googleclosuretutorials</media:title>
		</media:content>
	</item>
		<item>
		<title>Lightbox / Shadowbox / Whateverbox built on Closure</title>
		<link>http://googleclosuretutorials.wordpress.com/2009/11/13/lightbox-shadowbox-whateverbox-built-on-closure/</link>
		<comments>http://googleclosuretutorials.wordpress.com/2009/11/13/lightbox-shadowbox-whateverbox-built-on-closure/#comments</comments>
		<pubDate>Fri, 13 Nov 2009 10:36:55 +0000</pubDate>
		<dc:creator>googleclosuretutorials</dc:creator>
				<category><![CDATA[Images]]></category>
		<category><![CDATA[UI]]></category>

		<guid isPermaLink="false">http://googleclosuretutorials.wordpress.com/?p=3</guid>
		<description><![CDATA[LOOKING FOR SOURCE? Zip containing all the required files (you still need the Closure library though, naturally). For my first few forays into Google&#8217;s Closure library I&#8217;ll be looking at building some common UI components. First up is the inline / modal popup. Most of the time these things are used for images, so for [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=3&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><strong>LOOKING FOR SOURCE? </strong><a href="http://dl.dropbox.com/u/2741750/InlinePopup.zip"><strong>Zip containing all the required files</strong></a><strong> (you still need the Closure library though, naturally).</strong></p>
<p>For my first few forays into <a href="http://code.google.com/closure/" target="_blank">Google&#8217;s Closure library</a> I&#8217;ll be looking at building some common UI components.</p>
<p>First up is the <strong>inline / modal popup</strong>. Most of the time these things are used for images, so for this little app I&#8217;m going to make it work for that purpose.</p>
<p>Now, what do we want out of this?</p>
<ol>
<li>It must be portable and easy to implement.</li>
<li>The popup itself should shrink or expand to match the image inside it.</li>
<li>When the popup is launched, the rest of the page should fade out.</li>
<li>The popup must have a close button, but clicking on the page / background should also close it.</li>
</ol>
<p>Right, let&#8217;s get started&#8230; I’m going to assume you’ve run through the Hello World tutorial provided by Google. If not, there is a great walkthrough of it on <a href="http://www.moretechtips.net/2009/11/getting-closer-to-google-closure.html" target="_blank">moretechtips.net</a>.</p>
<p>To begin with, make a new .JS file and give it a meaningful name (being the imaginative person I am, I chose ‘inlinepopup.js’). The first thing we need to do is define a namespace for our InlinePopup Class. Therefore, our first declaration should therefore make use of goog.provide():</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>goog.provide( 'neame.ui.InlinePopup' );</code></div>
<p>Now that we’ve done that, we need to identify which classes in the Closure library we’ll be using for our InlinePopup. A quick glance through the google.ui package shows a few potential candidates but <a href="http://closure-library.googlecode.com/svn/trunk/closure/goog/demos/dialog.html" target="_blank">Dialog</a> seems to be the most appropriate.  Frankly, it looks like all we’re going to need to do is tweak a few properties and Bob’s your uncle.</p>
<p>As for preloading the image – Google kindly provides us with the ImageLoader class, in the goog.net package. We’re also going to need to handle some events, so we’ll need goog.events for that, and we’re going to be working with the DOM so a DomHelper would be handy too. The lines to include these classes are as follows:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>goog.require( 'goog.events' );<br />
goog.require( 'goog.ui.Dialog' );<br />
goog.require( 'goog.dom.DomHelper' );<br />
goog.require( 'goog.net.ImageLoader' );</code></div>
<p>Ok, so we have our namespace, we’ve included the required classes… We know we’re going to need at least a constructor, a method to launch the popup, a method to close the popup and a method to handle the image load, so let’s define those now:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>// constructor – takes no arguments<br />
neame.ui.InlinePopup = function(){ };// open popup – takes a click event as an argument<br />
neame.ui.InlinePopup.prototype.goPopup = function( e ){ };</p>
<p>// close popup – takes a click event as an argument<br />
neame.ui.InlinePopup.prototype.closePopup = function( e ){ };</p>
<p>// image loaded – takes a load event as an argument<br />
neame.ui.InlinePopup.prototype.imageLoaded = function( e ){ };</p>
<p></code><code>// bind to class – adds a listener to any links with the specified class ‘c’<br />
neame.ui.InlinePopup.prototype.bindToClass = function( c ){ };</code></p>
</div>
<p>Note that none of these methods will return anything (or if you like AS3 or Java, they return void).</p>
<p>So we have our skeletons set up but no logic yet. The constructor is the logical place to start. I’ll write out the code here and we can discuss it afterwards:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>neame.ui.InlinePopup = function(){// init objects<br />
this.dia = new goog.ui.Dialog( 'inlinepopup' , true );<br />
this.loader = new goog.net.ImageLoader();<br />
this.domh = new goog.dom.DomHelper();</p>
<p>// setup objects<br />
this.dia.setVisible( false );<br />
this.dia.setBackgroundElementOpacity( 0.9 );<br />
this.dia.getButtonElement().parentNode.removeChild( this.dia.getButtonElement() );<br />
this.dia.getTitleCloseElement().innerHTML = 'X';</p>
<p>// event listeners<br />
goog.events.listen( this.dia.getBackgroundElement() ,  goog.events.EventType.CLICK , this.closePopup , false , this );<br />
goog.events.listen( this.loader , goog.events.EventType.LOAD , this.imageLoaded , false , this );</p>
<p></code><code>};</code></p>
</div>
<p>First off, we instantiate our objects. We create a new Dialog with the class name ‘inlinepopup’, using an iframe mask for the background. Next up, we create our ImageLoader and DomHelper. Nothing too taxing so far.</p>
<p>Now for some more interesting stuff – let’s set up our Dialog. The syntax is pretty much self-commenting but all I’m doing here is making sure it’s not visible at first, setting the background to 90% opacity, removing the OK and Cancel buttons, and adding a simple ‘X’ character to the close button (you might want to use an image background via CSS instead). If you change setVisible to true right now, you&#8217;ll be able to see the Dialog on your page if you create a new InlinePopup&#8230; But it won&#8217;t look like much until we apply the CSS later.</p>
<p>Next we set up our event listeners. One to listen for a CLICK on the background and call closePopup. Another to listen for a LOAD event on our imageloader and call imageLoaded.</p>
<p>So our constructor is now in place! On to the open and close methods:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>neame.ui.InlinePopup.prototype.goPopup = function( e ){<br />
// dont follow the link<br />
e.preventDefault();// add link href as image to load<br />
this.loader.addImage( 'previewimg' , e.currentTarget.href );<br />
this.loader.start();</p>
<p>// set title<br />
if( e.currentTarget.title )<br />
this.dia.setTitle( e.currentTarget.title ); // use title if the anchor has one<br />
else<br />
this.dia.setTitle( e.currentTarget.href ); // otherwise show href as title</p>
<p>};</p>
<p></code><code>neame.ui.InlinePopup.prototype.closePopup = function( e ){<br />
this.dia.setVisible( false );<br />
};</code></p>
</div>
<p>closePopup shouldn’t really need any explanation – all it does it setVisible to false on the Dialog (i.e.: it hides it).</p>
<p>openPopup is a little more involved. Since this is going to be launched from anchor elements on the page (&lt;a&gt;), we need to make sure the link isn’t followed or the browser will navigate off the page. To prevent this we make a call to preventDefault on the event. This means the default action of the click event will not fire – the link will not be followed and the user will stay on the page. Next, we pass the link href to the ImageLoader and tell it to start loading. Since the anchor element is the currentTarget of the CLICK event, we can access this URL via e.currentTarget.href. ‘previewimg’ in this call is just the ID we want to give the image. If you want to load a bunch of these you’ll need a unique ID for each image, but in this case we’re only dealing with 1 image at a time so it’s safe to use the same ID each time.  Finally, we set the Dialog title. If the anchor element has a title attribute, we use that. Otherwise we just default to the href value.</p>
<p>So, we have a constructor, a way to open the Dialog and close it, but what we are missing is logic to handle the image load:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>neame.ui.InlinePopup.prototype.imageLoaded = function( e ){<br />
// set width, then content , then show it<br />
this.dia.getDialogElement().style.width = ( e.target.width + 30 ) + 'px';<br />
this.dia.setContent( '&lt;img src="' + e.target.src + '" width="' + e.target.width + '" height="' + e.target.height + '" /&gt;' );<br />
// show it<br />
this.dia.setVisible( true ); </code><code>};</code></p>
</div>
<p>The first statement matches the Dialog width to the image width. This is done fairly simply by accessing the target of the load event (the image) and just reading off it’s width property. I’m adding 30 pixels here to allow for 15 pixels padding either side of the image. Then we just need to set the content of the dialog and show it.</p>
<p>Last up is the bindToClass method:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>neame.ui.InlinePopup.prototype.bindToClass = function( c ){var es = this.domh.getElementsByTagNameAndClass( '*' , c );<br />
// listen for CLICK Event on every object in the NodeList<br />
for( i in es ) if( typeof es[ i ] == 'object' )<br />
goog.events.listen( es[ i ] , goog.events.EventType.CLICK , this.goPopup , false , this );</p>
<p></code><code>};</code></p>
</div>
<p>This is pretty self-explanatory but all we’re doing here is selecting every element on the page with the class given and listening for a click event on it. Then the event is passed to our goPopup method to open the Dialog.</p>
<p>And that’s it for the InlinePopup class!</p>
<p>Here’s the CSS I used. Feel free to play around with these but you need to keep the position declarations, or the dialog will render below the background iframe rather than on top of it. I pretty much just ripped this off from the Dialog example page and then modified it to suit a style that I’d like:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>.inlinepopup-bg {<br />
position: absolute;<br />
background-color: #000;<br />
top: 0;<br />
left: 0;<br />
}<br />
.inlinepopup {<br />
position: absolute;<br />
background-color: #000;<br />
width: 1000px; /* this gets replaced anyway via Closure JS */<br />
overflow: hidden;<br />
}<br />
.inlinepopup-title {<br />
position: relative;<br />
background-color: #000;<br />
color: #fff;<br />
padding: 10px 15px;<br />
font-size: 16px;<br />
font-weight: bold;<br />
vertical-align: middle;<br />
cursor: hand;<br />
}.inlinepopup-title-close {<br />
position: absolute;<br />
top: 10px;<br />
right: 15px;<br />
width: 15px;<br />
height: 16px;<br />
cursor: default;<br />
}</p>
<p></code><code>.inlinepopup-content {   padding: 15px; }</code></p>
</div>
<p>Finally, we pull it all together in our HTML document:</p>
<div style="background-color:#eee;border:1px solid #999;padding:5px;"><code>&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;&lt;head&gt;&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;</p>
<p>&lt;title&gt;Google Closure Shadowbox!&lt;/title&gt;</p>
<p>&lt;script src="/path/to/closure/goog/base.js"&gt;&lt;/script&gt;</p>
<p>&lt;script src="inlinepopup.js"&gt;&lt;/script&gt;</p>
<p>&lt;link href=”style.css” /&gt;</p>
<p>&lt;/head&gt;</p>
<p>&lt;body&gt;</p>
<p>&lt;div&gt;&lt;a href=&quot;http://arkandis.com/images/blog/google.gif&quot; class=&quot;inlinepopup-trigger&quot; title=&quot;Google logo in Lego&quot;&gt;&lt;img src=&quot;pic.jpg&quot; width=&quot;200&quot; height=&quot;125&quot; alt=&quot;Pic&quot; /&gt;&lt;/a&gt;&lt;/div&gt;</p>
<p>&lt;div&gt;&lt;a href=&quot;http://images.businessweek.com/ss/06/07/top_brands/image/google.jpg&quot; class=&quot;inlinepopup-trigger&quot; title=&quot;Google logo on some dude's hand&quot;&gt;&lt;img src=&quot;pic.jpg&quot; width=&quot;200&quot; height=&quot;125&quot; alt=&quot;Pic&quot; /&gt;&lt;/a&gt;&lt;/div&gt;</p>
<p>&lt;script&gt;</p>
<p>var popup = new neame.ui.InlinePopup();</p>
<p>popup.bindToClass( 'inlinepopup-trigger' );</p>
<p>&lt;/script&gt;</p>
<p>&lt;/body&gt;</p>
<p></code><code>&lt;/html&gt;</code></p>
</div>
<p>Note: If you&#8217;re going to push this to a live site, don&#8217;t forget to compile your code. This stuff is just the source!</p>
<p>Anyway, hope you found the tutorial useful. Comments are very welcome. Next up is a Slideshow!</p>
<p>Dan</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/googleclosuretutorials.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/googleclosuretutorials.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/googleclosuretutorials.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/googleclosuretutorials.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/googleclosuretutorials.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/googleclosuretutorials.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/googleclosuretutorials.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/googleclosuretutorials.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/googleclosuretutorials.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/googleclosuretutorials.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/googleclosuretutorials.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/googleclosuretutorials.wordpress.com/3/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/googleclosuretutorials.wordpress.com/3/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/googleclosuretutorials.wordpress.com/3/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=3&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://googleclosuretutorials.wordpress.com/2009/11/13/lightbox-shadowbox-whateverbox-built-on-closure/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1d1fe746b0171382bfa14106342b481?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">googleclosuretutorials</media:title>
		</media:content>
	</item>
		<item>
		<title>&#8216;allo &#8216;allo</title>
		<link>http://googleclosuretutorials.wordpress.com/2009/11/12/hello-world/</link>
		<comments>http://googleclosuretutorials.wordpress.com/2009/11/12/hello-world/#comments</comments>
		<pubDate>Thu, 12 Nov 2009 11:38:40 +0000</pubDate>
		<dc:creator>googleclosuretutorials</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false"></guid>
		<description><![CDATA[There&#8217;s nothing here right now but if you check back on Friday the 13th November you will find a spiffing tutorial on how to build a Shadowbox / Lightbox with Google Closure.<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=1&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>There&#8217;s nothing here right now but if you check back on <strong>Friday the 13th November</strong> you will find a spiffing tutorial on how to build a Shadowbox / Lightbox with Google Closure.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/googleclosuretutorials.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/googleclosuretutorials.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/googleclosuretutorials.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/googleclosuretutorials.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/googleclosuretutorials.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/googleclosuretutorials.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/googleclosuretutorials.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/googleclosuretutorials.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/googleclosuretutorials.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/googleclosuretutorials.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/googleclosuretutorials.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/googleclosuretutorials.wordpress.com/1/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/googleclosuretutorials.wordpress.com/1/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/googleclosuretutorials.wordpress.com/1/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=googleclosuretutorials.wordpress.com&amp;blog=10451866&amp;post=1&amp;subd=googleclosuretutorials&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://googleclosuretutorials.wordpress.com/2009/11/12/hello-world/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/a1d1fe746b0171382bfa14106342b481?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">googleclosuretutorials</media:title>
		</media:content>
	</item>
	</channel>
</rss>
