Bootstrap tabs inside Owl carousel - javascript

I've seen a lot of questions about placing an Owl carousel control inside a Bootstrap tab pane. For instance, Owl Carousel not working inside Bootstrap Tabs and Owl Carousel broken inside tab panel.
I'd like to implement the opposite: to place Bootstrap tab panes inside a slide (div) within Owl carousel. Unfortunately, it doesn't work: clicking on a button group doesn't switch the tabs. If I get the slide outside of the carousel, it starts working. I've found what the problem is. Owl Carousel creates copies of the slide (owl-item cloned) to make the slides look looped. As the result, there are several button groups with the same id and name. They are conflicting, so switching tabs doesn't work.
Is there a way to workaround the issue somehow? Or Owl carousel supports simple, cloneable, types of slides only?
If I set loop to false, it helps, but I'd like to keep the slides looped.
$('.owl-carousel').owlCarousel({
items: 1,
loop: false, // <--------
nav: true,
});

Try this
<!DOCTYPE html>
<html>
<head>
<title>OwlCarousel Slider</title>
<link rel="stylesheet" media="all" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" media="all" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.2.0/assets/owl.carousel.min.css">
<link rel="stylesheet" media="all" href="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.2.0/assets/owl.theme.default.min.css">
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12">
<div>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">Home</li>
<li role="presentation">Profile</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="home">
<div id="owl-example" class="owl-carousel">
<div> Your Content Tab 1</div>
<div> Your Content Tab 1 </div>
<div> Your Content Tab 1</div>
<div> Your Content Tab 1 </div>
<div> Your Content Tab 1</div>
<div> Your Content Tab 1</div>
<div> Your Content Tab 1</div>
</div>
</div>
<div role="tabpanel" class="tab-pane" id="profile">
<div id="owl-example" class="owl-carousel">
<div> Your Content Tab 2</div>
<div> Your Content Tab 2</div>
<div> Your Content Tab 2</div>
<div> Your Content Tab 2</div>
<div> Your Content Tab 2Tab 2Tab 2</div>
<div> Your Content Tab 2Tab 2</div>
<div> Your Content Tab 2</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<script src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/OwlCarousel2/2.2.0/owl.carousel.min.js"></script>
<script>
$(document).ready(function() {
$(".owl-carousel").owlCarousel({
speed: 800,
margin:15,
autoplay:true,
nav:false,
responsive:{
0:{
items:1
},
600:{
items:3
},
1000:{
items:3
}
}
});
$('a[data-toggle="tab"]').on('shown.bs.tab', function (e) {
e.target // newly activated tab
e.relatedTarget // previous active tab
$(".owl-carousel").trigger('refresh.owl.carousel');
});
});
</script>
</body>
</html>

Related

How to add animation on owlCarousel slider contents

