I have this simple next and previous function that i wrote but i am having one simple issue. On the last slider on click next, it shows a blank slider then on click next it starts all over as it is supposed to. What am i missing? Below is the jquery code;
$('div.contsliders').each(function(e) {
if (e != 0)
$(this).hide();
});
$('span.next').click(function(){
if ($('div.contsliders:visible').next().length != 0)
$('div.contsliders:visible').next().fadeIn(1000).prev().hide();
else {
$('div.contsliders:visible').hide();
$('div.contsliders:first').fadeIn(1000);
}
return false;
});
$('span.prev').click(function(){
if ($('div.contsliders:visible').prev().length != 0)
$('div.contsliders:visible').prev().fadeIn(1000).next().hide();
else {
$('div.contsliders:visible').hide();
$('div.contsliders:last').fadeIn(1000);
}
return false;
});
HERE IS THE JSFIDDLE LINK
I will really appreciate it mates, thanks.
That is because when it checks for the following condition for the div which you think it is the last using $('div.contsliders:visible').next().length gives .contsnextprev (hence length will still be 1 instead of 0 as assumed) so it shows that one instead of moving to the beginning, which happens when you click on it again. It is because .contsnextprev is the div next to the last slide #five.
if ($('div.contsliders:visible').next().length != 0)
$('div.contsliders:visible').next().fadeIn(1000).prev().hide();
You can change it to:
var $nxt = $('div.contsliders:visible').next('.contsliders');
if ($nxt.length != 0)
$nxt.fadeIn(1000).prev().hide();
Demo
Infact you can simplify this to just one handler as well:
$('div.contsliders:gt(0)').hide(); //Hide all but the first one
var $allSlides = $('div.contsliders'),
traverseDefault = "first", //set the defaults
actionDefault ="next";
$('span.next, span.prev').click(function(){
var traverse = traverseDefault,
action = actionDefault;
if($(this).is('.prev')){ //if action is prev
traverse = "last"; //set traverse to last in case nothing is available
action = "prev"; //set action to prev
}
var $curr = $allSlides.filter(':visible'), //get the visible slide
$nxtTarget = $curr[action](".contsliders"); //get the next target based on the action.
$curr.stop(true, true).fadeIn(1000).hide(); //hide current one
if (!$nxtTarget.length){ //if no next
$nxtTarget = $allSlides[traverse](); //based on traverse pick the next one
}
$nxtTarget.stop(true, true).fadeIn(1000); //show the target
});
Demo
Related
The page with the problem: http://robinbz216.216.axc.nl/kinderen.html
I open a modal on click and get different content in the modal for each of the 11 divs you can click on. I made a left and right arrow so users dont have to close the modal and click the next div to view the next content. When a div is clicked, jquery looks for it position in a nodelist of all the 11 items, puts that in a variable (named indexVar) and get the right content out of the 11 content arrays. If you click the left arrow, indexVar gets -1, and then that number again get checked with the content arrays and the previous div content is shown in the modal.
This all works fine the first time you click a div. But when you close the modal, and click again on a div, the last indexVar has not disappeared and another instance of the same click function is made and so it doubles the next previous
and next clicks that are done with the arrow buttons.
I guess my function structure is pretty bad, and i dont know how to fix it so that with a second click on one of the 11 divs, it starts fresh without the functions from the last modal use.
$(".kindDiv").click(function() {
if (!($("#singleModal2").hasClass("zichtbaar"))) {
$("#singleModal2").addClass("zichtbaar");
// Returns a NodeList
var kindDivss = document.getElementsByClassName("kindDiv");
var indexVar = $(".kindDiv").index(this);
var modalLength = modalArray.length;
var modalLengthMin = modalLength;
var modalLengthMini = modalLength;
modalLengthMini = modalLengthMini - 1;
modalLengthMin = modalLengthMin - 2;
for (i = 0; i < modalLength; i++) {
var firstWord = modalArray[i].replace(/ .*/, '');
arrayVoornaam.push(firstWord);
if (i == indexVar) {
//append content in modal
$("#singleModal2 h4").html(arrayVoornaam[i]);
$("#singleModal2 p").html(modalArray[i]);
$("#singleModal2 img").attr("src", imageArray[i]);
}
}
//Hide buttons when first or last of 11 divs is opened
if (indexVar == modalLengthMini) {
$(".arrowRight").addClass("invisible");
}
if (indexVar == 0) {
$(".arrowLeft").addClass("invisible");
}
//Left arrow click
$(".arrowLeft").click(function() {
if (indexVar == 1) {
$(".arrowLeft").addClass("invisible");
}
if (indexVar !== modalLengthMin) {
$(".arrowRight").removeClass("invisible")
}
indexVar--;
$("#singleModal2 h4").html(arrayVoornaam[indexVar]);
$("#singleModal2 p").html(modalArray[indexVar]);
$("#singleModal2 img").attr("src", imageArray[indexVar]);
});
//Right arrow click
$(".arrowRight").click(function() {
if (!indexVar == 1) {
$(".arrowLeft").removeClass("invisible");
}
if (indexVar == modalLengthMin) {
$(".arrowRight").addClass("invisible");
}
indexVar++;
$("#singleModal2 h4").html(arrayVoornaam[indexVar]);
$("#singleModal2 p").html(modalArray[indexVar]);
$("#singleModal2 img").attr("src", imageArray[indexVar]);
});
//close modal
$(".close").click(function() {
$("#singleModal2").removeClass("zichtbaar");
arrayVoornaam = [];
$(".arrowLeft").removeClass("invisible");
$(".arrowRight").removeClass("invisible");
});
}
});
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);
}
});
function nextSlideFunc() {
var currentSlide = $(".slide.active-slide");
var currentSlideIndex = $(".slide.active-slide").index();
var nextSlideIndex = currentSlideIndex + 1;
var nextSlide = $(".slide").eq(nextSlideIndex);
$("#nextBtn").on("click", function(e) {
e.preventDefault();
currentSlide.removeClass("active-slide");
if(nextSlideIndex === $(".slide").last().index() + 1) {
//stay at last slide when reached.
$(".slide").eq(nextSlideIndex - 1).addClass("active-slide");
} else {
nextSlide.addClass("active-slide");
}
});
}
After I clicked on the next button, the slide goes to the next slide which is what I want, but when I continue to click, it just stopped going forward.
I checked my HTML in the dev tool, it has the class name "active-slide" on one of the slides which fulfills the condition, but I'm not sure why it's not working.
As for the previous button, it's not removing class "active-slide" like it's supposed to, any idea why this is happening?
You have to set your variables inside the listener of your click event:
https://codepen.io/anon/pen/OxMxwd
$("#prevBtn").on("click", function(e) {
var currentSlide = $(".slide.active-slide");
var currentSlideIndex = $(".slide.active-slide").index();
var prevSlideIndex = currentSlideIndex - 1;
var prevSlide = $(".slide").eq(prevSlideIndex);
}
That way you will calculate your index and next index every time you click the button. The way you did it, is calculating it once and reusing it over and over again, so you will do the same thing on the same index over and over again.
im have a code that add and remove dynamically form controls. The add and delete methods works fine. But i like if exist only one control, not remove it.
I defined the next var, outside $(document).ready scope:
var Alumnos = {};
And initialize inside of $(document).ready:
// Valor inicial de casilleros renderizados.
Alumnos.count = 3;
The method that remove controls is:
// Elimina un bloque
$(document).on('click','.closable',function(){
if(Alumnos.count > 1){
var idRow = $(this).attr('data-toggle');
var victim = $(idRow + " .row-fluid:last-child");
victim.remove();
var childs = $(idRow).children();
if(childs.length === 0)
{
$(idRow).remove();
$(this).remove();
Alumnos.count -= 1;
}
}
console.log(Alumnos.count);
return false;
});
The Alumnos.count value persist after delete. Any ideas ?
UPDATE 1
When the user click on "Add more", the code, create a form row with 3 controls, from a prototype.
Because, i cant use children count.
I need the user dont remove all controls.
I think you should have:
if(Alumnos.count >= 1){ //Probably if there is only 1, it's erasable. You had >
And move the decrement outside, like this:
var childs = $(idRow).children();
if(childs.length === 0)
{
$(idRow).remove();
$(this).remove();
}
Alumnos.count -= 1; //This was moved
Hope this helps. Cheers
Thanks for all your replies !! I found the way to control the elements remove with the childs count. May be isnt the best code, but works.
$(document).on('click','.closable',function(){
// Get the id of the row.
var dataToggle = $(this).attr('data-toggle');
// Get the row
var row = $(dataToggle);
// if isnt first row (#id0), ok, remove all if you want.
// if is first row (#id0) and have more than one child, happy remove ^^
if((dataToggle === "#id0" && row.children().length > 1) || dataToggle !== "#id0"){
// remove code...
}
return false;
});
So, I need a div to slide up when another slides down.
Example:
When Home button is clicked a div, we'll call it box_Home, slides down. When Games button is clicked, box_Home should slide up and then box_Games should slide down. What's happening is that they are overlapping instead of swapping out.
http://jsfiddle.net/M8UgQ/15/
var open = $('.open'),
a = $('ul').find('a');
console.log(a.hasClass('active'));
open.click(function(e) {
e.preventDefault();
var $this = $(this),
speed = 500;
var link_id = $this.attr('id');
var box_id = '#box_' + link_id;
console.log(box_id);
if($this.hasClass('active') === true) {
$this.removeClass('active');
$(box_id).slideUp(speed);
} else if(a.hasClass('active') === false) {
$this.addClass('active');
$(box_id).slideDown(speed);
} else {
a.removeClass('active')
$(box_id).slideUp(speed);
$this.addClass('active');
$(box_id).delay(speed).slideDown(speed);
}
});
take a look at this
http://jsfiddle.net/rWrJ9/1/
the main idea is...
if the element clicked is active, remove it, otherwise: 1. find (if any) already active elements (using $('.active')) and use jQuery.map() to make them inactive and slide them up, and 2. make the element clicked active.
I also removed the unneeded variable a
IMPORTANT: the this inside the map() function is different from the this (or rather, $this as you called it) outside the map() function
I think you're saying you have two buttons id="Home" class="open" and id="Game" class="open", and two divs id="box_Home" and id="box_Game". If so, you add class="box" to box_Home and box_Game and do something like this:
$('.open').click(function(e) {
e.preventDefault();
var $this = $(this);
var link_id = $this.attr('id');
var box_id = '#box_' + link_id;
$('.box').slideUp();
$(box_id).slideDown();
});
Hi check this fiddle i hope you need thing to implement
jsfiddle
in the if else statement you are doing a mistake
else if(a.hasClass('active') === false) {
replace it with
else if($this.hasClass('active') === false) {