Search for photos using JQuery, Flickr API and Fancybox part 2

Like we discussed on the first part of this tutorial the next step it’s to create the JavaScript that dose the request, retrieves the data and remembers it.

Here is the demo.

What we have achieved so far?
We build the entire HTML structure and we made the layout looking a little better. Of course is not very grate but you can design it the way you need it.

The JavaScript code:

function searchPics(yourKeywords) {
 $.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
 {
  lang    : 'en-us',
  tags    : yourKeywords,
  tagmode : 'all',
  limit   : '20',
  format  : 'json'
 },
 function(data){
  var imgInsert = "";
  var items = [];
 
  //create the element that holds the images
  $('<div />', {
    'id': 'content',
    html: items.join('')
  }).appendTo('#wrapper').insertAfter('#left_sidebar');
 
  /* each image loaded from flickr will have a div as parent then the main parent
  will apend to the wrapper */
  $.each(data.items, function(i,item){
    if (i == 20) return false;
      var imgThumb = item.media.m.split('m.jpg')[0] + 'm.jpg'; //size of the image small max 240px
      var imgLarge = item.media.m.split('m.jpg')[0] + 'b.jpg'; //large size of the image for fancybox
      imgInsert += '<div class="avatar">';
      imgInsert += '<a href="' + imgLarge + '" rel="flickr_group" class="big_img" title="' + item.title + '">';
      imgInsert += '<img title="' + item.title + '" src="' + imgThumb + '" alt="' + item.title + '" />';
      imgInsert += '</a></div>';
   });
   var cachedItems = $(imgInsert).data('cached', imgInsert);
   $('#content').append(imgInsert).addClass(yourKeywords).data('cached', data.items);
   /* create a history list and insert it into the left sidebar */
   var listChached = '';
   listChached += '<div class="history_list">';
   listChached += '<a class="' + yourKeywords + '_chached" href="javascript:;">';
   listChached +=  yourKeywords + '</a></div>';
 
   $(listChached).appendTo('#left_sidebar').insertAfter('form');
 
   $('.' + yourKeywords + '_chached').click(function(){
 
    /* if the content has items then remove them
	and insert the chathed itmes */
    if ( $('#content').length > 0 ) {  
      $('#content').empty();
	$('#content').html(cachedItems);
 
	 //open the images using fancybox for the cached images
	 $("a[rel=flickr_group]").fancybox({
	   'transitionIn': 'none',
	   'transitionOut': 'none',
	   'titlePosition': 'over',
	   'titleFormat': function (title, currentArray, currentIndex, currentOpts) {
	     return '<span id="fancybox-title-over">Image ' + (currentIndex + 1) + ' / ' + currentArray.length + (title.length ? ' &nbsp; ' + title : '') + '</span>';
	    }
	 });                             
      }                        
   })
 
   //open the images using fancybox for the new search
   $("a[rel=flickr_group]").fancybox({
     'transitionIn': 'none', 
     'transitionOut': 'none',
     'titlePosition': 'over',
     'titleFormat': function (title, currentArray, currentIndex, currentOpts) {
	return '<span id="fancybox-title-over">Image ' + (currentIndex + 1) + ' / ' + currentArray.length + (title.length ? ' &nbsp; ' + title : '') + '</span>';
     }
    });                
  });
}
 
$(function(){
 $('.search_form').submit(function(){
  //if it has been a search allready remove the old content and replace it with the new search
  if ( $('#content').length > 0 ) {
  	$('#content').remove();
  }                        
  searchPics(document.getElementById('keywords').value );
  return false;
 })
})

Now let’s break down the code piece by piece.

First he main function searchPics:

$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
 lang    : 'en-us',
 tags    : yourKeywords,
 tagmode : 'all',
 limit   : '20',
 format  : 'json'
},

What I did in this part: I gave to JSON a link to Flickr to retrieve public photos. Afterwards I have specify the language. Tags represents the keywords the user enters into our input text. Then I limit the search to 20 results and told the Flickr that I use the JSON format. It’s not that hard. Here you can find the full documentation of the api.

