Bootstrap carousel with thumbnails (Multiple Carousel) - javascript

I was looking up how to create a Bootstrap carousel with thumbnails, and I came across this:
http://jsfiddle.net/xuhP9/67/
$('#myCarousel').carousel({
interval: 4000
});
$('[id^=carousel-selector-]').click(function () {
var id_selector = $(this).attr("id");
var id = id_selector.substr(id_selector.length - 1);
id = parseInt(id);
$('#myCarousel').carousel(id);
$('[id^=carousel-selector-]').removeClass('selected');
$(this).addClass('selected');
});
$('#myCarousel').on('slid', function (e) {
var id = $('.item.active').data('slide-number');
id = parseInt(id);
$('[id^=carousel-selector-]').removeClass('selected');
$('[id^=carousel-selector-' + id + ']').addClass('selected');
});
Which works well, however, I need to have multiple carousel in a page, and I am not quite sure how I can accomplish this. I tired to switch the id selector into a class selector so I can create more than one. But I am not sure how to actually fix the JS functionality to make it work since they seem to be blinded together.
Basically, this is what I am trying to accomplish: http://jsfiddle.net/xuhP9/70/ but without repeating the JS for each independent carousel I create.
Thanks in advance!

This method requires your carousels to have ID = myCarousel1, myCarousel2 etc.
and your selectors for the corresponding carousel to be carousel-selector1-1, carousel-selector1-2 ... and carousel-selector2-1, carousel-selector2-2
Updated Fiddle: http://jsfiddle.net/xuhP9/77/
$('.customCarousel').carousel({
interval: 4000
});
// handles the carousel thumbnails
$('[id^=carousel-selector]').click(function () {
var id_selector = $(this).attr("id");
var id = id_selector.substr(id_selector.length - 1);
id = parseInt(id);
var parent = $(this).closest('ul').data('carousel');
$('#myCarousel' + parent).carousel(id);
$('[id^=carousel-selector' + parent +'-]').removeClass('selected');
$(this).addClass('selected');
});
// when the carousel slides, auto update
$('.customCarousel').on('slid', function (e) {
var cont = $(this).data('carousel');
var id = $('#myCarousel'+ cont +' .item.active').data('slide-number');
id = parseInt(id);
$('[id^=carousel-selector' +cont+'-]').removeClass('selected');
$('[id^=carousel-selector'+cont+'-' + id + ']').addClass('selected');
});

Related

Adding Next and Previous Buttons to Bootstrap Targeting Link IDs

I am attempting to add next/prev and then swipe events to a bootstrap modal image gallery. The thumbnails are displayed in a grid so when I try closest(), siblings(), and next() I am only able to go to the images below and above in the same column and not the other columns in the grid.
Each thumbnail has an id with the images ID in the database. ie:
<a class="image-gallery-item" id="img-1002" href="#showImageModal" data-toggle="modal" onclick="..."><img src="..." /></a>
<a class="image-gallery-item" id="img-4664" href="#showImageModal" data-toggle="modal" onclick="..."><img src="..." /></a>
Every link passes the images src, caption, and ID to a function which changes out the info displayed the modal. All that works fine, I just can't seem to get next/prev working when trying to trigger the next item.
Ideally, instead of using next() and closest() and sibling() methods, I would LIKE to just target the ID greater than the current id for first next and lesser than the current ID for the first previous and trigger a click if the element exists.
Thanks.
UPDATE
Per #Ersian's suggestion, I created an array and cycle thru the images by index. They're still going by column but at least they're moving to the next column after. This will present a little confusion for users, I feel, who will expect the images to display left to right before going to the next row of square thumbnails.
$('.image-gallery-item').modal('hide');
setTimeout(function () {
var thisIMG = $("#imgid").html();
var imgs = document.getElementsByClassName("image-gallery-item");
var $imgvalues = Array.prototype.map.call(imgs, function (el) {
return el.id;
});
index = $imgvalues.indexOf(thisIMG);
if (index >= 0 && index < $imgvalues.length - 1)
nextItem = $imgvalues[index + 1];
$('#' + nextItem).trigger('click');
}, 1000);
UPDATE - WORKING CODE
Found the solution by adding sort to the array and then looped the next/prev if hitting the end or start of items with the class image-gallery-item. I'll post the working code as an answer in case anyone else finds this question and wants to make a bootstrap modal image gallery with gridalicious, isotope, or masonry layouts with columns.
Keep in mind you will need to add buttons with show-next-image and show-previous-image classes to your modal. After that, the following code will let you cycle thru images with the class image-gallery-item.
$('#show-next-image, #show-previous-image').click(function () {
if ($(this).attr('id') == 'show-previous-image') {
$('#showImageModal').modal('hide');
setTimeout(function () {
var thisIMG = $("#imgid").html();
var imgs = document.getElementsByClassName("image-gallery-item");
var $imgvalues = Array.prototype.map.call(imgs, function (el) {
return el.id;
});
var lastIMG = $('.image-gallery-item').length;
$imgvalues.sort();
index = $imgvalues.indexOf(thisIMG);
if (index <= lastIMG - 2) {
nextItem = $imgvalues[index + 1];
} else {
nextItem = $imgvalues[0];
}
$('#' + nextItem).trigger('click');
}, 1000);
} else {
$('#showImageModal').modal('hide');
setTimeout(function () {
var thisIMG = $("#imgid").html();
var imgs = document.getElementsByClassName("image-gallery-item");
var $imgvalues = Array.prototype.map.call(imgs, function (el) {
return el.id;
});
var lastIMG = $('.image-gallery-item').length;
$imgvalues.sort();
index = $imgvalues.indexOf(thisIMG);
if (index >= 1) {
nextItem = $imgvalues[index - 1];
} else {
nextItem = $imgvalues[lastIMG - 1];
}
$('#' + nextItem).trigger('click');
}, 1000);
}
});

