Show "X" number of page dots on Flickity plugin - javascript

I using the flickity plugin for a slideshow on my website and I want to show the dots on the image to allow the user to navigate the images.
Here is a link to the plugin https://flickity.metafizzy.co/
Is it possible to show, for example 4 dots even if there is 10 images. I dont always know the number of images so if I could just cap the dots to 4 and update every time the image is swithced?
Here is some of my code:
$('[data-venue-id="' + venueId + '"]').find('.flickity-button-inset').each(function () {
$(this).flickity({
// options
lazyLoad: true,
wrapAround: true,
pageDots: true,
contain: true,
adaptiveHeight: false,
imagesLoaded: true,
setGallerySize: false
//fade: true
});
});
This is an example of the dots on the images. I only want to display a certain number
Thanks in advance

As mentioned in my comment above, I believe the easiest would be with using asNavFor.
.carousel-main {
counter-reset: carousel-cell;
width: 100%;
}
.carousel-main-item {
width: 100%;
background: #f1f1f1;
text-align: center;
line-height: 100px;
}
.carousel-nav {
width: 50px;
margin: 20px auto;
}
.carousel-nav-item {
width: 10px;
height: 10px;
background: #000;
border-radius: 50%;
margin: 5px;
cursor: pointer;
}
.carousel-nav-item.is-selected {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/flickity/2.2.2/flickity.pkgd.min.js" integrity="sha512-cA8gcgtYJ+JYqUe+j2JXl6J3jbamcMQfPe0JOmQGDescd+zqXwwgneDzniOd3k8PcO7EtTW6jA7L4Bhx03SXoA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/flickity/2.2.2/flickity.min.css" integrity="sha512-BiFZ6oflftBIwm6lYCQtQ5DIRQ6tm02svznor2GYQOfAlT3pnVJ10xCrU3XuXnUrWQ4EG8GKxntXnYEdKY0Ugg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<div class="carousel-main" data-flickity='{"pageDots": false }'>
<div class="carousel-main-item">1</div>
<div class="carousel-main-item">2</div>
<div class="carousel-main-item">3</div>
<div class="carousel-main-item">4</div>
<div class="carousel-main-item">5</div>
<div class="carousel-main-item">6</div>
<div class="carousel-main-item">7</div>
</div>
<div class="carousel-nav" data-flickity='{ "asNavFor": ".carousel-main", "contain": false, "pageDots": false, "prevNextButtons": false, "draggable": false }'>
<div class="carousel-nav-item"></div>
<div class="carousel-nav-item"></div>
<div class="carousel-nav-item"></div>
<div class="carousel-nav-item"></div>
<div class="carousel-nav-item"></div>
<div class="carousel-nav-item"></div>
<div class="carousel-nav-item"></div>
</div>

I did this via an on change and ready event. I suspect there's a cleaner way of doing this.
I wanted 1,2,3 shown if 1 was selected. Otherwise n-1, n, n+1 until the last slide when it should be the last three.
$('.gallery').flickity({
cellSelector: ".gallery-item",
wrapAround: true,
prevNextButtons: true,
contain: true,
pageDots: true,
on: {
ready: function () {
if ($(this)[0].slides.length <= 3) {
$(this)[0].$element.find('.dot').addClass("show-me");
} else {
$(this)[0].$element.find('.dot').eq(0).addClass("show-me");
$(this)[0].$element.find('.dot').eq(1).addClass("show-me");
$(this)[0].$element.find('.dot').eq(2).addClass("show-me");
}
},
change: function (index) {
if ($(this)[0].slides.length <= 3) {
$(this)[0].$element.find('.dot').addClass("show-me");
} else {
$(this)[0].$element.find('.dot').removeClass("show-me");
if (index == 0) {
$(this)[0].$element.find('.dot').slice(0, 3).addClass("show-me");
} else {
if (index == ($(this)[0].slides.length - 1)) {
$(this)[0].$element.find('.dot').eq(index).addClass("show-me");
$(this)[0].$element.find('.dot').eq(index - 1).addClass("show-me");
$(this)[0].$element.find('.dot').eq(index - 2).addClass("show-me");
}
else {
$(this)[0].$element.find('.dot').eq(index).addClass("show-me");
$(this)[0].$element.find('.dot').eq(index - 1).addClass("show-me");
$(this)[0].$element.find('.dot').eq(index + 1).addClass("show-me");
}
}
}
}
}
});
CSS:
.flickity-page-dots {
li {
display: none;
}
li.show-me {
display: inline-block;
}

Related

Slick Slider styles

This question was migrated from Webmasters Stack Exchange because it can be answered on Stack Overflow.
Migrated 22 hours ago.
I'm trying to create a gallery slider using slick slider js library. A basic mobile responsive gallery carousel with a progress bar. Everything is running however I'm having trouble with some styling. I want the effect of the gallery center image to be raised above the other 2 (half) slides in the background. For some reason- I can't achieve the center padding effect and the slides are jumping a little when its on autoplay. The widths are also messed up responsively. Im not sure why none of my styles are working correctly. I attached my html code(without the actual image links) and how I initialized it in my js. I also attached some css that I had implemented (I had originally fully styled it- but I took out the styles because it really got messy).
Any advice how to proceed will be greatly appreciated
//Initialize slick slider
$(document).ready(function() {
$(".coverflow").slick({
dots: false,
arrows: true,
infinite: true,
centerMode: true,
centerPadding: '150px',
variableWidth: true,
focusOnSelect: true,
speed: 1000,
autoplay: true,
autoplaySpeed: 2500,
slidesToShow: 3,
slidesToScroll: 1,
responsive: [{
breakpoint: 1024,
settings: {
slidesToShow: 1,
slidesToScroll: 1,
},
}, ],
});
});
//add slick-center class to create the carousel effect
$(document).ready('.coverflow').on('beforeChange', function(event, slick, currentSlide, nextSlide) {
$('.slick-center').removeClass('slick-center');
$('.slick-slide').eq(nextSlide).addClass('slick-center');
})
//add the slick container class
;
$(document).ready('.coverflow').on('beforeChange', function(event, slick, currentSlide, nextSlide) {
$('.slick-center .slide-container').removeClass('slick-center');
$('.slick-slide').eq(nextSlide).find('.slide-container').addClass('slick-center');
});
//progress bar for slick slider
$(document).ready(function() {
var $slider = $('.coverflow');
var $progressBar = $('.progress');
var $progressBarLabel = $('.slider__label');
$slider.on('beforeChange', function(event, slick, currentSlide, nextSlide) {
var calc = ((nextSlide) / (slick.slideCount - 1)) * 100;
$progressBar
.css('background-size', calc + '% 100%')
.attr('aria-valuenow', calc);
$progressBarLabel.text(calc + '% completed');
});
});
.progress {
max-width: 800px!important;
margin-right: auto;
margin-left: auto;
display: block;
width: 75%;
height: 3px;
border-radius: 3px;
overflow: hidden;
background-color: #5B5B5B;
background-image: linear-gradient(to right, #FA5927, #FA5927);
background-repeat: no-repeat;
background-size: 0 100%;
transition: background-size .4s ease-in-out;
margin-top: 55px;
}
.slide-number {
color: #FA5927;
font-family: 'PT SANS';
font-size: var(--wp--preset--font-size--medium)!important;
padding: 10px;
}
.slide-container {
margin-right: 50px;
margin-left: 50px;
}
#media only screen and (max-width:880px) {
/*--gallery slider--*/
.coverflow img {
width: 70%;
margin: auto;
}
}
#media only screen and (max-width:787px) {
/*--gallery slider--*/
.coverflow img {
width: 50%;
margin: auto;
}
}
#media only screen and (max-width:414px) {
/*--gallery slider--*/
.coverflow img {
width: 35%;
margin: auto;
}
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" rel="stylesheet" />
<link href="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick-theme.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.6.3.js" integrity="sha256-nQLuAZGRRcILA+6dMBOvcRh5Pe310sBpanc6+QBmyVM=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/slick-carousel/1.8.1/slick.min.js"></script>
<div class="slider">
<section class="coverflow">
<div class="slide-container">
<span class="slide-number">01</span>
<img src="https://mdbcdn.b-cdn.net/img/new/slides/041.webp">
</div>
<div class="slide-container">
<span class="slide-number">02</span>
<img src="https://mdbcdn.b-cdn.net/img/new/slides/041.webp">
</div>
<div class="slide-container">
<span class="slide-number">03</span>
<img src="https://mdbcdn.b-cdn.net/img/new/slides/041.webp">
</div>
<div class="slide-container">
<span class="slide-number">04</span>
<img src="https://mdbcdn.b-cdn.net/img/new/slides/041.webp">
</div>
<div class="slide-container">
<span class="slide-number">05</span>
<img src="https://mdbcdn.b-cdn.net/img/new/slides/041.webp">
</div>
<div class="slide-container">
<span class="slide-number">06</span>
<img src="https://mdbcdn.b-cdn.net/img/new/slides/041.webp">
</div>
</section>
<div class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100">
<span class="slider__label sr-only">
</span>
</div>
<!-- end content -->
</div>

Why are my swiper js slides very big and not showing the right amount I specified

I am trying to build a swiper slider with the following layout:
<div id="brokerCarousel" class="swiper">
<div class="swiper-container">
<div class="swiper-wrapper">
#foreach($partners as $partner)
<div class="swiper-slide">
<img src="{{ $partner->media('logo')->first() !== null ? $partner->media('logo')->first()->getUrl(800,600,'canvas') : '' }}" alt="{{ $partner->name }}">
</div>
#endforeach
</div>
</div>
</div>
I then have my JS code:
brokerCarousel() {
if (document.getElementById('brokerCarousel')) {
new Swiper('#brokerCarousel .swiper-container', {
slidesPerView: 10,
spaceBetween: 30,
autoplay: {
delay: 2500,
},
breakpoints: {
576: {
slidesPerView: 2,
},
768: {
slidesPerView: 3,
},
1200: {
slidesPerView: 5,
}
}
});
}
}
Where I set slides to 5.
My scss:
#brokerCarousel {
&.swiper{
width: 100%;
height: 100%;
.swiper-container {
max-height: 100%;
.swiper-wrapper {
.swiper-slide {
background-color: #fff;
padding: 30px;
border-radius: 10px;
img {
height: 200px;
width: auto;
}
}
}
}
}
}
But this is what my slides look like:
As you can see there are only two slides in view which is wrong by itself but they are also very wide. When I inspect the .swiper-slide in my inspector I see this style is applied: width: 1600px; margin-right: 30px;. My container is 1440px so one slide can never be 1600px when I have it set to 5.
What am I missing?

