0

I’m making a site using FreeWall and I’m having trouble when I use the appendBlock method to add new blocks to the wall. When I add new blocks, I get the same blocks that I already have again.

Here is my code (JavaScript):

// Populate grid with initail images.
// This is going to get the first 10 images (1.jpg → 10.jpg)
// and add them to the grid for the initial page setup.
// This is working fine.

var temp = "<div class='fwbrick' style='width:{width}px;'><a href='#' data-reveal-id='modal-{modal}'><img src='http://yamsandwich.com/img/profile/{index}.jpg' width='100%'></a></div>";
var w = 1,
  h = 1,
  html = '',
  limitItem = 10;
for (var i = 0; i < limitItem; ++i) {
  w = 1 + 3 * Math.random() << 0;
  html += temp.replace(/\{width\}/g, w * 150).replace("{modal}", i + 1).replace("{index}", i + 1);
}

// create add more button
$(".add-more").click(function() {
  var temp = "<div class='fwbrick' style='width:{width}px;'><a href='#' data-reveal-id='modal-{modal}'><img src='http://yamsandwich.com/img/profile/{index}.jpg' width='100%'></a></div>";
  var w = 1,
    h = 1,
    html = '',
    limitItem = 10;

  // The problem is right here. 
  // I don’t know how to tell it to find images 11 to 20 or X to Y.
  // Right now, it just repeats the first 10. 
  // Even when I set `i` to `10` to start, I still just get images 1 – 10 over again.

  for (var i = 1; i < limitItem; ++i) {
    w = 1 + 3 * Math.random() << 0;
    html += temp.replace(/\{width\}/g, w * 150).replace("{modal}", i + 1).replace("{index}", i + 1);
  }

  wall.appendBlock(html);

});

// target the div for the wall
$("#freewall").html(html);

// create the walls structure
var wall = new Freewall("#freewall");
wall.reset({
  selector: '.fwbrick',
  animate: true,
  cellW: 150,
  cellH: 'auto',
  onResize: function() {
    wall.fitWidth();
  }
});

// load the images into the wall
var images = wall.container.find('.fwbrick');
images.find('img').load(function() {
  wall.fitWidth();
});

So what I would like to know is, how to get the counter in the add-more function to get the next 10 blocks in the sequence.

See it in action at the link in the first sentence or if you missed that, click here.

Sebastian Simon
  • 18,263
  • 7
  • 55
  • 75
user12920
  • 301
  • 3
  • 11

2 Answers2

1

UPDATED

I found here a way to check if the image actually exists before create the html. Replace the code i mentioned before by:

var initial = 0; //Current image
var increment = 10; //total of images each time someone hits the button (and the initial images on the page)

function imageExists(image_url){
    var http = new XMLHttpRequest();
    http.open('HEAD', image_url, false);
    http.send();
    return http.status != 404;
}

function appendImageBlocks() {
    var temp = "<div class='fwbrick' style='width:{width}px;'><a href='#' data-reveal-id='modal-{modal}'><img src='http://yamsandwich.com/img/profile/{index}.jpg' width='100%'></a></div>";
    var w = 1, h = 1, html = '', limitItem = initial+increment;
    for (var i = initial; i < limitItem; ++i) {
console.log("http://yamsandwich.com/img/profile/"+(i+1)+".jpg");
        if(imageExists("http://yamsandwich.com/img/profile/"+(i+1)+".jpg")) {
            w = 1 + 3 * Math.random() << 0;
            html += temp.replace(/\{width\}/g, w*150).replace("{modal}", i + 1).replace("{index}", i + 1);
            initial++;
        } else {
            console.log("Image "+(i+1)+" not found");
            return "";
        };
    }
    return html;
}

$(".add-more").click(function() {
    html = appendImageBlocks();
    wall.appendBlock(html);
});

html = appendImageBlocks();

// target the div for the wall
//Rest of the code
Community
  • 1
  • 1
Clyff
  • 4,046
  • 2
  • 17
  • 32
  • but.. the first time you click the add more button you get the first 10 images again, but the second time you click it, you get the next to (11 to 20) and then after that you get the rest as expected. – user12920 Jul 28 '15 at 04:43
  • You sure? I can't see thats happening. But i'm becoming a litle worried about one thing. Does your js checks if you have the img file before append the html? – Clyff Jul 28 '15 at 04:49
  • Updated the answer so now we can check if the img exists ;) – Clyff Jul 28 '15 at 12:41
  • Ok it works good now. Thank you do much for your help. But let me ask you this, when it loads the next set of blocks, it doesnt lay the grid properly . I try to fix the width with fixWidth() but until you hit the button a second time then the grid shuffles everybody into place. – user12920 Jul 29 '15 at 02:37
  • Mmm i see. If you still having trouble with that, i plan to check this code later. I liked the plugin, probably i will use one day. (sorry the late response) – Clyff Jul 30 '15 at 15:37
0

You want your index and your limitItem to be cached each time add-more is called so that you know where to start off next time, so declare them both with the rest of your global variables

var temp = "<div class='fwbrick' style='width:{width}px;'><a href='#' data-reveal-id='modal-{modal}'><img src='http://yamsandwich.com/img/profile/{index}.jpg' width='100%'></a></div>";
var w = 1,
  h = 1,
  html = '',
  limitItem = 11,
  index = 1;

Then in your for loops don't reinitialize them since you want to use the last value of index that failed as the first value this time.

for ( ; index < limitItem; ++index) {
  w = 1 + 3 * Math.random() << 0;
  html += temp.replace(/\{width\}/g, w * 150).replace("{modal}", index).replace("{index}", index);
}

notice there are no plus ones since index started at one and limitItem is 11. Then inside your add-more function do not set limitItem with the keyword var to 10 but increment it by ten. If you use var you are creating a variable local to the function that won't affect the global variable. You could probably even skip redeclaring the w,h and html vars too.

html = '';
limitItem+=10; //limit Item is 21 after first call and 31 after second ect...

Then just reuse the same for loop inside the function. The first call to addmore index will start off at 11 and limitItem will be 21 and you should get images 11 to 20

Better yet use a closure to encapsulate this all and use the returned function to both prepopulate and addmore images

var addTen = (function(){
  //cached variables
  var index = 1,
      limitItem = 1,
      temp = "<div class='fwbrick' style='width:{width}px;'><a href='#' data-reveal-id='modal-{modal}'><img src='http://yamsandwich.com/img/profile/{index}.jpg' width='100%'></a></div>";
  return function(){
    var html='',
        w=1,
        h=1;
    limitItem+=10;
    for ( ; index < limitItem; ++index) {
      w = 1 + 3 * Math.random() << 0;
      html += temp.replace(/\{width\}/g, w * 150).replace("{modal}", index).replace("{index}", index);
    }
    wall.appendBlock(html);
  }
}());

$(".add-more").click(addTen);

var wall = new Freewall("#freewall");
addTen();

// rest of your code

This does however assume that appendblock and new Freewall functions work on an empty div.

Dean Brown
  • 156
  • 4