I'm fairly new to JS and not very familiar with jQuery, but I'd like to give a shot at dynamically calling slimbox's multi-image function.
For example, there is a photoslider that randomly cycles through 3 images on my website, and I would like slimbox to show 2 more images for the first and 1 more for the last. This means slimbox will display a total of 6 images in the slideshow.
So in case you need it, here's the detailed walk through: when the user visits my site, the user will see a div block that shows 1 image at a time. The image in the photoslider will rotate out to the next one (of the 3 randomly loaded). When the user clicks on the image, the user will trigger the slimbox (lightweight lightbox) and a larger slideshow will take up the screen (dimming the background). Through slimbox, the user will see a up to a total of 6 images cycle through.
In order to create a dynamic variable, I tried to use EVAL within a FOR loop, but this fails when running jQuery. EVAL works outside of the loop, though. I'm not sure which other function to use instead. Let's dig into the code...
Calling slimbox via JS:
// usage as shown for multi-image slideshow. yes, there are arrays within an array
jQuery.slimbox([["image","desc"], ["image","desc"], ["image","desc"]], startAtImage);
// or simplified further
jQuery.slimbox([[array1], [array3], [array2]], startAtImage);
// after appending the images to select the first and last images
jQuery.slimbox([[array1], [array4], [array5], [array3], [array2], [array6]], startAtImage);
Here's my attempt at dynamically calling the slimbox function:
var imgAlbum = "summer";
var arrayGiven = [1,3,2]; // randomized image order given
var img1 = [4,5]; // registering images to be appended -- aiming for [1,4,5]
var img2 = [6]; // registering images to be appended -- aiming for [2,6]
var desc1 = "Description #1"; // unique descriptions
var desc2 = "Description #2";
var desc3 = "Description #3";
var desc4 = "Description #4";
var desc5 = "Description #5";
var desc6 = "Description #6";
var arrayExtended = arrayGiven;
for(var i=1; i<=3; i++){ // cycle through arrayGiven and append images
var imgLocate = i;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended); // locating array index number of a specific image. if imgLocate = 1, then imgAtIndex = 0 , if 2 then 4, and so forth
var imgAfter = imgAtIndex + 1; // allows appending to selected image at index
eval("var imgCurrent = img" + imgLocate + ";"); // creating dynamic variable
if(imgCurrent != null){
arrayExtended.splice(imgAfter, 0, imgCurrent);
}
} // alert(arrayExtended) should be [1,4,5,3,2,6]
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
eval("var array" + imgLocate + " = ['img/" + imgAlbum + "/" + imgLocate + ".jpg',desc" + imgLocate + "];"); // if imgLocate = 1, then var array1 = ['img/summer/1.jpg',desc1];
// array1 array2 array3 array4 array5 array 6 ... now defined
}
var arrayMain = [];
for(var i=1; i<=arrayExtended.length; i++){ // must wait for arrays to be built before adding to arrayMain
var atIndex = i - 1;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended); // if imgLocate = 1, then imgAtIndex = 0 , if 2 then 4
eval("arrayMain.push('[' + array" + arrayExtended[atIndex] + " + ']');");
}
var imgClicked = 0; // clicked on image within arrayExtended index 0
var startAtImage = imgClicked; // slimbox slideshow will start on 1.jpg
jQuery.slimbox("[" + mainArray + "]",startAtImage);
And finally hoping for the following result:
jQuery.slimbox([["img/summer/1.jpg","Desciption #1"], ["img/summer/4.jpg","Desciption #4"], ["img/summer/5.jpg","Desciption #5"], ["img/summer/3.jpg","Desciption #3"], ["img/summer/2.jpg","Desciption #2"]], ["img/summer/6.jpg","Desciption #6"], 0);
Any help or advice will be much appreciated! There's much to learn.
Updated 8-26-11 Changed structure based on advices. Also added more images and groups into array to better illustrate the functionality needed. There are errors when trying to call image groups (1, 2, 7) from img object:
var imgAlbum = "summer";
var arrayGiven = [1,3,2,7,11]; // randomized image order given
var img = {
1: [4,5],
2: [6],
7: [10,8,9]
};
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6',
7: 'Description #7',
8: 'Description #8',
9: 'Description #9',
10:'Description #10',
11:'Description #11'
};
var arrayExtended = arrayGiven.slice();
for(var i=1; i<=arrayGiven.length; i++){
var imgLocate = i;
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended);
var imgAfter = imgAtIndex + 1;
var imgCurrent = img[imgAfter];
if(imgCurrent != null){
arrayExtended.splice(imgAfter, 0, imgCurrent);
}
//alert(imgCurrent); // shows 4,5 undefined undefined undefined undefined
} //alert(arrayExtended);// shows 1,4,5,3,2,6,7,10,8,9,11
var imgArray = {};
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
imgArray[imgLocate] = ['imgs/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
}
var mainArray = [];
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
mainArray.push(imgArray[arrayExtended[atIndex]]);
//alert(imgArray[arrayExtended[atIndex]]); // shows (simplified) 1.jpg,Desc#1 undefined 3.jpg,Desc#3 2.jpg,Desc#2 undefined undefined
}
var imgClicked = 0;
var startAtImage = imgClicked;
jQuery.slimbox(mainArray,startAtImage);
Updated 8-30-11 FINAL SOLUTION Fixes applied and added randomizer from production code. The results are accurate. If you plan on using the randomizer, I recommend keeping the images-to-be-appended outside of the getRandomArray range, unless you wish to see duplicates.
Thanks everyone for your awesome support!
function getRandomArray(min,max){
var A= [];
while(max>= min) A.push(max--)
A.sort(function(){return .5- Math.random()});
return A;
}
var randomness = getRandomArray(1,11).slice();
var leadingZeroArray = randomness.slice();
leadingZeroArray.unshift("0"); // was needed for my project, but if removed, everything else will need to be re-adjusted
var arrayGiven = randomness.slice(); // or you can plug in -> var arrayGiven = [1,3,2,7,11]; for original example
var imgAlbum = "summer";
var img = {
1: [4,5],
2: [6],
7: [10,8,9]
};
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6',
7: 'Description #7',
8: 'Description #8',
9: 'Description #9',
10:'Description #10',
11:'Description #11'
};
var arrayExtended = arrayGiven.slice();
for(var i=0; i<arrayGiven.length; i++){
var imgLocate = arrayGiven[i];
var imgAtIndex = jQuery.inArray(imgLocate,arrayExtended);
var imgAfter = imgAtIndex + 1;
var imgCurrent = img[imgLocate];
if(imgCurrent != null){
if(imgCurrent.length > 0){
for(var j=imgCurrent.length-1; j>-1; j--){
var imgMore = imgCurrent[j];
arrayExtended.splice(imgAfter, 0, imgMore);
}
}
else{arrayExtended.splice(imgAfter, 0, imgCurrent); }
}
}
var imgArray = {};
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
imgArray[imgLocate] = ['images/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
}
var mainArray = [];
for(var i=1; i<=arrayExtended.length; i++){
var imgLocate = i;
var atIndex = i - 1;
mainArray.push(imgArray[arrayExtended[atIndex]]);
}
var imgClickedOn = 5;
var imgAtIndex = jQuery.inArray(imgClickedOn,arrayExtended);
jQuery.slimbox(mainArray,imgAtIndex);
Instead of having multiple vars for img
, use an array or an object.
var img = {
1: [4,5],
2: [6]
};
Then instead of eval("var imgCurrent = img" + imgLocate + ";");
, you can do:
var imgCurrent = img[imgLocate];
You can do the same sort of thing for:
eval("var array" + imgLocate + " = ['img/" + imgAlbum + "/" + imgLocate + ".jpg',desc" + imgLocate + "];");
Create an object and put the arrays in there:
var desc = {
1: 'Description #1',
2: 'Description #2',
3: 'Description #3',
4: 'Description #4',
5: 'Description #5',
6: 'Description #6'
};
var imgArray = {};
imgArray[imglocate] = ['img/'+imgAlbum+'/'+imgLocate+'.jpg', desc[imgLocate]];
EDIT: Try changing var imgLocate = i;
inside for(var i=1; i<=arrayGiven.length; i++){
to var imgLocate = arrayGiven[i];
.