Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

JavaScript Use a Public API to Create a Gallery

Juliette Tworsey
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Juliette Tworsey
Front End Web Development Techdegree Graduate 32,425 Points

Unable to click to next and previous images in Flickr API gallery

Hi,

I am working on a project that requires me to pull some photos from Flickr that are to be displayed in my own gallery. The problem is that my previous and next functions are not iterating to the next and previous photos in the gallery. I have tried many different avenues and functions, but I am still coming up empty for a solution (though I feel like I am close).

Can anyone help? Thanks in advance:-)

Here is my repo: https://github.com/firebuggirl/publicapi3

..and here is my project as hosted on Github Pages:

https://firebuggirl.github.io/publicapi3/

4 Answers

Özgür Ozan Çakmak
Özgür Ozan Çakmak
11,451 Points

The problem is the statement used in the prevImage() and nextImage() functions

$(".selected").closest('li')

returns an empty array. Therefore the .closest("li") doesn't work and functions break.

Juliette Tworsey
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Juliette Tworsey
Front End Web Development Techdegree Graduate 32,425 Points

Thanks Özgür!

I have tried removed .closest('li') and the code still does not work. This is what I have currently:

function prevImage(){
  var $activeImg = $(".selected").removeClass('selected');

  var $imagePrev =$activeImg.prev('.flickerImage').addClass('selected').attr("src");



  $overlay.append($imagePrev);
  $imagePrev.show();
}
Özgür Ozan Çakmak
Özgür Ozan Çakmak
11,451 Points

Hm... seems I can't solve it. What plugin are you using here? Maybe its documentation might offer some help to us?

Juliette Tworsey
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Juliette Tworsey
Front End Web Development Techdegree Graduate 32,425 Points

I'm not actually using any plugin, though I am calling on the Flickr API to load the initial gallery (thumbnail) photos. Everything to do with the overlay is (and the API call) is happening in gallery.js.

I'm stumped too (obviously...lol)....

Özgür Ozan Çakmak
Özgür Ozan Çakmak
11,451 Points

Any development on the issue? If not can you write your pseudocode for me? Like what you were planning to do from the start step by step?

Juliette Tworsey
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Juliette Tworsey
Front End Web Development Techdegree Graduate 32,425 Points

Hi Özgür!

I'm trying to work on it now and still no luck.

What I have accomplished so far was to create two separate calls to the Flickr API, one to load the photos and one inside of a button/click event handler to sort through the photos by dog type/breed.

When I first started this project clicking on a thumbnail would lead to the default Flickr overlay/gallery. Now I have it so the photos appear in my own gallery (the current photo in the gallery has an added class of ".selected") one by one on click. What is happening now is that the right/left click functions are removing the class ".selected", but not moving to the next/prev photo(s) which then are supposed to have the class ".selected" added in order to click through to the next and previous photo(s).

This is what I have in gallery.js as of now:

$(document).ready(function() {

  var $overlay = $('<div id="overlay"></div>');
  var $closeLightbox = $("<div id='closeLightbox'></div>");
  var $poster = $('<div id="poster"></div>');
  var $infoDiv = $('<div id="infoDiv"></div>');
  var $p = $('<p id="posterText"></p>');
  var $p2 = $('<p id="posterText2"></p>');

  //Keep track of image index for prev/next, we will use a list index
  //position to determine where we are and what it means to move forward
  //and backwards by 1.

  var $index = 0;

  //Add image to overlay

  var $img = ('.flickrImage');

  $("body").append($overlay);

  $(".arrows").hide();//hide arrows div on page load
  $closeLightbox.hide();

  var saved_results = null;


// Pull photos from Flickr
var flickerAPI = "https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
var animal = $(this).text();

var flickrOptions = {
  tags: "german shepherd, border collie, black terrier",
  tagmode: "any",
  format: "json"
};
function displayPhotos(data) {
  var photoHTML = '<ul id="imageGallery">';
  var saved_results = data;
  var indexOfImage;
  $.each(data.items,function(i,photo) {
    if(i < 15){
    photoHTML += '<li class="layout">';
  // photoHTML += '<a href="" >';
  photoHTML += '<a href="' + photo.link + '" class="image">';
    //photoHTML += '<img src="' + photo.link + '" class="image">';
    photoHTML += '<img class="flickrImage" src="' + photo.media.m + '" photo_index ="' + i + '"></a></li>';
  }
  }); // end each
  photoHTML += '</ul>';
  $('.galleryDiv').html(photoHTML);
//Prevent flickr page/overlay load
  $('li').on('click', '.image', function(e) {
          e.preventDefault();
        });

  $("#imageGallery a .flickrImage").click(function (event) {
    //var selected =  $(this).addClass("selected").attr('src');
    var selected =  $('.image').addClass("selected").attr('src');

    var indexOfImage = parseInt($(this).attr('photo_index'));
      event.preventDefault();//prevent default browser behavior
      event.stopPropagation();//prevent bubbling

      $(this).unbind('click');
      $(".flickrImage").removeClass('selected');//removes class .selected on all images not currently selected

      $(this).addClass("selected").attr('src');// adds class .selected to image that is clicked
      //$overlay.append($(this));
      $overlay.append($poster).append($(this));

      $(this).show();
      $closeLightbox.show();
        $overlay.append($closeLightbox);

      $overlay.show();
      $overlay.append($poster);
      $poster.append($infoDiv);
      $infoDiv.append($p);
      $infoDiv.append($p2);
      $poster.show();

      var title = saved_results.items[indexOfImage].title;
      var date = saved_results.items[indexOfImage].date_taken;
      console.log(indexOfImage);
      $p.append(title);
      $p2.append(date);
      console.log(date);
      console.log(title);

     $(".arrows").show();
//Hide fixed scroll bar with z-index that was previously getting in the way of te close button
      $("#top").hide();

      $("#leftArrow").show();//show leftArrow in overlay

      $("#rightArrow").show();//show rightArrow in overlay




function prevImage(){
  var $activeImg = $(".selected");
  var $previous = $activeImg.closest('li').prev().find('a');

  var $captionText = $previous.addClass('selected').children("img").attr("alt");
  var $imagePrev = $previous.addClass('selected').attr("href");
  $activeImg.removeClass('selected');


}

function nextImage(){
  var $activeImg = $(".selected").removeClass('selected');//create location for current image selected by assigning .selected class (established above) to variable within function @ the local scope

 var $imageNext = $activeImg.find().next('.flickerImage').addClass('selected').attr("src");

//debugger;
$overlay.append($imageNext);
$overlay.show($imageNext);

}


$('#leftArrow').click(function(){
  prevImage();
});
$('#rightArrow').click(function(){
  nextImage();
});


});


  //When close button is clicked hide the overlay and arrows, re-introduce search box and remove video

  var $closeLightbox = $("<div id='closeLightbox'></div>");//create div for close button and style in css

  $overlay.before($closeLightbox);//tell DOM where close button fits in the DOM structure of the overlay

  $($closeLightbox).click(function () {
      $closeLightbox.hide();
      $overlay.hide();//close the overlay
      $("#top").show();//bring back search bar when overlay is hidden
      $('.selected').hide();
      $(".arrows").hide();
        location.reload();//reload page to prevent text/photos from being displayed more than once if/when overlay closed/re-opened


  });//end img/thumbnail click function/event
}//end callback for the api request
$.getJSON(flickerAPI, flickrOptions, displayPhotos);


// end of first API Request and JSON callback on initial page load
//
//
// Beginning of 2nd API request

$("button").click(function (event) {
    event.preventDefault();//
    //event.stopPropagation();
    // the AJAX part
    var flickerAPI = "https://api.flickr.com/services/feeds/photos_public.gne?jsoncallback=?";
    var animal = $(this).text();
    var flickrOptions = {
      tags: animal,
      format: "json"
    };

    $.getJSON(flickerAPI, flickrOptions, displayPhotos);


  });





}); //DOCUMENT.READY END

Thanks for checking back!

Özgür Ozan Çakmak
Özgür Ozan Çakmak
11,451 Points

A question first, why don't you use a lightbox plugin to do that? Secondly far as I can see this project has these steps and maybe we can write it from the scratch? What I imagined is thus:

// load up the flickr gallery
// for each image create an img and append it to the div
// when the image is clicked
    // load up the lightbox ( this actually involves a lot of steps which is beyond my mastery I am afraid)

I whipped up a script which is on my other machine so I can't share it at the moment. Also I checked back because I think this is an interesting problem.

Take care and happy coding!

Juliette Tworsey
seal-mask
.a{fill-rule:evenodd;}techdegree seal-36
Juliette Tworsey
Front End Web Development Techdegree Graduate 32,425 Points

I suppose that using a plugin would be an easier solution, though I already have taken all of the steps that you have mentioned (minus the glitch...lol..).

Thanks again:-)