Tippy.js custom theme not being applied

I want to change the style of a tooltip (from tippy.js) and am doing exactly as being told in the docs here:
Themes are created by including a class on the tippy-tooltip element as part of a selector in the form .tippy-tooltip.x-theme. Let's demonstrate this by creating our own theme called tomato:
.tippy-tooltip.tomato-theme {
background-color: tomato;
color: yellow;
}
To apply the theme, specify a theme prop without the -theme suffix:
tippy('button', {
theme: 'tomato',
});
But for some reason my tooltip stays the default color, why?
I added this style:
.tippy-tooltip.tomato-theme {
background-color: tomato;
color: yellow;
}
.infosvg {
width: 20px;
}
tooltippy {
position: absolute;
top: 150px;
left: 300px;
}
My html
<span class="tooltippy">
<img class="infosvg" src="assets/images/custom/icon_info.svg">
<div class="tooltipcontent darktext">Test</div>
</span>
My js:
$( ".tooltippy" ).each(function( i ) {
tippy(this, {
trigger: 'click',
allowHTML: true,
placement: 'right',
animation: 'scale-subtle',
interactive: true,
theme: 'tomato',
content: function (reference) {
return reference.querySelector('.tooltipcontent');
}
});
});
What is going wrong? I've tried different colors in hex or in text like above but it stays the default tooltip.
According to the documentation you need to change this line:
.tippy-tooltip.tomato-theme {
to:
.tippy-box[data-theme~='tomato'] {
And, in order to add the style to the arrow you need also:
.tippy-box[data-theme~='tomato'][data-placement^='right'] > .tippy-arrow::before {
The snippet:
$( ".tooltippy" ).each(function( i ) {
tippy(this, {
trigger: 'click',
allowHTML: true,
placement: 'right',
animation: 'scale-subtle',
interactive: true,
theme: 'tomato',
content: function (reference) {
return reference.querySelector('.tooltipcontent');
}
});
});
.tippy-box[data-theme~='tomato'] {
background-color: tomato;
color: yellow;
}
.tippy-box[data-theme~='tomato'][data-placement^='right'] > .tippy-arrow::before {
border-right-color: tomato;
}
.infosvg {
width: 20px;
}
.tooltippy {
position: relative;
top: 150px;
left: 300px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/#popperjs/core#2/dist/umd/popper.min.js"></script>
<script src="https://unpkg.com/tippy.js#6/dist/tippy-bundle.umd.js"></script>
<div>
<span class="tooltippy">
<img class="infosvg" src="https://upload.wikimedia.org/wikipedia/commons/e/e4/Infobox_info_icon.svg">
<div class="tooltipcontent darktext">Test</div>
</span>
</div>

Why does the last container flicker?

I'm trying to create a set of div's that will animate on hover. I'm using jQuery and the HoverIntent plugin to animate it.
The HTML
<body>
<div class="wrapper">
<div class="grow" style="background-color:#03045E;"></div>
<div class="grow" style="background-color:#0077B6;"></div>
<div class="grow" style="background-color:#00B4D8;"></div>
<div class="grow" style="background-color:#90E0EF;"></div>
</div>
</body>
... and the JS Code
$(function() {
$('.grow').hoverIntent({
over : function() {
$('.grow').animate({
'width':'15%'
},{duration:400,queue:false});
$(this).animate({
'width':'55%'
},{duration:400,queue:false});
},
out : function() {
//we need to check if the mouse is outside the main object to fire a back to original state. Hence, the mouse out effect on the containers itself should do nothing.
}
});
$('.wrapper').hoverIntent({
out : function() {
$('.grow').animate({
'width':'25%'
});
}
});
});
It is available here - https://jsfiddle.net/be0u3hfx/12/
I cant seem to understand why the last div flickers on hover of any div! Help!?
It's because during the size changes, the widths of the elements will occasionally amount to more than 100% total, and when that happens, the browser briefly wraps the last element, making it appear below the first. To prevent that, add display: flex; to your wrapper's CSS rules.
Fixed code:
$(function() {
$('.grow').hoverIntent({
sensitivity: 1, // sensitivity threshold
interval: 10, // milliseconds for onMouseOver polling interval
timeout: 500, // number = milliseconds delay before onMouseOut
over: function() {
$('.grow').animate({
'width': '15%'
}, {
duration: 400,
queue: false
});
$(this).animate({
'width': '55%'
}, {
duration: 400,
queue: false
});
},
out: function() {}
});
$('.wrapper').hoverIntent({
over: () => {},
out: function() {
$('.grow').animate({
'width': '25%'
});
}
});
});
* {
box-sizing: border-box;
}
body {
background-color: black;
margin: 0 auto;
padding: 10px;
height: 100vh;
width: 100%;
}
.wrapper {
padding: 10px;
height: 100%;
background: #fff;
display: flex;
}
.grow {
box-sizing: border-box;
height: 100%;
/* Original height */
width: 25%;
/* Original width */
float: left;
/* Just for presentation (Not required) */
position: relative;
/* Just for presentation (Not required) */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery.hoverintent/1.10.1/jquery.hoverIntent.min.js"></script>
<div class="wrapper">
<div class="grow" style="background-color:#03045E;"></div>
<div class="grow" style="background-color:#0077B6;"></div>
<div class="grow" style="background-color:#00B4D8;"></div>
<div class="grow" style="background-color:#90E0EF;"></div>
</div>

Create a new array in an .each loop

I am using swiper.js to create a nested swiper for my website. I am using the renderBullet function to create a custom pagination for it. This works great for the parent swiper and the first nested swiper.
However, when there are more nested swipers, all nested swipers have the pagination of the first nested swiper.
$('.swiper-container-nested').each(function () {
var namesNested = [];
$(".c-home__slide-nested.swiper-slide").each(function () {
namesNested.push($(this).data("name"));
});
var swiperNested = new Swiper('.c-home__swiper-nested.swiper-container-nested', {
speed: 0,
spaceBetween: 100,
direction: 'horizontal',
nested: true,
autoHeight: true,
pagination: {
el: '.swiper-pagination-nested',
clickable: 'true',
type: 'bullets',
renderBullet: function (index, className) {
return '<li class="' + className + ' c-link secondary">' + (namesNested[index]) + '</li>';
},
bulletClass: 'c-menu__item',
bulletActiveClass: 'active',
},
allowTouchMove: false,
a11y: {
prevSlideMessage: 'Previous section',
nextSlideMessage: 'Next section',
firstSlideMessage: 'This is the first section',
lastSlide: 'This is the last section',
paginationBulletMessage: 'Go to section {{index}}'
},
});
});
I know that I somehow need to iterate the following bit for each nested swiper, but I don't know how:
var namesNested = [];
$(".c-home__slide-nested.swiper-slide").each(function () {
namesNested.push($(this).data("name"));
});
Hard to know your problem only by JS (Without HTML markup // complete-example).
No known issue with Swiper Pagination related to custom pagination
Maybe the code-snippet below will be helpful.
Nested each loop
In your code looks like you always loop throw the same element(For the nested-array) - i solve this by using this:
.children() (swiper-wrapper element) ==> .children() (swiper-slide elements)
$this.children().children().each(function(index, element) {
/*do something*/
Related stackoverflow Q:
Targeting $(this) within nested for each loops in jQuery
$.each() with nested array
Nested swipers - Get Custom pagination text from data-attribute (Jquery):
var swiperH = new Swiper(".swiper-container-h", {
spaceBetween: 50,
pagination: {
el: ".swiper-pagination-h",
clickable: true
}
});
// 1. outer loop //
$(".swiper-container-nested").each(function(index, element) {
var $this = $(this);
var fruitsArray = [];
// 1.1. nested loop
$this.children().children().each(function(index, element) {
fruitsArray.push($(this).data("fruit"));
});
/* create swiper objects */
$this.addClass("instance-" + index);
var swiperNested = new Swiper(".instance-" + index, {
direction: "vertical",
spaceBetween: 50,
pagination: {
el: ".swiper-pagination-nested",
clickable: true,
renderBullet: function(index, className) {
return (
'<span class="' +
className +
'">' +
(index + 1) +
"." +
fruitsArray[index] +
"</span>"
);
}
}
});
});
html,
body {
position: relative;
height: 100%;
}
body {
background: #eee;
font-family: Helvetica Neue, Helvetica, Arial, sans-serif;
font-size: 14px;
color: #000;
margin: 0;
padding: 0;
}
.swiper-container {
width: 100%;
height: 100%;
}
.swiper-slide {
text-align: center;
font-size: 18px;
background: #fff;
/* Center slide text vertically */
display: -webkit-box;
display: -ms-flexbox;
display: -webkit-flex;
display: flex;
-webkit-box-pack: center;
-ms-flex-pack: center;
-webkit-justify-content: center;
justify-content: center;
-webkit-box-align: center;
-ms-flex-align: center;
-webkit-align-items: center;
align-items: center;
}
.swiper-container-v {
background: #eee;
}
.swiper-pagination-nested .swiper-pagination-bullet {
width: auto;
height: 20px;
text-align: center;
border-radius: 5px;
line-height: 20px;
font-size: 12px;
padding: 5px 9px;
color:#000;
opacity: 1;
background: rgba(0,0,0,0.2);
}
.swiper-pagination-nested .swiper-pagination-bullet-active {
color:#fff;
background: red;
}
ul.swiper-wrapper,
li.swiper-slide {
padding: 0px;
margin: 0px;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/css/swiper.min.css" rel="stylesheet"/>
<!-- Swiper -->
<main class="swiper-container swiper-container-h">
<ul class="swiper-wrapper">
<li class="swiper-slide">
<div class="swiper-container swiper-container-nested">
<div class="swiper-wrapper">
<div data-fruit="Orange" class="swiper-slide">1. Orange</div>
<div data-fruit="Apple" class="swiper-slide">2. Apple</div>
<div data-fruit="Cranberry" class="swiper-slide">3. Cranberry</div>
<div data-fruit="Guava" class="swiper-slide">4. Guava</div>
<div data-fruit="Pumpkin" class="swiper-slide">5. Pumpkin</div>
</div>
<div class="swiper-pagination swiper-pagination-nested"></div>
</div>
</li>
<li class="swiper-slide">
<div class="swiper-container swiper-container-nested">
<div class="swiper-wrapper">
<div data-fruit="Cranberry" class="swiper-slide">1. Cranberry</div>
<div data-fruit="Guava" class="swiper-slide">2. Guava</div>
<div data-fruit="Pumpkin" class="swiper-slide">3. Pumpkin</div>
</div>
<div class="swiper-pagination swiper-pagination-nested"></div>
</div>
</li>
<li class="swiper-slide">
<div class="swiper-container swiper-container-nested">
<div class="swiper-wrapper">
<div data-fruit="Lemon" class="swiper-slide">1. Lemon</div>
<div data-fruit="Melon" class="swiper-slide">2. Melon</div>
</div>
<div class="swiper-pagination swiper-pagination-nested"></div>
</div>
</li>
</ul>
<!-- Add Pagination -->
<div class="swiper-pagination swiper-pagination-h"></div>
</main>
<!-- assets -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/4.5.1/js/swiper.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src=""></script>
Related: Read this Github issue:
Multiple Instances of Swiper on Same page? #273
Codepen
https://codepen.io/ezra_siton/pen/MWgqMde?editors=1010

Categories