Reputation: 1445
I'm currently using the Flickity Carousel to create a carousel with different film content panels.
The carousel is using a custom navigation to control it, rather than the standard one that comes with the carousel. However I'm struggling to disable the next navigation button when you reach the end of the carousel slides. Here is an example of what I'm trying to achieve and have based my code on this.
You will see from my example that the Previous button works correctly and is disabled when you first land on the carousel. However the Next button is never disabled when reaching the end.
Here is a JSFiddle
My code:
$(document).ready(function () {
$('.carousel-container').each(function (i, container) {
var options = {
cellAlign:'left',
groupCells:'3',
pageDots: false,
prevNextButtons: false
};
$('.carousel__slides').flickity(options);
var $container = $(container);
var $slider = $container.find('.carousel__slides');
var flkty = $slider.data('flickity');
var selectedIndex = flkty.selectedIndex;
var slideCount = flkty.slides.length;
var $prev = $container.find('.prev');
var $next = $container.find('.next');
// previous
$prev.on('click', function () {
$slider.flickity('previous');
});
// next
$next.on('click', function () {
$slider.flickity('next');
});
$slider.on( 'select.flickity', function() {
// enable/disable previous/next buttons
if ( !flkty.cells[ flkty.selectedIndex - 1 ] ) {
$prev.attr( 'disabled', 'disabled' );
$next.removeAttr('disabled'); // <-- remove disabled from the next
} else if ( !flkty.cells[ flkty.selectedIndex +1 ] ) {
$next.attr( 'disabled', 'disabled' );
$prev.removeAttr('disabled'); //<-- remove disabled from the prev
} else {
$prev.removeAttr('disabled');
$next.removeAttr('disabled');
}
});
});
});
.carousel-container {
position:relative;
}
.carousel__slide {
width: 20%;
max-width:286px;
opacity: 0.5;
}
.carousel__slide.is-selected {
opacity: 1;
}
.carousel__nav {
display:block;
}
.carousel__nav button {
width:65px;
height:50px;
background:red;
border-radius:0 100% 100% 0;
position: absolute;
top: 80px;
cursor:pointer;
border:none;
outline:0;
transition-duration: 0.3s;
transition-property: all;
}
.carousel__nav button:hover,
.carousel__nav button:active,
.carousel__nav button:focus {
background:green;
outline:0;
}
.carousel__nav button:disabled {
background:black;
opacity: 0.5;
}
.carousel__nav button i {
content:'';
display:block;
margin:0 auto;
width: 0;
height: 0;
border-style: solid;
border-width: 10.5px 0 10.5px 14px;
border-color: transparent transparent transparent white;
}
.carousel__nav .prev {
left:0;
}
.carousel__nav .prev i {
transform:rotate(180deg);
}
.carousel__nav .next {
right:0;
border-radius:100% 0 0 100%;
}
.film-section {
margin-top:50px;
}
.film-item {
padding:0 15px;
}
.film-item p {
font-size:1.4rem;
line-height:2.6rem;
margin-bottom:0;
}
.film-item__image {
position:relative;
}
.film-item__play {
width:65px;
height:65px;
border-radius:100% 0 0 0;
position:absolute;
right:0;
bottom:0;
background:rgba(0,0,0,0.4);
border:none;
transition-duration: 0.3s;
transition-property: all;
}
.film-item__play:hover,
.film-item__play:active,
.film-item__play:focus {
background:red;
outline:0;
}
.film-item__play:after {
content:'';
display:block;
margin:0 auto;
width: 0;
height: 0;
border-style: solid;
border-width: 10.5px 0 10.5px 14px;
border-color: transparent transparent transparent white;
position:absolute;
top:31px;
left:33px;
}
.heading-content {
display:none;
opacity: 0;
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/flickity@2/dist/flickity.pkgd.min.js"></script>
<link href="https://unpkg.com/flickity@2/dist/flickity.min.css" rel="stylesheet"/>
<div class="carousel-container">
<div class="carousel__slides">
<div class="carousel__slide">
<div class="offset-slide"></div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
<h3 class="js-video-heading heading-content">Universitat Oberta de Catalunya</h3>
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="offset-slide"></div>
</div>
</div>
<div class="carousel__nav">
<button class="prev" disabled><i></i></button>
<button class="next"><i></i></button>
</div>
</div>
Upvotes: 6
Views: 2349
Reputation: 3869
Here's how I did it:
var PrevNextButton = Flickity.PrevNextButton;
PrevNextButton.prototype.update = function () {
// index of first or last cell, if previous or next
var cells = this.parent.cells;
// enable is wrapAround and at least 2 cells
if (this.parent.options.wrapAround && cells.length > 1) {
this.enable();
return;
}
var lastIndex = cells.length ? cells.length - 1 : 0;
var boundIndex = this.isPrevious ? 0 : lastIndex;
var isEnabling;
if (this.parent.options.contain) {
var boundCell = cells[boundIndex];
var selectedCell = cells[this.parent.selectedIndex];
isEnabling = selectedCell.target != boundCell.target;
} else {
isEnabling = this.parent.selectedIndex == boundIndex
}
var method = isEnabling ? 'enable' : 'disable';
this[method]();
};
It's with an older version of Flickity, so it may need tests. With it, I'm able to disable/enable next/prev (disable next when the last slide is reached, disable prev if the first slide is on) controls and then handle design with CSS :disabled
. This code goes just above my FLickity init el.flickity({...})
.
This is from metafizzy/flickity/issues/289 (answered by author Desandro himself)
EDIT:
Ok I tested my sample in your code. I think it failed because of the groupCells, and the Math behind was still using complete cell number as a variable. I dirty edited it with some Math.floor
to use the slide number instead of cell number (Desandro sample seems still to work when NOT using grouped cells, but a 1 cell = 1 slide config).
It works with included flickity next/prev feature, but I believe you could adapt it to use your external controls.
This is a quick hack, so it needs tests, better Maths, and flickity option handling. But it's a start.
https://jsfiddle.net/0c7xqrpw/20/
Upvotes: 0
Reputation: 11447
The issue with you code is that you set groupCells options but using flkty.cells. "Cells" represent all element. You need to use "slides" which represent the groups in your slider.
Here is a slightly modified version of your code:
$(document).ready(function() {
$('.carousel-container').each(function(i, container) {
var options = {
cellAlign: 'left',
groupCells: '3',
pageDots: false,
prevNextButtons: false
};
$('.carousel__slides').flickity(options);
var $container = $(container);
var $slider = $container.find('.carousel__slides');
var flkty = $slider.data('flickity');
var selectedIndex = flkty.selectedIndex;
var slideCount = flkty.slides.length;
var $prev = $container.find('.prev');
var $next = $container.find('.next');
// previous
$prev.on('click', function() {
$slider.flickity('previous');
});
// next
$next.on('click', function() {
$slider.flickity('next');
});
$slider.on('select.flickity', function() {
// enable/disable previous/next buttons
if (!flkty.slides[flkty.selectedIndex - 1]) {
$prev.attr('disabled', 'disabled');
$next.removeAttr('disabled'); // <-- remove disabled from the next
} else if (!flkty.slides[flkty.selectedIndex + 1]) {
$next.attr('disabled', 'disabled');
$prev.removeAttr('disabled'); //<-- remove disabled from the prev
} else {
$prev.removeAttr('disabled');
$next.removeAttr('disabled');
}
});
});
});
.carousel-container {
position:relative;
}
.carousel__slide {
width: 20%;
max-width:286px;
opacity: 0.5;
}
.carousel__slide.is-selected {
opacity: 1;
}
.carousel__nav {
display:block;
}
.carousel__nav button {
width:65px;
height:50px;
background:red;
border-radius:0 100% 100% 0;
position: absolute;
top: 80px;
cursor:pointer;
border:none;
outline:0;
transition-duration: 0.3s;
transition-property: all;
}
.carousel__nav button:hover,
.carousel__nav button:active,
.carousel__nav button:focus {
background:green;
outline:0;
}
.carousel__nav button:disabled {
background:black;
opacity: 0.5;
}
.carousel__nav button i {
content:'';
display:block;
margin:0 auto;
width: 0;
height: 0;
border-style: solid;
border-width: 10.5px 0 10.5px 14px;
border-color: transparent transparent transparent white;
}
.carousel__nav .prev {
left:0;
}
.carousel__nav .prev i {
transform:rotate(180deg);
}
.carousel__nav .next {
right:0;
border-radius:100% 0 0 100%;
}
.film-section {
margin-top:50px;
}
.film-item {
padding:0 15px;
}
.film-item p {
font-size:1.4rem;
line-height:2.6rem;
margin-bottom:0;
}
.film-item__image {
position:relative;
}
.film-item__play {
width:65px;
height:65px;
border-radius:100% 0 0 0;
position:absolute;
right:0;
bottom:0;
background:rgba(0,0,0,0.4);
border:none;
transition-duration: 0.3s;
transition-property: all;
}
.film-item__play:hover,
.film-item__play:active,
.film-item__play:focus {
background:red;
outline:0;
}
.film-item__play:after {
content:'';
display:block;
margin:0 auto;
width: 0;
height: 0;
border-style: solid;
border-width: 10.5px 0 10.5px 14px;
border-color: transparent transparent transparent white;
position:absolute;
top:31px;
left:33px;
}
.heading-content {
display:none;
opacity: 0;
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://unpkg.com/[email protected]/dist/flickity.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/flickity/2.2.1/flickity.pkgd.min.js"></script>
<div class="carousel-container">
<div class="carousel__slides">
<div class="carousel__slide">
<div class="offset-slide"></div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
<h3 class="js-video-heading heading-content">Universitat Oberta de Catalunya</h3>
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="film-item">
<div class="film-item__image">
<img class="w-100" src="http://placekitten.com/510/380" alt="">
</div>
<h3>Heading</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc volutpat augue at quam ultrices euismod vel ac sapien. Ut finibus posuere augue, eget condimentum nunc porttitor in. Praesent in ornare mi, at rhoncus felis. In iaculis viverra sem sit amet lacinia.</p>
</div>
</div>
<div class="carousel__slide">
<div class="offset-slide"></div>
</div>
</div>
<div class="carousel__nav">
<button class="prev" disabled><i></i></button>
<button class="next"><i></i></button>
</div>
</div>
Upvotes: 1
Reputation: 341
try to set "if" as folows:
if ((flkty.selectedIndex - 1) < 0 ) {
$prev.attr( 'disabled', 'disabled' );
$next.removeAttr('disabled'); // <-- remove disabled from the next
} else if ( (flkty.selectedIndex + 1) == slideCount){
$next.attr( 'disabled', 'disabled' );
$prev.removeAttr('disabled'); //<-- remove disabled from the prev
} else {
$prev.removeAttr('disabled');
$next.removeAttr('disabled');
}
Upvotes: 0