<?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/"
	>

<channel>
	<title>Kyle Rush &#187; JavaScript</title>
	<atom:link href="http://kylerush.net/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://kylerush.net</link>
	<description>Blog &#38; Portfolio of Kyle Rush</description>
	<lastBuildDate>Wed, 04 May 2011 14:16:09 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.2</generator>
		<item>
		<title>JavaScript Epoch Time Converter Number Method</title>
		<link>http://kylerush.net/javascript/javascript-epoch-time-converter-number-method/</link>
		<comments>http://kylerush.net/javascript/javascript-epoch-time-converter-number-method/#comments</comments>
		<pubDate>Sun, 10 Jan 2010 02:18:58 +0000</pubDate>
		<dc:creator>Kyle Rush</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[epoch time]]></category>
		<category><![CDATA[js prototype method]]></category>
		<category><![CDATA[number object]]></category>

		<guid isPermaLink="false">http://kylerush.net/?p=450</guid>
		<description><![CDATA[This JavaScript Number object method will return a numerical and word based string from an epoch time number. For example, the method will turn the number "98635" into the string "1 days, 3 hours, 23 minutes, 55 seconds".]]></description>
			<content:encoded><![CDATA[<h2 id="overview">Overview</h2>
<p>The code below extends the JavaScript Number object with a method that will convert an epoch time into a string that represents the days, hours, minutes and seconds of the given epoch number. For example, the method will turn the number &#8220;98635&#8243; into the string &#8220;1 days, 3 hours, 23 minutes, 55 seconds&#8221;.</p>
<p>I made this simple number object method one day for a side project of mine where I needed to profile the amount of time that certain ajax calls were taking to complete. I then average these times together and after multiplied that average by the number of requests that were still left to complete. This provided me with an estimated time of completion for x number of ajax calls. To get the difference of the time, I just created a new date when the ajax call started and another after it finished. Since JavaScript stores these times as seconds since the epoch, it&#8217;s easy to subtract one from the other to get the amount of time it took for the ajax call to complete. As soon as I had the number of milliseconds that all the remaining ajax calls would take to complete (according to my average calculation), I used this method to return something readable to a human being. I hope you find it useful.</p>
<h2 id="usage">Usage</h2>
<p>To use the method, simply create a number type variable (var time = 98635;) and then call the method named &#8216;timeLeft&#8217; on the variable, like so: &#8220;var timeLeft = time.timeLeft();&#8221;.</p>
<h2 id="the-code">The Code</h2>
<h3>Minified Code:</h3>
<div class="clear">
<pre class="brush: jscript">
Number.prototype.timeLeft=function(){var days=Math.floor(this/86400);var hours=Math.floor((this-(days*86400))/3600);var minutes=Math.floor((this-((hours*3600)+(days*86400)))/60);var seconds=this-((days*86400)+(hours*3600)+(minutes*60));var result=new String();if((days>0)===true){result+=days+' days,';}if((hours>0)===true){result+=' '+hours+' hours, ';}if((minutes>0)===true){result+=' '+minutes+' minutes,';}if((seconds>0)){result+=' '+seconds+' seconds,';}result=result.slice(0,-1);return result;}
</pre>
</div>
<p><!--.clear--></p>
<h3>Full Code:</h3>
<div class="clear">
<pre class="brush: jscript">
Number.prototype.timeLeft = function(){

    var days = Math.floor(this / 86400);

    var hours = Math.floor((this - (days * 86400)) / 3600);

    var minutes = Math.floor((this - ((hours * 3600) + (days * 86400))) / 60);

    var seconds = this - ((days * 86400) + (hours * 3600) + (minutes * 60));

    var result = new String();

    if((days > 0) === true){result += days + ' days,';}
    if((hours > 0) === true){result += ' ' + hours + ' hours, ';}
    if((minutes > 0) === true){result += ' ' + minutes + ' minutes,';}
    if((seconds > 0)){result += ' ' + seconds + ' seconds,';}

    result = result.slice(0, -1);

    return result;

}
</pre>
</div>
<p><!--.clear--></p>
<p><script type="text/javascript" src="http://kylerush.org/kr/syntax-highlighter/scripts/shCore.js"></script><br />
<script type="text/javascript" src="http://kylerush.org/kr/syntax-highlighter/scripts/shBrushJScript.js"></script><br />
<script type="text/javascript" src="http://kylerush.org/kr/syntax-highlighter/scripts/shBrushCss.js"></script><br />
<script type="text/javascript" src="http://kylerush.org/kr/syntax-highlighter/scripts/shBrushXml.js"></script></p>
<link type="text/css" rel="stylesheet" href="http://kylerush.org/kr/syntax-highlighter/styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="http://kylerush.org/kr/syntax-highlighter/styles/shThemeDefault.css"/>
<script type="text/javascript">// <![CDATA[
		SyntaxHighlighter.config.clipboardSwf = 'http://kylerush.org/kr/syntax-highlighter/scripts/clipboard.swf';
		SyntaxHighlighter.all();
// ]]&gt;</script></p>
]]></content:encoded>
			<wfw:commentRss>http://kylerush.net/javascript/javascript-epoch-time-converter-number-method/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interview on Open Voice about jParse</title>
		<link>http://kylerush.net/javascript/interview-open-voice-jparse/</link>
		<comments>http://kylerush.net/javascript/interview-open-voice-jparse/#comments</comments>
		<pubDate>Mon, 16 Nov 2009 16:36:29 +0000</pubDate>
		<dc:creator>Kyle Rush</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Interview]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[jparse]]></category>
		<category><![CDATA[open voice]]></category>

		<guid isPermaLink="false">http://kylerush.net/?p=431</guid>
		<description><![CDATA[Schalk Neeling at <a href="http://openvoice.ossreleasefeed.com/">Open Voice</a> was kind enough to have me for an <a href="http://openvoice.ossreleasefeed.com/2009/11/kyle-rush-on-jparse-easy-xml-parsing-with-jquery/">interview</a> on <a href="http://jparse.kylerush.net">jParse</a>. We discussed what sets <a href="http://jparse.kylerush.net">jParse</a> apart from other XML parsing methods and jQuery plugins, how to use it, planned feature additions and more. <a href="http://openvoice.ossreleasefeed.com/2009/11/kyle-rush-on-jparse-easy-xml-parsing-with-jquery/">Read the interview here</a>.]]></description>
			<content:encoded><![CDATA[<p>Schalk Neeling at <a href="http://openvoice.ossreleasefeed.com/">Open Voice</a> was kind enough to have me for an <a href="http://openvoice.ossreleasefeed.com/2009/11/kyle-rush-on-jparse-easy-xml-parsing-with-jquery/">interview on jParse</a>. We discussed what sets <a href="http://jparse.kylerush.net">jParse</a> apart from other XML parsing methods and jQuery plugins, how to use it, planned feature additions and more. <a href="http://openvoice.ossreleasefeed.com/2009/11/kyle-rush-on-jparse-easy-xml-parsing-with-jquery/">Read the interview here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://kylerush.net/javascript/interview-open-voice-jparse/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>jParse: Easily Parse XML with jQuery</title>
		<link>http://kylerush.net/uncategorized/introducing-jparse-jquery-plugin-parse-xml/</link>
		<comments>http://kylerush.net/uncategorized/introducing-jparse-jquery-plugin-parse-xml/#comments</comments>
		<pubDate>Mon, 09 Nov 2009 16:24:30 +0000</pubDate>
		<dc:creator>Kyle Rush</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Plugin]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[jparse]]></category>

		<guid isPermaLink="false">http://kylerush.net/?p=416</guid>
		<description><![CDATA[Today I launched the site of a jQuery plugin that I've been working on called <a href="http://jparse.kylerush.net">jParse</a>. The plugin allows you to easily parse XML that has been fetched with an Ajax request. The plugin works off of jQuery's <a href="http://docs.jquery.com/Ajax/jQuery.ajax#options">ajax method</a>, so all of the same options are available. In terms of parsing, the plugin gives you a few options: Custom Output, Limit, Count of Items and the ability to run functions before and after <a href="http://jparse.kylerush.net">jParse</a> is finished.]]></description>
			<content:encoded><![CDATA[<p>Today I launched the site of a jQuery plugin that I&#8217;ve been working on called <a href="http://jparse.kylerush.net">jParse</a>. The plugin allows you to easily parse XML that has been fetched with an Ajax request. The plugin works off of jQuery&#8217;s <a href="http://docs.jquery.com/Ajax/jQuery.ajax#options">ajax method</a>, so all of the same options are available. In terms of parsing, the plugin gives you a few options: Custom Output, Limit, Count of Items and the ability to run functions before and after <a href="http://jparse.kylerush.net">jParse</a> is finished.</p>
<div id="entries-cont" style="margin: 20 0; background: #F0F0F0; padding: 15px;">
<h3>jParse Demo:</h3>
<p>The following is populated by jParse from the main RSS feed of this site.</p>
<div id="entries-inner-cont"></div>
<p><!--/#entries-inner-cont-->
</div>
<p><!--/#entries-cont--></p>
]]></content:encoded>
			<wfw:commentRss>http://kylerush.net/uncategorized/introducing-jparse-jquery-plugin-parse-xml/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Tutorial: Use the Flickr API, Javascript (jQuery), AJAX and JSON to Build a Detailed Photo Wall</title>
		<link>http://kylerush.net/javascript/tutorial-flickr-api-javascript-jquery-ajax-json-build-detailed-photo-wall/</link>
		<comments>http://kylerush.net/javascript/tutorial-flickr-api-javascript-jquery-ajax-json-build-detailed-photo-wall/#comments</comments>
		<pubDate>Wed, 17 Jun 2009 04:34:18 +0000</pubDate>
		<dc:creator>Kyle Rush</dc:creator>
				<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Flickr]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[JSON]]></category>

		<guid isPermaLink="false">http://kylerush.net/?p=322</guid>
		<description><![CDATA[In this tutorial, I'll show you how to create a photo wall of your Flickr photos. The script will use jQuery to send several Ajax requests for JSON data and then ultimately insert all of the images and the information associated with them into the document. The photo wall will be complete with a rollover on each image which will show and link to the information that is available for the image.]]></description>
			<content:encoded><![CDATA[<div class="wp-caption alignnone" style="width: 640px"><img title="Photos by Kyle Rush" src="http://kylerush.net/images/flickr-tutorial/flickr-tutorial-img.jpg" alt="Tutorial: How to Use the Flickr API, JavaScript, jQuery, Ajax and JSON to Build a Photo Wall" width="630" height="200" /><p class="wp-caption-text">Tutorial: How to Use the Flickr API, JavaScript, jQuery, Ajax and JSON to Build a Photo Wall</p></div>
<div class="demo">
<p><a href="http://kylerush.net/tutorials/flickr-photo-wall/" target="_blank">VIEW DEMO</a></p>
</div>
<p><!--/.demo--></p>
<h2>Introduction</h2>
<p>In this tutorial, I&#8217;ll show you, line by line, how to build a photo wall by pulling your pictures from Flickr using the Flickr API, jQuery, Ajax and JSON. The script I wrote places the following information over the image to which it relates: title, author, comment count, tag listing, location with a link to a map of those coordinates and the description. If any of this information doesn&#8217;t exist for a given photo, the script will just not include it.  If you haven&#8217;t used the Flickr API before, you should read my post on <a href="http://kylerush.net/flickr/flickr-api/">How to Use the Flickr API</a> first. I won&#8217;t provide much explanation here on the Flickr API. This is more a tutorial of interacting with Flickr using JavaScript, jQuery, Ajax, and JSON. You do not need an advanced or intermediate understanding of JavaScript or jQuery because I&#8217;ll explain almost everything. Let&#8217;s get started.</p>
<h2>Getting Started: the HTML/CSS</h2>
<p>Because the HTML and CSS to achieve this layout is fairly simple and because this isn&#8217;t an HTML/CSS tutorial, comments on this section will be short. Whenever you are using JavaScript to manipulate the DOM, you have to take into account accessibility. Since we&#8217;ll be adding our Flickr photo to the document after it is loaded, we&#8217;ll need to provide an alternative way to get to the content (your Flickr photos) for visitors without JavaScript enabled. This needs to be handwritten in the HTML. Take note of the element with an ID of <span class="code">a-link</span>. I&#8217;ve written this into the HTML so that anyone without JavaScript enabled can still get to my photos, however, later on I&#8217;ll use JavaScript to remove it immediately so that visitors with JavaScript won&#8217;t see it. That aside, you have to place a container for your images and make sure you give it a unique ID so that later jQuery can quickly find it in the document. Next, create some markup for each of your images. This is completely dependent on how you want your Photo Wall to look. Mine looks like this:</p>
<div class="clear">
<pre class="brush: xml">
<div id="container">
<h1><a>DEMO: Use the Flickr API, JavaScript (jQuery), AJAX and JSON to Build a Photo Wall <span>by Kyle Rush</span></a></h1>

<a id="a-link" href="http://www.flickr.com/photos/kylerush/">Click Here to See My Flickr Photos</a>
<div id="tut-info" class="clearfix">
                <a>View Tutorial &gt;&gt;</a>
                <a>How to Use the Flickr API &gt;&gt;</a>
                <a href="http://www.kylerush.net">kylerush.net &gt;&gt;</a></div>

<!--#tut-info-->

<!--#image-container--></div>

<!--#container--></pre>
</div>
<p><!--/.clear--></p>
<p>The CSS is fairly self explanatory. I floated the &#8216;image-container&#8217; class to the left since I want all the photos to display in rows of three. I&#8217;m letting the browser wrap them within the container. Next, I just applied some styling to suit my taste:</p>
<div class="clear">
<pre class="brush: css">body, html {background: #000; font-size: 12px;}
#container {width: 810px; margin: 0 auto 0 auto;}
#notice {color: #fff; font-weight: bold; font-size: 15px; font-style: italic;}
h1 {font-size: 38px; line-height: 45px;}
h1 span {font-size: 16px; color: #ff0084;}
h1 a:hover span {color: #fff;}
#tut-info {width: 810px; margin: 0 0 20px 0;}
#tut-info a {float: left; display: block; background: #fff; font-size: 20px; padding: 20px 20px; font-weight: bold; margin: 0 15px 0 0;}
#tut-info a:hover {background: #ff0084;}
#loader {margin: 20px 0 40px 350px;}
.image-container {height: 180px; width: 240px; position: relative; float: left; margin: 0 20px 20px 0; background-color: #666; border: 5px solid #fff; overflow: hidden;}
.image-info {display: none;}
.image-info-active {height: 180px; width: 240px; background: rgba(255,255,255,.85);}
a {cursor: pointer; text-decoration: none; color: #0063dc;}
a:hover {color: #fff; background: #0063dc;}
a.title {color: #ff0084;}
a.title:hover {color: #fff; background: #ff0084;}
.bottom {padding: 5px;}
.bottom p {margin: 0 0 5px 0; }
p.top {background: #fff; width: 240px; padding: 0 0 5px 0; margin: 0;}
a.title {font-size: 20px; font-weight: bold; display: block; line-height: 20px;}
span.author {font-size: 10px;}
.infoTitle {font-weight: bold;}
.clearfix:after { content:"."; display:block; height:0; clear:both; visibility:hidden; }
.clearfix {display:inline-block;}
.clearfix {display:block;}</pre>
</div>
<p><!--/.clear--></p>
<h2>Starting the jQuery and the Initial Ajax Request</h2>
<p>In the code below, line 1 starts the doc ready function of jQuery. This is the same as using <span class="code">document.ready</span>. Immediately after, I remove the accessibility link (#a-link). Then, I append a &#8216;loading&#8217; image into the <span class="code">#image-container</span> element so that if the user has a slow connection or Flickr is taking a while to respond, he/she will know that the JavaScript is actually running. <a href="http://www.ajaxload.info/">Ajaxload</a> is a very easy to use online app that will generate an animated loading gif images. On line seven, I set my Flickr API key equal to the variable <span class="code">apiKey</span>. Since I&#8217;ll be using my API key in several parts of this script, it&#8217;s easier to have it stored in one place in case I need to change it. Line 11 starts the Ajax request to Flickr. To send the request, I&#8217;ve used jQuery&#8217;s <a href="http://docs.jquery.com/Ajax/jQuery.getJSON">getJSON</a> method. This method allows for cross-domain Ajax calls, meaning that you can request data from a different domain than that of which the script is running. Ajax is not inherently cross-domain and takes some hacking to do so, but jQuery makes it easy for us.</p>
<p>Notice the URL for the Ajax request. Instead of providing my API key, I have just referenced the variable that holds my API key that I created earlier. I do this by using the <span class="code">+</span> operator to concatenate the variable into the string. So the <span class="code">&#8216;</span> (apostrophe) character at the beginning of the URL starts the string and it then ends after <span class="code">&amp;apiKey=</span>. The plus sign concatenates the variable into the string and then we add another string after the <span class="code">apiKey</span> variable. After JavaScript processes that statement, it will look like <span class="code">http://api.flickr.com/services/rest/?&amp;method=flickr.people.getPublicPhotos&amp;api_key=[YOUR API KEY]&amp;user_id=29096781@N02&amp;per_page=12&amp;page=4&amp;format=json&amp;jsoncallback=?</span> where <strong>[YOUR API KEY]</strong> is the value of the apiKey variable/your Flickr API key.</p>
<div class="clear">
<pre class="brush: jscript">$(function(){
    jQuery('#a-link').remove();   

    jQuery('<img alt="" />').attr('id', 'loader').attr('src', 'ajax-loader.gif').appendTo('#image-container');

    //assign your api key equal to a variable
    var apiKey = '[YOUR API KEY]';

    //the initial json request to flickr
    //to get your latest public photos, use this request: http://api.flickr.com/services/rest/?&amp;method=flickr.people.getPublicPhotos&amp;api_key=' + apiKey + '&amp;user_id=29096781@N02&amp;per_page=15&amp;page=2&amp;format=json&amp;jsoncallback=?
	$.getJSON('http://api.flickr.com/services/rest/?&amp;method=flickr.photosets.getPhotos&amp;api_key=' + apiKey + '&amp;photoset_id=72157619415192530&amp;format=json&amp;jsoncallback=?',</pre>
</div>
<p><!--/.clear--></p>
<h2>Understanding JSON</h2>
<p>Flickr responses in JSON format are not very readable in order to save space. So a typical response of the <a href="http://www.flickr.com/services/api/flickr.people.getPublicPhotos.html"><span class="code">flickr.people.getPublicPhotos</span></a> method is: <span class="code">jsonFlickrApi({&#8220;photos&#8221;:{&#8220;page&#8221;:4, &#8220;pages&#8221;:52, &#8220;perpage&#8221;:3, &#8220;total&#8221;:&#8221;154&#8243;, &#8220;photo&#8221;:[{"id":"3606437738", "owner":"29096781@N02", "secret":"7a02f95b14", "server":"2480", "farm":3, "title":"Water Fountain Closeup", "ispublic":1, "isfriend":0, "isfamily":0}, {"id":"3605617857", "owner":"29096781@N02", "secret":"2f9da1d270", "server":"3385", "farm":4, "title":"Water Fountain Closeup", "ispublic":1, "isfriend":0, "isfamily":0}, {"id":"3605617773", "owner":"29096781@N02", "secret":"bf1c89212e", "server":"2463", "farm":3, "title":"Water Fountain Closeup", "ispublic":1, "isfriend":0, "isfamily":0}]}, &#8220;stat&#8221;:&#8221;ok&#8221;})</span>. I have limited this request to three photos for brevity using the <span class="code">&amp;per_page=3</span> argument. For something more readable, I copied that code and pasted it into the online <a href="http://jsbeautifier.org/">JavaScript Beautifier</a>. The result is below.</p>
<div class="clear">
<pre class="brush: jscript">jsonFlickrApi({
    "photos": {
        "page": 4,
        "pages": 52,
        "perpage": 3,
        "total": "154",
        "photo": [{
            "id": "3606437738",
            "owner": "29096781@N02",
            "secret": "7a02f95b14",
            "server": "2480",
            "farm": 3,
            "title": "Water Fountain Closeup",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
        },
        {
            "id": "3605617857",
            "owner": "29096781@N02",
            "secret": "2f9da1d270",
            "server": "3385",
            "farm": 4,
            "title": "Water Fountain Closeup",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
        },
        {
            "id": "3605617773",
            "owner": "29096781@N02",
            "secret": "bf1c89212e",
            "server": "2463",
            "farm": 3,
            "title": "Water Fountain Closeup",
            "ispublic": 1,
            "isfriend": 0,
            "isfamily": 0
        }]
    },
    "stat": "ok"
})</pre>
</div>
<p><!--/.clear--></p>
<p>To access data in the array, we just follow the simple structure. If you imagine that the entire array is called, say &#8216;data&#8217;, then <span class="code">data.photos.pages</span> would return the value <span class="code">52</span>. In this tutorial, we&#8217;re not interested in how many pages of images are available, so <span class="code">data.photos.photo.title[0]</span> (JavaScript starts its numbers at 0 instead of 1) would return <strong>&#8220;Water Fountain Closeup&#8221;</strong> for the first image. Since we know we&#8217;ll have more than one image, but we don&#8217;t necessarily know how many, we can create a loop that will pull the data we need for each photo that exists. That will be covered next.</p>
<h2>Getting Basic Information and the Geo Location of Each Photo</h2>
<p>Line 1 continues the jQuery JSON request and instructs jQuery to run the code within the function when the data is received. Line 4 in the following code starts jQuery&#8217;s <a href="http://docs.jquery.com/Utilities/jQuery.each">.each()</a> method, which is arguably an easier way to write a for loop. This loop will carry out a function through each of the items (photos) that Flickr sent. On line 7 I created a string variable that contains a URL for the image on which the loop is currently on (information on how the URL is build can be <a href="http://kylerush.net/flickr/flickr-api#working-with-the-data">found here</a> or on the <a href="http://www.flickr.com/services/api/misc.urls.html">Flickr API URL info page</a>). Notice how and where I place the data from Flickr&#8217;s JSON response. I will later use this variable as the value of the <span class="code">href</span> parameter of the anchor linking back to the image. After that, on line 10, I turn the photo&#8217;s ID into a variable as I will be using this several times.</p>
<p>We have pretty much all the basic information on the photo from our first Ajax request, but if you look carefully you can see that the geo location is not provided. To get this, we start another Ajax request on line 13 using the Flickr API&#8217;s <a href="http://www.flickr.com/services/api/flickr.photos.geo.getLocation.html">flickr.photos.geo.getLocation</a> method. We already have required arguments, so look carefully how I placed them into the URL. On line 14 I tell jQuery to run a function as soon as the data is received. On line 13 I use a conditional statement to see if my request was a failure. I do this because not all photos on Flickr have a geo location and if they don&#8217;t, Flickr will respond with failed request details. Here is the response Flickr will give if one of the pictures I request has no geo location: <span class="code">jsonFlickrApi({&#8220;stat&#8221;:&#8221;fail&#8221;, &#8220;code&#8221;:2, &#8220;message&#8221;:&#8221;Photo has no location information.&#8221;})</span>. If <span class="code">data.stat</span> is ever in the response then the request has failed. So, the conditional statement on line 17 tells JavaScript that if <span class="code">data.stat</span> does not exist, continue with the following code. In the following code on line 18, I create a variable called <span class="code">pLocation</span> (the keyword <span class="code">location</span> is reserved in JavaScript) that contains a string of HTML combined with the latitude and longitude from the request. In the HTML of this, I have included a link to the Flickr map where the image was taken because we have latitude/longitude data. You may have noticed that earlier I use the <span class="code">var</span> keyword to declare the <span class="code">apiKey</span> variable while this time I did not. In JavaScript, variables declared with the <span class="code">var</span> keyword are <strong>local</strong> variables that live inside the function in which they were created. Variables declared without <span class="code">var</span> are global and can be accessed outside the function in which they were created. I decided to make <span class="code">pLocation</span> a global variable because I will need to access it outside of the function I created it later on in the code. When possible, you should always use local variables as global variables can interfere with each other and cause you some headaches. At the end of first the loop I will delete this global variable so that it doesn&#8217;t cause problems when the loop moves to the next image.</p>
<div class="wp-caption alignnone" style="width: 640px"><img title="Each Image Will Link to Its Latitude and Longitude on the Flickr Map" src="/images/flickr-tutorial/flickr-map.jpg" alt="Each Image Will Link to Its Latitude and Longitude on the Flickr Map" width="630" height="200" /><p class="wp-caption-text">Each Image Will Link to It&#39;s Latitude and Longitude on the Flickr Map</p></div>
<div class="clear">
<pre class="brush: jscript">function(data){

    //loop through the results with the following function
    $.each(data.photoset.photo, function(i,item){

        //build the url of the photo in order to link to it
        var photoURL = 'http://farm' + item.farm + '.static.flickr.com/' + item.server + '/' + item.id + '_' + item.secret + '_m.jpg'

        //turn the photo id into a variable
        var photoID = item.id;

        //use another ajax request to get the geo location data for the image
        $.getJSON('http://api.flickr.com/services/rest/?&amp;method=flickr.photos.geo.getLocation&amp;api_key=' + apiKey + '&amp;photo_id=' + photoID + '&amp;format=json&amp;jsoncallback=?',
        function(data){

            //if the image has a location, build an html snippet containing the data
            if(data.stat != 'fail') {
                pLocation = '<a href="http://www.flickr.com/map?fLat=' + data.photo.location.latitude + '&amp;fLon=' + data.photo.location.longitude + '&amp;zl=1" target="_blank">' + data.photo.location.locality._content + ', ' + data.photo.location.region._content + ' (Click for Map)</a>';
            }
        });</pre>
</div>
<p><!--/.clear--></p>
<h2>Getting the Flickr Tags of the Images</h2>
<p>Line 2 in the following code starts another Ajax request similar to the one that I used to get the geo location. The only difference is the URL. When the request is complete, I used a conditional statement on line 6 that searches the response data to see if there are any tags. In JavaScript, this is known <span class="code">!=</span> as an <strong>is not</strong> operator. It is the opposite of <span class="code">==</span>. So, if <span class="code">data.photo.tags.tag</span> is not empty (specified by empty apostrophes: <span class="code">&#8221;</span>), then run the following code.</p>
<p>I chose to hold each tag in an <a href="http://www.w3schools.com/JS/js_obj_array.asp">Array</a>. To do this, I set the variable <span class="code">tagsArr</span> equal to a new array. On line 12 I start a new for each loop to loop through each tag since they are grouped separately. The only thing different on this loop is that I use <span class="code">j</span> instead of <span class="code">i</span> so as to not have any confusion with the geo code loop which uses the variable <span class="code">i</span>. Next, on line 15, I add some HTML that contains the tag data to the <span class="code">tagsArr</span> array using JavaScript&#8217;s <a href="http://www.w3schools.com/jsref/jsref_push.asp">.push()</a> method. When that loop is finished going through the tags, I use the <a href="http://www.w3schools.com/jsref/jsref_join.asp">.join()</a> method on line 20 to combine all the tags in the array into a string that will be easier to use later. I created a new variable <span class="code">tags</span> and set it to a value of the tags.</p>
<div class="clear">
<pre class="brush: jscript">//use another ajax request to get the tags of the image
$.getJSON('http://api.flickr.com/services/rest/?&amp;method=flickr.photos.getInfo&amp;api_key=' + apiKey + '&amp;photo_id=' + photoID + '&amp;format=json&amp;jsoncallback=?',
    function(data){

        //if the image has tags
        if(data.photo.tags.tag != '') {

        //create an empty array to contain all the tags
        var tagsArr = new Array();

        //for each tag, run this function
        $.each(data.photo.tags.tag, function(j, item){

            //push each tag into the empty 'tagsArr' created above
            tagsArr.push('<a href="http://www.flickr.com/photos/tags/' + item._content + '">' + item.raw + '</a>');

            });

            //turn the tags array into a string variable
            var tags = tagsArr.join(', ');
        }</pre>
</div>
<p><!--/.clear--></p>
<h2>Preparing the Variable to Append to the Document</h2>
<p>Now that we have prepared all of our data in nice little variables that we can use, we need to combine it all into one variable that we can easily insert into the DOM. On line 2 I create this variable and give it a value of some HTML interlaced with some of the data from the request received. On line 5, I use a conditional statement to see if the <span class="code">tags</span> variable exists. It will only exist if there were tags in our data because if there weren&#8217;t, our previous conditional statement wouldn&#8217;t have run the code that created the variable in the first place. Returning the <span class="code">typeof</span> of a variable will tell you what kind of variable it is. If the <span class="code">typeof</span> is undefined, then the variable doesn&#8217;t exist. On line 8, I use the <span class="code">+=</span> operator to concatenate a string onto the previously created <span class="code">imgCont</span> variable.</p>
<p>On line 12, I do the exact same thing with the geo location data as I did with the tags on line 5. I add the description of the image to the <span class="code">imgCont</span> variable on line 19. Now that the <span class="code">imgCont</span> variable contains all the data I want it to, I use jQuery&#8217;s <a href="http://docs.jquery.com/Manipulation/appendTo">appendTo()</a> method to insert the picture and all its data into the <span class="code">#image-container</span> div in the HTML. Directly after that I delete the global variable <span class="code">pLocation</span> so that it doesn&#8217;t repeat in the next loop because that will be a different image.</p>
<div class="clear">
<pre class="brush: jscript">//create an imgCont string variable which will hold all the link location, title, author link, and author name into a text string
var imgCont = '
<div class="image-container" style="background: url(' + photoURL + ');">
<div class="image-info">

<a class="title" href="http://www.flickr.com/photos/' + data.photo.owner.nsid + '/' + photoID + '">' + data.photo.title._content + '</a> <span class="author">by <a href="http://flickr.com/photos/' + data.photo.owner.nsid + '">' + data.photo.owner.username + '</a></span>
<div class="bottom">

<span class="infoTitle">Comments:</span> ' + data.photo.comments._content + '

';

//if there are tags associated with the image
if (typeof(tags) != 'undefined') {

    //combine the tags with an html snippet and add them to the end of the 'imgCont' variable
    imgCont += '

<span class="infoTitle">Tags:</span> ' + tags + '

';
}

//if the image has geo location information associate with it
if(typeof(pLocation) != 'undefined'){

    //combine the geo location data into an html snippet and at that to the end fo the 'imgCont' variable
    imgCont += '

<span class="infoTitle">Location:</span> ' + pLocation + '

';
}

//add the description &amp; html snippet to the end of the 'imgCont' variable
imgCont += '

<span class="infoTitle">Decription:</span> ' + data.photo.description._content + '</div>
</div>

';

//append the 'imgCont' variable to the document
$(imgCont).appendTo('#image-container');

//delete the pLocation global variable so that it does not repeat
delete pLocation;
});

});
});</div>
</pre>
</div>
<p><!--/.clear--></p>
<h2>Adding the Rollover Effect and Removing the Loading Image</h2>
<div class="wp-caption alignnone" style="width: 640px"><img title="An Image which Reveals Information on Mouseover" src="/images/flickr-tutorial/mouseover.jpg" alt="An Image which Reveals Information on Mouseover" width="630" height="200" /><p class="wp-caption-text">An Image which Reveals Information on Mouseover</p></div>
<p>In the following code, I use jQuery&#8217;s <a href="http://docs.jquery.com/Events/live">.live()</a> method to apply a function when our images are either rolled over or rolled off of. In this situation I have to use <span class="code">.live()</span> instead of <span class="code">.hover()</span> because I need the rollover to apply to elements inserted into the DOM after the DOM was loaded. <span class="code">.live()</span> is an awesome method that will apply a function to all elements that match the selector no matter when they are added to the DOM. To create the rollover, I just change the class of the image container to a class that&#8217;s <span class="code">display</span> property is not <span class="code">none</span>. Line 5 just reverses this previous function when the mouse hovers off the image. The last thing is to remove the loader image since everything is done. Although all images may not have been loaded, everything has been added to the document. We could create a function that checks to see if the last image was loaded and then to remove the loader image, but this tutorial is already quite long.</p>
<div class="clear">
<pre class="brush: jscript">//assign hover actions to each image
$('.image-container').live('mouseover', function(){
    $(this).children('div').attr('class', 'image-info-active');
});
$('.image-container').live('mouseout', function(){
    $(this).children('div').attr('class', 'image-info');
});

jQuery('#loader').remove();

});</pre>
</div>
<p><!--/.clear--></p>
<h2>Conclusion</h2>
<p>Congratulations on building a dynamic Flickr photo wall. I know it was a long tutorial, but I wanted to provide as much information as possible. Was the tutorial helpful for you? See anything that should be changed? Want to see more tutorials like this? Let me know in the comments!</p>
<p><script type="text/javascript" src="http://kylerush.org/kr/syntax-highlighter/scripts/syntax-highlighter-all.js"></script></p>
<link type="text/css" rel="stylesheet" href="http://kylerush.org/kr/syntax-highlighter/styles/shCore.css"/>
<link type="text/css" rel="stylesheet" href="http://kylerush.org/kr/syntax-highlighter/styles/shThemeDefault.css"/>
<script type="text/javascript">// <![CDATA[
		SyntaxHighlighter.config.clipboardSwf = 'http://kylerush.org/kr/syntax-highlighter/scripts/clipboard.swf';
		SyntaxHighlighter.all();
// ]]&gt;</script></p>
]]></content:encoded>
			<wfw:commentRss>http://kylerush.net/javascript/tutorial-flickr-api-javascript-jquery-ajax-json-build-detailed-photo-wall/feed/</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
	</channel>
</rss>