I haven’t used any user id or key api because I don’t need them to search to a specific user photos. But you can do that by simply specify the user id or the key api which you can gate it from here.

Example:

$.getJSON("http://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?",
{
 id      : '[here you can insert a user id]',
 lang    : 'en-us',
 tags    : yourKeywords,
 tagmode : 'all',
 limit   : '20',
 format  : 'json'
},

Normally Flickr returns an xml format of the request, but if you specify that your request is JSON format it will look like this:

{
"foo": {
 "bar": "baz",
 "woo": {
  "yay": "hoopla"
  }
 }
}

I hope you did understand a little bit of the code above if not please free to comment and I’ll try to explain in more details.

Next step: create the HTML elements

function(data){
  var imgInsert = "";
  var items = [];
 
  //create the element that holds the images
  $('<div />', {
    'id': 'content',
    html: items.join('')
  }).appendTo('#wrapper').insertAfter('#left_sidebar');
 
  /* each image loaded from flickr will have a div as parent then the main parent
  will apend to the wrapper */
  $.each(data.items, function(i,item){
    if (i == 20) return false;
      var imgThumb = item.media.m.split('m.jpg')[0] + 'm.jpg'; //size of the image small max 240px
      var imgLarge = item.media.m.split('m.jpg')[0] + 'b.jpg'; //large size of the image for fancybox
      imgInsert += '<div class="avatar">';
      imgInsert += '<a href="' + imgLarge + '" rel="flickr_group" class="big_img" title="' + item.title + '">';
      imgInsert += '<img title="' + item.title + '" src="' + imgThumb + '" alt="' + item.title + '" />';
      imgInsert += '</a></div>';
   });
   var cachedItems = $(imgInsert).data('cached', imgInsert);
   $('#content').append(imgInsert).addClass(yourKeywords).data('cached', data.items);
   /* create a history list and insert it into the left sidebar */
   var listChached = '';
   listChached += '<div class="history_list">';
   listChached += '<a class="' + yourKeywords + '_chached" href="javascript:;">';
   listChached +=  yourKeywords + '</a></div>';
 
   $(listChached).appendTo('#left_sidebar').insertAfter('form');
 
   $('.' + yourKeywords + '_chached').click(function(){
 
    /* if the content has items then remove them
	and insert the chathed itmes */
    if ( $('#content').length > 0 ) {  
      $('#content').empty();
	$('#content').html(cachedItems);
 
	 //open the images using fancybox for the cached images
	 $("a[rel=flickr_group]").fancybox({
	   'transitionIn': 'none',
	   'transitionOut': 'none',
	   'titlePosition': 'over',
	   'titleFormat': function (title, currentArray, currentIndex, currentOpts) {
	     return '<span id="fancybox-title-over">Image ' + (currentIndex + 1) + ' / ' + currentArray.length + (title.length ? ' &nbsp; ' + title : '') + '</span>';
	    }
	 });                             
      }                        
   })

imgInsert variable it’s empty so I can use it later. items it’s an array that will be populated with the data I will received from Flickr.
Furthermore I have created an element with the id content:

$('<div />', {
 'id': 'content',
 html: items.join('')
 ).appendTo('#wrapper').insertAfter('#left_sidebar');

The HTML that will be inserted into this div it will be our variable called items then used the join() method which joins all elements of an array into a string, and returns the string, then append it to our main wrapper and inserted after the left_sidebar because it will float:left.

$.each(data.items, function(i,item){
 if (i == 20) return false;
   var imgThumb = item.media.m.split('m.jpg')[0] + 'm.jpg'; //size of the image small max 240px
   var imgLarge = item.media.m.split('m.jpg')[0] + 'b.jpg'; //large size of the image for fancybox
 
   imgInsert += '<div class="avatar">';
   imgInsert += '<a href="' + imgLarge + '" rel="flickr_group" class="big_img" title="' + item.title + '">';
   imgInsert += '<img title="' + item.title + '" src="' + imgThumb + '" alt="' + item.title + '" />';
   imgInsert += '</a></div>';
  });
  var cachedItems = $(imgInsert).data('cached', imgInsert);

Each item found on Flickr it will be inserted into a holder. But first thing first.
As you can see I added an condition if there are 20 results then the script can go further. You probably wonder what item.media.m.split('m.jpg')[0] + 'm.jpg'; does. Well when you send a request to Flickr default the api will return the photos in m format which means the medium format 240px. Here is a full documentation of the images size that you can take from Flickr.

Now that we have our images size 240px this it will be the thumbnail size and b it will be for the Fancybox big image.

imgInsert += '<div class="avatar">';
imgInsert += '<a href="' + imgLarge + '" rel="flickr_group" class="big_img" title="' + item.title + '">';
imgInsert += '<img title="' + item.title + '" src="' + imgThumb + '" alt="' + item.title + '" />';
imgInsert += '</a></div>'

This is the part where we create the image holder with the class avatar for each item that we receive from our Flickr call. In the href attr we specify the link for the big image. The rel flickr_group it will be used to open the images with Fancybox. The src attribute of the image is the link to our m image the small one.

var cachedItems = $(imgInsert).data('cached', imgInsert);
 $('#content').append(imgInsert).addClass(yourKeywords).data('cached', data.items);

In the variable cachedItems I have stored all the content that I have received from the request. That means that all 20 photos including the div's are going to be stored using data which store arbitrary data associated with the specified element. Returns the value that was set.

Once we have the main content, the boxes and the images we have to create the left side links with them we will access the images stored again without doing another Flickr request.

var listChached = '';
listChached += '<div class="history_list">';
listChached += '<a class="' + yourKeywords + '_chached" href="javascript:;">';
listChached +=  yourKeywords + '</a></div>';
 $(listChached).appendTo('#left_sidebar').insertAfter('form');

In this step I have created an element with the class history_list. Which I styled in the part 1 of this tutorial. Then created an a tag with the keyword as class name. Once created each search will be inserted in the left_sidebar after the form.

 $('.' + yourKeywords + '_chached').click(function(){
   if ( $('#content').length > 0 ) {  
     $('#content').empty();
     $('#content').html(cachedItems);
     $("a[rel=flickr_group]").fancybox({
       'transitionIn': 'none',
       'transitionOut': 'none',
       'titlePosition': 'over',
       'titleFormat': function (title, currentArray, currentIndex, currentOpts) {
         return '<span id="fancybox-title-over">Image ' + (currentIndex + 1) + ' / ' + currentArray.length + (title.length ? ' &nbsp; ' + title : '') + '</span>';
       }
     });                             
   }                        
})

The class created above in the a tag we will use it. That on click check’s if the content has a content longer then 0 that means we have to remove those boxes and replace it with our previous stored data. We do this by calling the empty JQuery function. This will remove all the elements from our content.
Furthermore our content we will populate it with cachedItems variable which if you remember stored the received content right?
Finally we call the Fancybox function to open the images in a popup. Here you can find the methods for fancybox.
Our Fancybox will return the image title, number of photos etc.

Finally we call the function:

$(function(){
 $('.search_form').submit(function(){
  if ( $('#content').length > 0 ) {
    $('#content').remove();
  }                        
  searchPics(document.getElementById('keywords').value );
  return false;
 })
})

I used on DOM ready but you can remove that because the function it’s not called on DOM ready but on form submit.
Here we still do an final check to see if the content has any items inside, if it does we remove them it using remove function from JQuery.
After this we just call our function searchPics() in which I used the JavaScript document.getElementById and retrieve the value of the input text.
The return false is used so that the page wont refresh after we submit the form.

That’s a wrap folks. Please tell me your opinions, if you liked, if is helpful or has any bugs etc. Feel free to comment.

Here is the standalone page.

3 thoughts on “Search for photos using JQuery, Flickr API and Fancybox part 2

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.