I am using a bxSlider plugin to create a JS web application. On one slide there is a form which needs to be validated before I can get to a next slide. For validation I use jQuery Validate plugin which returns true / false when the form is valid.
How to make bxSlider not to go to next slide when form is not valid? I would prefer to use default bxSlider next/prev controls.
Function that initialize bxSlider:
bxSliderInit: function() {
var $slider = $(dom.slider);
$(dom.body).on('click', dom.pageLink, function(e) {
e.preventDefault();
_this = $(this);
slideFinished = true;
//newSlide = _this.data('slide-index');
app.slidePaging();
});
slider = $slider.bxSlider({
mode: 'horizontal',
easing: 'ease-out',
infiniteLoop: false,
touchEnabled: false,
preventDefaultSwipeY: true,
preventDefaultSwipeX: true,
responsive: false,
slideWidth: 1024,
pager: false,
prevText: '<i class="icon icon-arrow-left"></i>',
nextText: '<i class="icon icon-arrow-right"></i>',
onSlideBefore: function($slideElement, oldIndex, newIndex) {
app.slideValidation($slideElement, oldIndex, newIndex);
}
});
},
BxSlider callback onSlideBefore to validate the form
slideValidation: function($slideElement, oldIndex, newIndex) {
var $thisSlidevalidationForm = $(dom.slider).children().eq(oldIndex).find(dom.formValidationClass),
validationFromExist = $thisSlidevalidationForm.length > 0 ? true : false;
if (oldIndex < newIndex) {
if (validationFromExist) {
if (!$thisSlidevalidationForm.valid()) {
//slider.dontDoTransition
}
}
}
},
Everything seems to work fine, I just can't force the bxSlider to stay on the current slide when the form is not valid...
Thank u for ur help!
After some experiments and ideas, here is the solution:
onSlideBefore: function (currentSlideNumber, totalSlideQty, currentSlideHtmlObject) {
return currentSlideNumber--;
}
Related
I'm using slick.js as a content browser. As such, my slider has a number of images to peruse through. I'd like to be able to refresh the web page and have slick remember the last slide I was viewing. I'm new to jquery and javascript so any guidance would be appreciated.
Here's the code I'm working with:
$(document).ready(function(){
// Carousel Options
$('.mycarousel').slick({
infinite: true,
accessibility: true, mobileFirst: true,
adaptiveHeight: true,
arrows: false, draggable: true,
useCSS: true, cssEase:'linear', focusOnSelect: true,
dots: true, appendDots:$(document.innerHTML = "<p> </p>"),
lazyLoad: 'ondemand',
});
$('.leftArrow').on('click', function(){
$('.mycarousel').slick("slickPrev");
});
$('.rightArrow').on('click', function(){
$('.mycarousel').slick("slickNext");
});
$(window).on('resize orientationchange', function() {
$('.mycarousel').slick('resize');
});
});
I myself did some research and this is what I found:
$('#yourCarousel').on('slid.bs.carousel', function () {
var currentSlide = $('#yourCarousel div.active').index();
sessionStorage.setItem('lastSlide', currentSlide);
});
if(sessionStorage.lastSlide){
$("#yourCarousel").carousel(sessionStorage.lastSlide*1);
}
Instead of sessionStorage you could also use:
localStorage.setItem('lastSlide', currentSlide)
I need to add class inactive in prev if first slider and for next if end of the slider.
$('.bxslider').bxSlider({
nextSelector: '#slider-next',
prevSelector: '#slider-prev',
nextText: 'Nex →',
prevText: '← Prev',
infiniteLoop: false,
});
https://jsfiddle.net/uewLafk1/
According to the documentation for the bxSlider plugin, there's an onSlideAfter callback which triggers after every transition. In addition, it has methods for getCurrentSlide and getSlideCount.
Using all of these three, you can do the following:
var slider = $('.bxslider').bxSlider({
nextSelector: '#slider-next',
prevSelector: '#slider-prev',
nextText: 'Next →',
prevText: '← Prev',
infiniteLoop: false,
onSlideAfter: function() {
if (slider.getCurrentSlide() == 0)
// First slide
$('#slider-prev').addClass('inactive');
else if (slider.getCurrentSlide() == slider.getSlideCount() - 1)
// Last slide
$('#slider-next').addClass('inactive');
else
$('#slider-next, #slider-prev').removeClass('inactive');
}
});
Fiddle: https://jsfiddle.net/kbfdebzg/
Im working on a slider that contains two synced owl-sliders.
sync1 is main slider and sync2 is thumbnails slider. When I click on one of elements of second slider sync1 goes to proper slide.
Now goes my issue:
When user clicks on any of thumbnail a green border should appear on clicked elemment and should stay there until another element is clicked.
I've tried to use jquery .addClass and .css but nothing happens.
I think that I should add div with "position: absolute" that holds up to clicked element, but I don't know how to do it. Please help! :)
Here is my js
$(document).ready(function() {
var sync1 = $("#sync1");
var sync2 = $("#sync2");
var index2=0;
var flag=true;
var slides = sync1.owlCarousel({
items: 1,
loop: true,
autoplay: true,
autoplayTimeout:5000,
autoplayHoverPause:true,
nav: false,
mousedrag: false,
touchdrag: false,
pulldrag: false
});
$(document).on('click', '.prevbutton, .nextbutton',function() {
sync1.trigger('stop.owl.autoplay');
});
sync1.on('changed.owl.carousel', function(event) {
var index1=event.item.index;
var index11 = index1-2;
//console.log("index1", index1)
//console.log("index11", index11);
sync2.trigger("to.owl.carousel", [index11, 100, true]);
});
$('.nextbutton').click(function() {
//console.log(sync1);
sync1.trigger('next.owl.carousel');
});
$('.prevbutton').click(function() {
// With optional speed parameter
// Parameters has to be in square bracket '[]'
//console.log(sync1);
sync1.trigger('prev.owl.carousel', [500]);
});
/* thumbnails*/
var thumbnails= sync2.owlCarousel({
items: 6,
loop: true,
autoplay: false,
mousedrag: false,
touchdrag: false,
pulldrag: false,
addClassActive: true
});
/*buttons*/
$('.nextbutton2').click(function() {
sync2.trigger('next.owl.carousel');
});
$('.prevbutton2').click(function() {
// With optional speed parameter
// Parameters has to be in square bracket '[]'
sync2.trigger('prev.owl.carousel', [500]);
});
sync2.trigger("to.owl.carousel", [index2, 100, true]);
sync2.on('changed.owl.carousel', function(event) {
index2=event.item.index;
//console.log("index2", index2);
index22=index2-1;
// sync1.trigger("to.owl.carousel", [index22, 100, true]);
});
// console.log("index2", index2);
sync2.on('click', '.item', function(e) {
e.preventDefault();
sync1.trigger('to.owl.carousel', [$(e.target).parents('.owl-item').index()-6, 300, true]);
// console.log("clicked index", $(e.target).parents('.owl-item').index())
});
$('#stopcontainer').on('mouseover', function(){
if ($('#stopcontainer:hover').length != 0) {
flag=true;
console.log("flaga", flag);
}
if (flag==true) {
sync1.trigger('stop.owl.autoplay');
console.log("mousein");
}
}).on('mouseleave', function() {
setTimeout(
function()
{
if ($('#stopcontainer:hover').length == 0) {
flag=false;
console.log("flaga", flag);
}
if(flag==false){
console.log('mouse leave');
sync1.trigger('play.owl.autoplay');
}
}, 5000)}
);
});
Here is the solution:
sync2.on('click', '.owl-item', function(e) {
e.preventDefault();
$('.some-class').removeClass('active');
$(this).find('.some-class:first').addClass('active');
});
There is empty div with "some-class" inside carousel item, and when you click on this element class "active" is added
I have a page with multiple sliders - each within its own tab. I'd like for the sliders to start over if a user leaves a tab and then returns.
Dev link: http://dev.triciafrancis.com/mbrstudios/case-studies/
Here is the code I'm using for liquidslider and tabs:
//Use liquid slider to setup slides within tabbed content
$('#tabs .tab .liquid-slider').liquidSlider({
preloader: true,
autoHeight: false,
dynamicTabs: true,
dynamicTabsHtml: true,
dynamicTabsAlign: 'center',
dynamicTabsPosition: 'bottom',
panelTitleSelector: '.slide-nav',
dynamicArrows: true,
dynamicArrowsGraphical: true,
hideSideArrows: true,
hoverArrows: false,
hoverArrowDuration: 250,
autoSlide: true,
continuous: true,
autoSlideInterval: 5000,
autoSlideDirection: 'right',
slideEaseFunction: 'easeOutCirc',
heightEaseFunction: 'easeOutCirc'
});
//Set transitions for tab changes and activate first tab
$('.sub-menu a:visible').on('click', function(e) {
e.preventDefault();
$('.sub-menu a.active').removeClass('active');
$('.tab:visible').hide();
window.scrollTo(0, 0);
$(this.hash).fadeIn('slow');
if($('.ls-nav:visible a').length < 2) {
$('.ls-wrapper:visible').addClass('single-slide');
};
$(this).addClass('active');
}).filter(':first').click();
}
I emailed the plugin author and got the following feedback:
I would use the API to control the sliders inside. There are a few
things you could do...
var api = $.data( $('#slider')[0], 'liquidSlider');
This will store the slider as an object and give you access to its
functions.
api.setNextPanel(1)
This will set the panel to the first one. So you would have to set up
an event that sets all the sliders to the first panel based on the
action you desire. I'm assuming you would want to use the
pretransition function in the parent slider.
Here is some more information:
https://kevinbatdorf.github.io/liquidslider/examples/page1.html#advanced-controls
I applied this method and initially could only get it to work on the slideshow within the first tab. So I had to restructure the selector for liquidslider and apply the the technique to each tab. There's probably a more efficient way, but this is what I got to work:
//Use liquid slider to setup slides within tabbed content
$('#tab1-images, #tab2-images, #tab3-images, #tab4-images').liquidSlider({
preloader: true,
autoHeight: false,
dynamicTabs: true,
dynamicTabsHtml: true,
dynamicTabsAlign: 'center',
dynamicTabsPosition: 'bottom',
panelTitleSelector: '.slide-nav',
dynamicArrows: true,
dynamicArrowsGraphical: true,
hideSideArrows: true,
hoverArrows: false,
hoverArrowDuration: 250,
autoSlide: true,
continuous: true,
autoSlideInterval: 5000,
autoSlideDirection: 'right',
slideEaseFunction: 'easeOutCirc',
heightEaseFunction: 'easeOutCirc'
});
//Reset slideshows to first image on tab click
$('.sub-menu li:nth-child(1n) a').on('click', function() {
var tabImages = '#tab1-images';
if($(tabImages).length) {
var api = $.data( $(tabImages)[0], 'liquidSlider');
api.setNextPanel(0);
}
})
$('.sub-menu li:nth-child(2n) a').on('click', function() {
var tabImages = '#tab2-images';
if($(tabImages).length) {
var api = $.data( $(tabImages)[0], 'liquidSlider');
api.setNextPanel(0);
}
})
$('.sub-menu li:nth-child(3n) a').on('click', function() {
var tabImages = '#tab3-images';
if($(tabImages).length) {
var api = $.data( $(tabImages)[0], 'liquidSlider');
api.setNextPanel(0);
}
})
$('.sub-menu li:nth-child(4n) a').on('click', function() {
var tabImages = '#tab4-images';
if($(tabImages).length) {
var api = $.data( $(tabImages)[0], 'liquidSlider');
api.setNextPanel(0);
}
})
//Set transitions for tab changes and activate first tab
$('.sub-menu a:visible').on('click', function(e) {
e.preventDefault();
$('.sub-menu a.active').removeClass('active');
$('.tab:visible').hide();
window.scrollTo(0, 0);
$(this.hash).fadeIn('slow');
//Add class to single-image slides, so navigation elements can be hidden with css
if($('.ls-nav:visible a').length < 2) {
$('.ls-wrapper:visible').addClass('single-slide');
};
$(this).addClass('active');
}).filter(':first').click();
I am trying to make the bxslider cycle through three slides and then return to the first slide and stop the slideshow in that position. I've tried different bits of code but I can't find anything that specifically addresses this kind of action. Any help is appreciated.
$(document).ready(function(){
$('.bxslider').bxSlider({
auto: true,
autoControls: true,
pause: 5000,
slideMargin: 0
});
});
The simplest way I can think of would be to insert a second copy of the first slide at the end so you have three slides and then another copy of the first and you tell it not to auto-repeat.
$(document).ready(function() {
$('.bxslider').bxSlider({
auto: true,
autoControls: true,
pause: 5000,
infiniteLoop: false, // don't auto-repeat
slideMargin: 0
});
});
Beyond that, you could specify a callback and after the third slide finishes displaying, you could stop the auto-advance and then tell it to goto the first slide.
$(document).ready(function() {
var slider = $('.bxslider').bxSlider({
auto: true,
autoControls: true,
pause: 5000,
infiniteLoop: false,
slideMargin: 0,
onSlideNext: function($slideElement, oldIndex, newIndex) {
if (newIndex >= 3) {
slider.stopAuto();
slider.goToSlide(0);
}
}
});
});
If you only have three slides (a fact you haven't included that would have helped us), then perhaps you won't get an onSlideNext event when infiniteLoop is off. In that case, you could use the onSlideAfter method and trigger after showing the third slide.
$(document).ready(function() {
var slider = $('.bxslider').bxSlider({
auto: true,
autoControls: true,
pause: 5000,
infiniteLoop: false,
slideMargin: 0,
onSlideAfter: function($slideElement, oldIndex, newIndex) {
if (newIndex >= 2) {
slider.stopAuto();
setTimeout(function() {
slider.goToSlide(0);
}, 5000); // put whatever time here you want the 3rd slide to show
}
}
});
});
Did you try this using callback?
var slider = $('.bxslider').bxSlider(options); //your default options here.
$('.bxslider').bxSlider({
onSlideAfter: function($slideElement, oldIndex, newIndex){
//if slide number is 3
if(newIndex === 2){
slider.goToSlide(0);
slider.stopAuto();
}
});
What this code will do is, it will callback onSlideAfter function as soon as the slide is changed.. If the slide index is 3 then the code will stop autoplay after going to first slide..
Used callbacks and methods :
onSlideAfter (callback)
goToSlide (method)
Reference here : http://bxslider.com/options