views:

158

answers:

3

I'm a beginning coder, learned CSS, HTML, and Jquery in an internship this summer. My boss wants me to create a gallery that has one main image, and then two buttons to display the next or previous item. He wants me to use json, so that they can easily add and remove images. I have it written so that, I start with a variable 0, then when I click prev/next it decrements/increments the variable, and then goes back to the json to look for the corresponding picture. The only problem is that if I have four pictures, if the value goes below zero or above 3, it breaks.
How can I have the jquery tell if the json lookup returned undefined, so that I can have it either loop or disable the button? I suppose an if statement would be ideal, but I leave it to you.

$(document).ready(function(){
    $.getJSON("layout.json",function(data){

    // Then put the first picture up from the json data...
     $("<img />").attr({
      id: "0-middle_image", 
      class: "middle_image", 
      src: data.items[0].image ,
      })
     .appendTo("div#middle_image");

    // because I'm starting with the zeroth object, middleimage variable is 0
     var mi_val = 0 

    // when you click one of the cycle buttons...
     $("div.cycle_button").click(function(){
     //if it is the previous, decrement mi_val, else, increment mi_val
      if ( $(this).attr("id") == "button_prev") 
                         {--mi_val;}
      else {++mi_val;}
     //then, call the appropriate image object from the json
      $("img.middle_image").fadeOut(500,function(){
       $(this).attr({src: data.items[mi_val].image})
       .fadeIn(500);
       });
      });
     }); 
    });
+1  A: 

OK, I understand the problem now I think.

I would generalise the image-swapping code into a function that swaps out the current image given an index. I've called this function setImageWithIndex(). Then we can deal simply with what the index is in the .click() code.

This requires saving the data into another global, jsonData.

I would also save (a) the number of images returned in the JSON data and (b) the current image index (initially zero) in two global variables.

Here's the code. I've also removed some jquery and replaced it with standard javascript where it doesn't really add anything.

var imageCount;
var currentImage = 0;
var jsonData;

function setImageWithIndex(index) {
    $("img.middle_image").fadeOut(500, function() {
         $("img.middle_image")
            .attr({src: jsonData.items[index].image})
            .fadeIn(500);
    });
}

window.onload = function() {
    $.getJSON("layout.json", function(data) {
        jsonData = data;

        $("<img />").attr({
            id: "0-middle_image", 
            class: "middle_image", 
            src: data.items[0].image
        })
        .appendTo("div#middle_image");

        /* <PSEUDOCODE class="may not work"> */
        imageCount = data.items[0].length;
        // ie: save the number of images in a global variable
        /* </PSEUDOCODE> */
    }

    $("div.cycle_button").click(function() {
        if (this.id == "button_prev")
            if (currentImage > 0)
                setImageWithIndex(--currentImage);
        else
            if (currentImage < imageCount)
                setImageWithIndex(++currentImage);
    });
}
Benji XVI
Actually, that's backwards, Benji - If you declare a variable inside a function without var, it's global. If you use var it's local to the function.
Alex JL
You're damn right, and I'm a muppet. I've deleted the mistaken comment.
Benji XVI
A: 

You can use typeof to test for the return variables type:

$.getJSON("layout.json",function(data){
    // check for undefined return value
    if (typeof data == 'undefined') {
        // handle your undefined cases
    }
});
cballou
A: 

If I understand the problem correctly, then the dead-simplest solution would be to always use mi_val modulo the number of images you have. So, assuming that you always know imageCount (using Benji's variable) then you can just do

data.items[mi_val % imageCount].image

which will achieve a looping effect.

Matt Ball