Display one div at a time with multiple buttons

Using Foundation 6 as my framework, I wanted to implement a fading effect between two divs when a button is pressed.
The effect I'm trying to do is when button1 is clicked, div2 will hide and fade out (if visible) and div1 will show and fade in, and vice versa.
Here is my Javascript code:
var $button1 = $('#button1');
var $button2 = $('#button2');
var $div1 = $('#div1');
var $div2 = $('#div2');
$button1.click(function() {
if ($div2.is(':visible')) {
MotionUI.animateOut($div2, 'fadeOut');
MotionUI.animateIn($div1, 'fadeIn');
}
else {
$div1.show();
}
});
$button2.click(function() {
if ($div1.is(':visible')) {
MotionUI.animateOut($div1, 'fadeOut');
MotionUI.animateIn($div2, 'fadeIn');
}
else {
$div2.show();
}
});
I have gotten div1 and div2 to fade in/out between the two with one button, but I can't seem to get it to work when using multiple buttons.
Here's a really simple way to toggle display:none using jQuery's toggle() methods. I used fadeToggle since you mentioned wanting a fade, but you could use toggle and set a css3 transition instead.
Keeping the code super simple - to match what you have - this is how you would do it:
Fiddle: https://jsfiddle.net/f1dshffs/2/
var $button1 = $('#button1');
var $button2 = $('#button2');
var $div1 = $('#div1');
var $div2 = $('#div2');
var toggleDivs = function(){
$div1.fadeToggle();
$div2.fadeToggle();
};
$button1.click(toggleDivs);
$button2.click(toggleDivs);
Now there's some things you could do to optimize your code a little bit by selecting by a class instead of an id, and then adding only 1 event to the array of objects.
It reduces the code down to: Fiddle: https://jsfiddle.net/f1dshffs/3/
var buttons = $('.button');
var divs = $('.div');
var toggleDivs = function(){
divs.fadeToggle();
};
buttons.click(toggleDivs);

use multiple image lightboxes on one page without knowing how much

I'm using a lightbox script which uses a data attribut to know which images are part of a gallery.
To initialize a gallery, I have to do the following:
var selector = 'a[data-imagelightbox="a"]';
var lightbox = $( selector ).imageLightbox({});
If I wan't another gallery on the same page I have to add another:
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
I tried to use another selector and the .each function to get it working without writing this 2 code lines for each gallery. But it is not working. The problem is the data attribute groups all images with this attribute to one gallery. If I'm trying it without a, b, c or d - i always get one large gallery and not 3 seperate gallerys.
So, does anybody have a solution how I can use an unknown number of gallerys on one page, without having to define each gallery in Javascript?
I made a JSBIN, so it should be easier to try it out:
http://jsbin.com/goqije/1/
Thanks for your help!
Fixed it myself by doing it this way:
$('ul').each( function() {
var id = $(this).find('a').attr('data-imagelightbox');
var selector = 'a[data-imagelightbox="' + id +'"]';
var lightbox = $( selector ).imageLightbox({
quitOnDocClick: false,
onStart: function() { overlayOn(); closeButtonOn( lightbox ); arrowsOn( lightbox, selector ); },
onEnd: function() { overlayOff(); closeButtonOff(); arrowsOff(); },
onLoadStart: function() { },
onLoadEnd: function() { $( '.imagelightbox-arrow' ).css( 'display', 'block' ); }
});
});
Attribute selector maybe?
instead of doing :
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
and
var selector = 'a[data-imagelightbox="b"]';
var lightbox = $( selector ).imageLightbox({});
Just do it with a attribute selector :
var selector = 'a[data-imagelightbox]';
var lightbox = $( selector ).imageLightbox({});
Or even better, you can use a naming convention for all the gallery data attributes as follows:
gallery-1 , galery-2 , gallery-3 and then use a attribute selector as follows:
var selector = 'a[data-imagelightbox^="gallery"]';
var lightbox = $( selector ).imageLightbox({});
Solution two
The above solution seems to have a conflict, here's a slightly different solution that leverages "naming convention" (gallery-1 , gallery-2 ... etc.) and a for loop , see this example here. Notice how I am using a for loop to iterate over all the a elements and turn their color red:
HTML code here:
One
Two
Three
jQuery code here:
$(function () {
str_elm = $('a');
for (var i = 0; i < str_elm.length ; i++) {
data_val = $(str_elm[i]).attr('data-test');
str_temp = "a[data-test=" + '"'+ data_val + '"' + "]";
$(str_temp).css({'color' : 'red'});
};
});
Fiddle here.
You can change the JS as follows to suit your needs:
$(function () {
str_elm = $('a[data-imagelightbox^="gallery"]');
for (var i = 0; i < str_elm.length ; i++) {
data_val = $(str_elm[i]).attr('data-test');
str_temp = "a[data-test=" + '"'+ data_val + '"' + "]";
$(str_temp).imageLightbox({}); // initialization here
};
});