How to animate each content layer with selected css animation with owlCarousel slide?
Here what I did, but I can't make it work properly.
HTML
<div class="owl-carousel owl-theme">
<div class="slide-item-1">
<div class="layer layer1">
<div data-animate="animated fadeInLeft">
<h1>I'm layer 1</h1>
</div>
</div>
<div class="layer layer2">
<div data-animate="animated fadeInLeft">
<h2>I'm layer 2</h2>
</div>
</div>
</div>
<div class="slide-item-2">
<div class="layer layer1">
<div data-animate="animated fadeInLeft">
<h1>I'm layer 1</h1>
</div>
</div>
<div class="layer layer2">
<div data-animate="animated fadeInLeft">
<h2>I'm layer 2</h2>
</div>
</div>
<div class="layer layer3">
<div data-animate="animated fadeInLeft">
<h2>I'm layer 3</h2>
</div>
</div>
</div>
</div>
JavaScript
jQuery(document).ready(function($) {
$('.owl-carousel').owlCarousel({
items:1,
dots: true,
nav: false,
animateOut: 'fadeOutLeft',
animateIn: 'fadeInRight',
autoplay:true,
onTranslated: animateSlide,
onTranslate: removeAnimation
});
function removeAnimation() {
var item = $(".owl-item .layer");
item.removeClass(item.children().data('animate'));
}
function animateSlide() {
var item = $(".owl-item.active .layer");
item.addClass(item.children().data('animate'));
}
});
Now I have this issues,
It shows content first and then animate, I mean contents don't come with animated, it comes first then animate.
First slide 'layer' DIV content don't animate content in first view but good after come back from other slides..
Last slide 'layer' DIV content animation works on first time view but next time don't work. What I can see is it add double animation or don't remove animation class after slide to another.
Middle slides are working fine without any problem.
There are different events of the owl-carousel where you can bind animate.css animations to.
In the example I used the change.owl.carousel event:
change.owl.carousel
Type: attachable
Callback: onChange
Parameter: property
When a property is going to change its value.
The function itself adds the animation class (addClass()) and removes it again after the animation end is triggered (one(...) followed by removeClass()).
var owl = $('.custom1').owlCarousel({
animateOut: 'slideOutDown',
animateIn: 'flipInX',
items:1,
margin:30,
stagePadding:30,
smartSpeed:450,
loop: true,
dots: true,
autoplay: true,
});
owl.on('change.owl.carousel', function (event) {
var el = event.target;
$('h4', el).addClass('slideInRight animated')
.one('webkitAnimationEnd mozAnimationEnd MSAnimationEnd oanimationend animationend', function () {
$('h4', el).removeClass('slideInRight animated');
});
});
<link href="https://owlcarousel2.github.io/OwlCarousel2/assets/owlcarousel/assets/owl.carousel.min.css" rel="stylesheet"/>
<link href="https://owlcarousel2.github.io/OwlCarousel2/assets/owlcarousel/assets/owl.theme.default.min.css" rel="stylesheet"/>
<link href="https://owlcarousel2.github.io/OwlCarousel2/assets/css/docs.theme.min.css" rel="stylesheet"/>
<link href="https://owlcarousel2.github.io/OwlCarousel2/assets/css/animate.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<script src="https://owlcarousel2.github.io/OwlCarousel2/assets/owlcarousel/owl.carousel.js"></script>
<section id="demos">
<div class="custom1 owl-carousel owl-theme">
<div class="item"><h4>1</h4>
</div><div class="item"><h4>2</h4>
</div><div class="item"><h4>3</h4>
</div><div class="item"><h4>4</h4>
</div><div class="item"><h4>5</h4>
</div><div class="item"><h4>6</h4>
</div>
</div>
</section>

Call a function when tab selected in material design light

I have three tabs on the page.
<!-- Tabs -->
<div class="mdl-layout__tab-bar">
Plots
Plots data
Report
</div>
I need to re-draw plots when Plots tab is selected. I've tried to onclick="redraw_plots();" to the Plots tab, but function is called too fast before tab is activated. Any way to get an event when this tab activates?
Thank you.
It's happen because element inline event are the first event to be executed.
To Execute after MDL tab event you can do like this:
With Javascript Vanilla:
First add an id on link
<a id="#plots-tab" href="#plots-tab" class="mdl-layout__tab is-active"">Plots</a>
Second add an event listener
document.getElementById("#plots-tab").addEventListener("click", function(){
redraw();
});
Or with Jquery:
Add on event listener on element
$('a[href="#plots-tab"]').on('click',function(){
redraw();
});
For me it was not enough to hook to the click event.
A timeout of at least 0 milliseconds was necessary otherwise the content display it will still be set to none (tested on Chrome) and any drawing of your own that requires width calculations might fail.
Check the attached snippet and verify that without setTimeout, on the click event the tab content display is set to none and not 'block'. MDL must play an animation for smooth transition that cause absolute position drawing issues.
$('.mdl-layout__tab-bar').children().each(function(){
$(this).on('click', function(){
var timeout = 0;
var targetContent = this.getAttribute('href');
setTimeout(function(){
if($(targetContent).css('display') == "block"){
console.info("tab content is now visible after a timeout of %s millisenconds", timeout);
}
else{
console.warn("increase timeout to make sure that content is visible");
}
}, timeout);
});
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="https://code.getmdl.io/1.3.0/material.indigo-pink.min.css">
<script defer src="https://code.getmdl.io/1.3.0/material.min.js"></script>
<!-- Simple header with scrollable tabs. -->
<div class="mdl-layout mdl-js-layout mdl-layout--fixed-header">
<header class="mdl-layout__header">
<div class="mdl-layout__header-row">
<!-- Title -->
<span class="mdl-layout-title">Title</span>
</div>
<!-- Tabs -->
<div class="mdl-layout__tab-bar mdl-js-ripple-effect">
Tab 1
Tab 2
Tab 3
Tab 4
Tab 5
Tab 6
</div>
</header>
<div class="mdl-layout__drawer">
<span class="mdl-layout-title">Title</span>
</div>
<main class="mdl-layout__content">
<section class="mdl-layout__tab-panel is-active" id="scroll-tab-1">
<div class="page-content">
Tab 1
</div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-2">
<div class="page-content">
Tab 2
</div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-3">
<div class="page-content">
Tab 3
</div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-4">
<div class="page-content">
Tab 4
</div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-5">
<div class="page-content">
Tab 5
</div>
</section>
<section class="mdl-layout__tab-panel" id="scroll-tab-6">
<div class="page-content">
Tab 6
</div>
</section>
</main>
</div>
Another solution without adding anything special to the a tags would be
$("a.mdl-layout__tab").click(event => {
console.log("Tab switched!");
});

How to not repeat myself in jquery

I have found myself writing similar code a few times and im not sure of the best way to do it.
i have a few divs:
<div id="gallery1">
some content
</div>
<div id="gallery2">
some content
</div>
<div id="gallery3">
some content
</div>
<div id="gallery4">
some content
</div>
<div id="gallery5">
some content
</div>
<div id="gallery6">
some content
</div>
i will hide gallery 2 - 6 in css and then show them using jquery with the following:
$(document).ready(function(){
// shows gallery 1
$('.gallery1show').click(function(){
// prevents link from going anywhere
event.preventDefault();
// shows gallery 1
$('#gallery1').show();
// hides other galleries
$('#gallery2').hide();
$('#gallery3').hide();
$('#gallery4').hide();
$('#gallery5').hide();
$('#gallery6').hide();
});
// shows gallery 2
$('.gallery2show').click(function(){
// prevents link from going anywhere
event.preventDefault();
// shows gallery 2
$('#gallery2').show();
// hides other galleries
$('#gallery1').hide();
$('#gallery3').hide();
$('#gallery4').hide();
$('#gallery5').hide();
$('#gallery6').hide();
});
// shows gallery 3
$('.gallery3show').click(function(){
// prevents link from going anywhere
event.preventDefault();
// shows gallery 3
$('#gallery3').show();
// hides other galleries
$('#gallery1').hide();
$('#gallery2').hide();
$('#gallery4').hide();
$('#gallery5').hide();
$('#gallery6').hide();
});
... etc
});
i got a feeling that rather than using gallery1, gallery2 etc i should just give each div a class of gallery and then use this and not this in jquery. but im not sure where to start.
any advice?
I would do something like this:
var galleries = $('.gallery');
$('.show-gallery').on('click', function(e) {
e.preventDefault();
var gallery = $($(this).attr('href'));
galleries.not(gallery).hide();
gallery.show();
});
.gallery + .gallery {display:none;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="gallery1" class="gallery">gallery 1</div>
<div id="gallery2" class="gallery">gallery 2</div>
<div id="gallery3" class="gallery">gallery 3</div>
<div id="gallery4" class="gallery">gallery 4</div>
<div id="gallery5" class="gallery">gallery 5</div>
Gallery 1
Gallery 2
Gallery 3
Gallery 4
Gallery 5
Make all div a common class "gallery" and hide it
$(".gallery").hide();
and show only that gallery which is require
$("#gallery1").show();
or write code is such a way that jQuery identify div dynamically to show it.
$('.show').on('click',function() {
$('.gallery').hide();
$($(this).attr('href')).show();
});
.gallery {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
Show gallery 1
Show gallery 2
Show gallery 3
Show gallery 4
Show gallery 5
Show gallery 6
<div id="gallery1" class="gallery">
some content 1
</div>
<div id="gallery2" class="gallery">
some content 2
</div>
<div id="gallery3" class="gallery">
some content 3
</div>
<div id="gallery4" class="gallery">
some content 4
</div>
<div id="gallery5" class="gallery">
some content 5
</div>
<div id="gallery6" class="gallery">
some content 6
</div>
A bit late, but here's a working example : https://jsfiddle.net/
Guess you have given partial of your html code there, hence I assume it has some buttons to trigger the show action of gallery. Below is on that assumption how your HTML has to be
<div class="galleries">
<div id="gallery1" class="gallery active">
gallery 1
</div>
<div id="gallery2" class="gallery">
gallery 2
</div>
<div id="gallery3" class="gallery">
gallery 3
</div>
<div id="gallery4" class="gallery">
gallery 4
</div>
<div id="gallery5" class="gallery">
gallery 5
</div>
<div id="gallery6" class="gallery">
gallery 6
</div>
</div>
<div class="gallery-buttons">
<button data-id="1">Gallery 1</button> <button data-id="2">Gallery 2</button>
<button data-id="3">Gallery 3</button>
<button data-id="4">Gallery 4</button>
<button data-id="5">Gallery 5</button>
<button data-id="6">Gallery 6</button>
</div>
and css
.gallery{
display:none;
}
.gallery.active{
display:block;
}
and the js
$('.gallery-buttons button').on('click',function(){
var id = $(this).attr('data-id');
$('.gallery.active').removeClass('active');
$('.gallery[id="gallery'+id+'"]').addClass('active');
});
Here is a demo pen http://codepen.io/anon/pen/zGJaNM

Failed to execute getComputedStyle when using Swiper

I am using the swiper in the jquery version from idangerous. I load and initialize it with require.js like this:
define(['jquery','swiper'],function($){
$( document ).ready(function() {
var mySwiper = new Swiper ('.swiper-container', {
// Optional parameters
direction: 'horizontal',
loop: true,
speed:100,
// If we need pagination
// Navigation arrows
nextButton: '.m-stage-button-next',
prevButton: '.m-stage-button-prev',
});
});
});
<div style="width: auto; height: 300px;" class="swiper-wrapper swiper-container">
<div class="m-stage-slide swiper-slide">
<a href="#">
<img class="m-stage-slide-image" src="../img/slide1.jpg" alt="">
</a>
<div class="m-stage-slide-content">
<div class="m-stage-slide-text">
<h1 class="m-stage-slide-heading">{{sContent.headline}}</h1>
<span class="m-stage-slide-tagline">{{sContent.text}}</span>
</div>
<span class="c-btn c-btn--tertiary c-btn--arrow">{{sContent.btn_txt}}</span>
</div>
</div>
<div class="m-stage-slide swiper-slide">
<a href="#">
<img class="m-stage-slide-image" src="../img/slide2.jpg" alt="">
</a>
<div class="m-stage-slide-content">
<div class="m-stage-slide-text">
<h1 class="m-stage-slide-heading">{{sContent.headline}}</h1>
<span class="m-stage-slide-tagline">{{sContent.text}}</span>
</div>
<span class="c-btn c-btn--tertiary c-btn--arrow">{{sContent.btn_txt}}</span>
</div>
</div>
<div class="m-stage-button-prev"></div>
<div class="m-stage-button-next"></div>
</div>
(Those {{}} thingis are right now just placeholders)
Everything is loaded and rendered fine, but as soon as I try to swipe, I get
Uncaught TypeError: Failed to execute 'getComputedStyle' on 'Window': parameter 1 is not of type 'Element'
Any hints?
Instead of this:
<div style="width: auto; height: 300px;" class="swiper-wrapper swiper-container">
</div>
Try separating out your DIV's, with the swiper container on the outside:
<div style="width: auto; height: 300px;" class="swiper-container">
<div class="swiper-wrapper"></div>
</div>
Check the quick start guide (point 3) for an example of the correct HTML markup for SwiperJS:
http://www.idangero.us/swiper/get-started/
<!-- Slider main container -->
<div class="swiper-container">
<!-- Additional required wrapper -->
<div class="swiper-wrapper">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
<div class="swiper-slide">Slide 3</div>
</div>
<!-- If we need pagination -->
<div class="swiper-pagination"></div>
<!-- If we need navigation buttons -->
<div class="swiper-button-prev"></div>
<div class="swiper-button-next"></div>
<!-- If we need scrollbar -->
<div class="swiper-scrollbar"></div>
</div>
In my case, it happens in this code/scenario (I use swiperContainer - HTMLElement - more than one time ==> logos in this example).
<!-- error code use logos twice -->
<div class="swiper-container logos">
<div class="swiper-wrapper logos">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
</div>
</div>
var mySwiper = new Swiper('.logos', {
speed: 400
});
Throw this error:
Very easy to fix this issue (Remove logos from this element <div class="swiper-wrapper logos">).
I don't exactly know, what the failure was. I switched to Swiper 2.7.x and this worked without a single problem.
Seems like Swiper 3.x and Require with almond have some problems at the moment.
I am using the swiper from idangerous in an Angular 1.5 application. I got the same error when swiping slides with mouse, no error changing slides by clicking on arrows.
For me this was a timing issue. I solved it by moving the init of the swiper var mySwiper = new Swiper('.swiper-container', {... to where the view was done rendering.
The quickest solution for this is to remove the CLASS 'logos' and add it as an ID 'logos' to the same element. After that select the ID as the selector in your javascript file.
Eg: HTML
<div id="logos" class="swiper-container"> <!-- This line is edited -->
<div class="swiper-wrapper logos">
<!-- Slides -->
<div class="swiper-slide">Slide 1</div>
<div class="swiper-slide">Slide 2</div>
</div>
</div>
Eg: JavaScript
//.logo changed to #logo on the next line
var mySwiper = new Swiper('#logos', {
speed: 400
});
This happened to me when i tried to use some code provided from a tutorial...I checked the official docs and used their example and it worked without problems
https://swiperjs.com/get-started

Adding animated captions to Owl carousel

I'm using Owl Carousel and have been trying to add animated captions (just a simple fadein on slide display) but can't seem to figure out how to do it.
I have the opacity of all the captions set to 0 and then add a class named "animate-me" (with jQuery) to the captions. The first one fades in and then all the others are constantly displayed.
Here's what I have so far on jsbin... http://jsbin.com/OGehUKEh/3/edit
You need to use Owl Carousel callbacks. I found the callbacks you need.
$("#owl-example").owlCarousel({
beforeMove: function(){
// BEFORE going to the next slide (hide captions)
},
afterMove: function(){
// AFTER going to next slide (show captions)
}
})
I've successfully done this using jCapSlide (http://tympanus.net/codrops/2009/11/23/jcapslide-a-jquery-image-caption-plugin/).
Here's the HTML:
<div class="owl-carousel">
<div class="item" id="id_a"> <!-- The ID is for jCapSlide -->
<img alt="text" src="imagelocation"><!-- This is my image -->
<div class="overlay" style="display:none;"></div> <!-- this is the jCapSlide code -->
<div class="ic_caption">
<h3>TITLE To display</h3>
<p class="ic_text">Caption</p>
</div>
</div>
<div class="item" id="id_b">
<img alt="text" src="another image">
<div class="overlay" style="display:none;"></div>
<div class="ic_caption">
<h3>Title 2</h3>
<p class="ic_text">More Text</p>
</div>
</div>
<!-- More pictures in the same fashion as above -->
</div>
Include the CSS in the HEAD
<link rel="stylesheet" href="/css/owl.carousel.css">
<link rel="stylesheet" href="/css/caption/style.css">
Include the JScript just before the
<script src="/js/jquery-1.11.1.js"></script>
<script src="/js/jquery.capSlide.js"></script>
<script src="/js/owl.carousel.js"></script>
<script type="text/javascript">
$(window).load(function(){
$(".owl-carousel").owlCarousel({responsiveClass:true, autoplay:true, autoplayTimeout: 1000, autoplayHoverPause:true, autoWidth:true, loop:true});
$("#id_a").capslide({caption_color : '#FFFFFF', caption_bgcolor : '#002296', overlay_bgcolor : '#002296', border : '', showcaption : true});
$("#id_b").capslide({caption_color : '#FFFFFF', caption_bgcolor : '#002296', overlay_bgcolor : '#002296', border : '', showcaption : true});
</script>
jCapSlide is very flexible, and you can mess with the CSS and JS to get the exact colours/animation you want.
Debbie

Categories