change class of div on scroll HTML5 with data attribute

What I am trying to do is to call a function every time a person scrolls that checks the current class of container and adds +1 to the current value of the current data attribute and then toggles the class relative to the data attribute it is currently changing the class on scroll but giving a "NaN. I am already running this function on click and it works fine.
here is a fiddle.
http://jsfiddle.net/kaL63/1/
This is my function on scroll
var timeout;
$(window).scroll(function() {
if(typeof timeout == "number") {
window.clearTimeout(timeout);
delete timeout;
}
timeout = window.setTimeout( check, 100);
});
My html Looks like this
<div class="container year-1987" data-year-index="1987">
Some Content
</div>
the function I am calling right now that I think should work..
function check(){
var
animationHolder = $('.container'),
currentClass = animationHolder.attr("class").match(/year[\w-]*\b/);
var goToYear = $('.container').data('year-index');
var goToYear2 = parseInt(goToYear,1000) + 1;
animationHolder.toggleClass(currentClass + ' year-' + goToYear2);
animationHolder.attr('data-year-index', goToYear2);
}
My working code on click
$("a").click(function (e) {
e.preventDefault();
var
animationHolder = $('.container'),
currentClass = animationHolder.attr("class").match(/year[\w-]*\b/);
var goToYear = $(this).data('year-index');
animationHolder.toggleClass(currentClass + ' year-' + goToYear);
animationHolder.attr('data-year-index', goToYear);
I rewrote your check method:
function check() {
var $container = $('.container'),
currentYear = $container.data('m-index'),
nextYear = 1 + currentYear;
$container.removeClass('m-' + currentYear).addClass('m-' + nextYear);
$container.data('m-index', nextYear);
}
I made the following changes:
There is no need for the regular expression since we can generate the class name ourselves.
I am not sure why you were originally using two separate data-attributes (m-index and year-index), but I switched them to both match. If you need both of them, some more logic is needed to use year-index after the initial call.
I am now updating m-index via .data() rather than setting a data attribute.
This method seemed to work fine for me.

jquery swap images on click and hide then

I'm trying to build a menu. OVer a canvas I load different images and position them using CSS. Currently I operate with SHOW / HIDE with a lots of code duplication. My questions are:
- instead of just hidding an image, how can I change it on click with another one? and then again hide it, if I should click another button?
- is it possible to write all this code somehow simpler?
Thanks a lot...
$("#ten").click(sizeTen);
function sizeTen(){
cb_ctx.lineWidth = 10;
clickSound();
$(this).hide();
$("#twenty").show();
$("#forty").show();
$("#sixty").show();
}
$("#twenty").click(sizeTwenty);
function sizeTwenty(){
cb_ctx.lineWidth = 20;
clickSound();
$(this).hide();
$("#tenClick").show();
$("#ten").show();
$("#forty").show();
$("#sixty").show();
}
$("#forty").click(sizeForty);
function sizeForty(){
cb_ctx.lineWidth = 40;
clickSound();
$(this).hide();
$("#ten").show();
$("#twenty").show();
$("#sixty").show();
}
$("#sixty").click(sizeSixty);
function sizeSixty(){
cb_ctx.lineWidth = 60;
clickSound();
$(this).hide();
$("#ten").show();
$("#twenty").show();
$("#forty").show();
}
May be You Could shrink your coding by the following piece of code,
$("#ten,#twenty,#sixty").show();
I'd put all numeric values along with the corresponding IDs in a map and create a single handler for all buttons:
var boo = function () {
var values = { 'ten': 10, 'twenty': 20, 'forty': 40, 'sixty': 60 };
var id = $(this).attr('id');
$(this).hide();
// cb_ctx.lineWidth = values[id];
// clickSound();
$.each(values, function(key, value) {
if (id != key) {
$('#' + key).show();
}
});
};
$('#ten, #twenty, #forty, #sixty').click(boo);
Check out a jsfiddle at: http://jsfiddle.net/LNFza/4/
Cheers.

Categories