Customized Bootstrap Carousel - only show set number of DIVs - javascript

I have implemented a bootstrap carousel which looks like this on loading:
The code is as follows:
html:
<div class="container text-center my-3">
<div class="row mx-auto my-auto">
<div id="recipeCarousel" class="carousel slide w-100" data-wrap="false">
<div class="carousel-inner w-100" role="listbox">
<div class="carousel-item active">
<div class="col-md-1">
<div class="card card-body">
1
</div>
</div>
</div>
<div class="carousel-item">
<div class="col-md-1">
<div class="card card-body">
2
</div>
</div>
</div>
... carousel-item divs repeat to 18 ...
<div class="carousel-item">
<div class="col-md-1">
<div class="card card-body">
18
</div>
</div>
</div>
</div>
<a class="carousel-control-prev w-auto" href="#recipeCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon bg-dark border border-dark rounded-circle" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next w-auto" href="#recipeCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon bg-dark border border-dark rounded-circle" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
Javascript:
$('.carousel .carousel-item').each(function () {
var minPerSlide = 12;
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
for (var i = 0; i < minPerSlide; i++) {
next = next.next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
}
});
CSS:
#media (max-width: 768px) {
.carousel-inner .carousel-item > div {
display: block;
}
.carousel-inner .carousel-item > div:first-child {
display: block;
}
}
.carousel-inner .carousel-item.active,
.carousel-inner .carousel-item-next,
.carousel-inner .carousel-item-prev {
display: flex;
}
/* display 12 */
#media (min-width: 768px) {
.carousel-inner .carousel-item-right.active,
.carousel-inner .carousel-item-next {
transform: translateX(8.333%);
}
.carousel-inner .carousel-item-left.active,
.carousel-inner .carousel-item-prev {
transform: translateX(-8.333%);
}
}
.carousel-inner .carousel-item-right,
.carousel-inner .carousel-item-left {
transform: translateX(0);
}
I don't want to the carousel to repeat when I get to the end (clicking the right arrow 6 times):
However it seems I can continue clicking the right arrow until the 18 is the first div in the row:
I cannot figure out how to stop the right button from carrying out a move when the last (18) div first appears on screen (i.e. the second screenshot above).
Any help is greatly appreciated or if anything isn't clear please let me know.

So I managed to find the event that fires 'after' a slide completes and this is where I needed to handle the changes. Also, making use of the current Active attribute that gets auto-assigned to the current WeatherElement. Code working now looks like this:
html:
<div class="container text-center my-3">
<div class="row mx-auto my-auto">
<div id="recipeCarousel" class="carousel slide w-100" data-wrap="false">
<div class="carousel-inner carousel-weather w-100" role="listbox">
<div id="weatherCard_0" class="carousel-item active">
<div class="col-md-1">
<div class="card card-body">
1
</div>
</div>
</div>
... repeat till 18
<div id="weatherCard_18" class="carousel-item">
<div class="col-md-1">
<div class="card card-body">
18
</div>
</div>
</div>
</div>
<a id="leftWeatherButton" class="carousel-control carousel-control-prev w-auto" href="#recipeCarousel" role="button" data-slide="prev">
<span class="carousel-control-prev-icon bg-dark border border-dark rounded-circle" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a id="rightWeatherButton" class="carousel-control carousel-control-next w-auto" href="#recipeCarousel" role="button" data-slide="next">
<span class="carousel-control-next-icon bg-dark border border-dark rounded-circle" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
Where I have removed the onClick() events from the buttons.
Jaascript:
$('#recipeCarousel').bind('slid.bs.carousel', function (e) {
var $this = $(this);
$this.children('.carousel-control').show();
var weatherElements = $('.carousel-weather')[0].children;
var elementsLength = weatherElements.length - 1;
var first = weatherElements[0];
var lastCount;
if (elementsLength <= 11) {
lastCount = 0
}
else {
lastCount = elementsLength - 11;
}
var last = weatherElements[lastCount];
if ($(last).hasClass('active')) {
$this.children('.carousel-control-next').hide();
} else if ($(first).hasClass('active')) {
$this.children('.carousel-control-prev').hide();
}
});
function ManageWeatherButtons() {
$("#leftWeatherButton").hide();
$("#rightWeatherButton").hide();
debugger;
if (weatherCards.length > 12) {
$("#rightWeatherButton").show();
}
}
Which replaces all of the javascript from the initial code example.
This seems to work a lot better and will behave no matter how much you click the buttons.

Related

Carousel scrolling is not working. Around 25-30 images will be added from admin panel

In this code, scrolling is not working. Around 25-30 (image count is not fixed )images will be added from the admin panel each week that will replace the previous images and that will be displayed here. only the latest images will be visible in front Images get properly fetched but scrolling is not working. I think there is some issue in the javascript code. Please help me to resolve it.
/*
Carousel
*/
$('#carousel-example').on('slide.bs.carousel', function(e) {
/*
CC 2.0 License Iatek LLC 2018 - Attribution required
*/
var $e = $(e.relatedTarget);
var idx = $e.index();
var itemsPerSlide = 5;
var totalItems = $('.carousel-item').length;
if (idx >= totalItems - (itemsPerSlide - 1)) {
var it = itemsPerSlide - (totalItems - idx);
for (var i = 0; i < it; i++) {
// append slides to end
if (e.direction == "left") {
$('.carousel-item').eq(i).appendTo('.carousel-inner');
} else {
$('.carousel-item').eq(0).appendTo('.carousel-inner');
}
}
}
});
<!-- Cartoon Carousel -->
<section>
<div class="cartoon">
<div class="top-content">
<div class="container-fluid">
<div id="carousel-example" class="carousel slide" data-ride="carousel">
<!-- slides -->
<div class="carousel-inner row w-100 mx-auto" role="listbox">
<?php
if(sizeof($cartoons_category_data) > 0){
for($i = 0; $i< count($cartoons_category_data) ; $i++){
?>
<div class="carousel-item col-12 col-sm-6 col-md-4 col-lg-3 active">
<img src="<?php echo base_url('assets/uploads/library/'.$cartoons_category_data[$i]); ?>" class="img-fluid mx-auto d-block" alt="img1">
</div>
<?php
} //for
} ?>
</div>
<a class="carousel-control-prev" href="#carousel-example" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true" style="background-color: #ffa500;
padding: 15px;"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" href="#carousel-example" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true" style="background-color: #ffa500;
padding: 15px;"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
</div>
</section>

carousel arrow also changes text in a div react.js

I am making a character select screen and I want the bootstrap carousel arrows to also change the text in the scroll to match each character. Right now the scroll is a separate component but I'm open to putting them on the same page.
I was trying to grab it by the class "active" since that came with the bootstrap carousel and populating from a data.json, but it isn't working. Open to other (hopefully easier) ideas as well!!
state = {
data: characters,
curCharacter: {},
}
componentDidMount() {
var cur = this.state.data[0].description;
this.setState({ curCharacter: this.state.data[0] });
console.log(this.state.curCharacter)
}
characterSelect = (e) => {
e.preventDefault()
var cur = document.getElementsByClassName("active")
console.log("activ1", cur)
var newClass = cur[0].children[0].alt
console.log("activ2", newClass);
var arr = this.state.data;
console.log(arr);
for (let i = 0; i < arr.length; i++) {
console.log(arr[i], arr[i + 2]);
if (newClass == arr[i].class) {
this.setState({ curCharacter: arr[i] });
console.log(this.state.curCharacter)
}
}
}
render() {
return (
<div className="charContain">
<div className="row">
<div className="col-md-6">
<div id="carouselExampleControls" class="sprite carousel slide" data-ride="carousel" data-interval="false" >
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block h-100" src="https://i.imgur.com/ODs4zDn.gif" alt="Warrior" />
</div>
<div class="carousel-item">
<img class="d-block h-100" src="https://i.imgur.com/huVIPkL.png" alt="Archer" />
</div>
<div class="carousel-item">
<img class="d-block h-100" src="https://i.imgur.com/bKvuY6T.png" alt="Warrior" />
</div>
<div class="carousel-item">
<img class="d-block h-100" src="https://i.imgur.com/pIHmyE4.png" alt="Mage" />
</div>
</div>
<a class="carousel-control-prev" href="#carouselExampleControls" role="button" data-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="carousel-control-next" onClick={this.characterSelect} href="#carouselExampleControls" role="button" data-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
<button onClick={handleButtonChoose} className="choose">Choose Character</button>
</div>
<div className="col-md-6">
<Scroll
text={this.state.description}
/>
</div>
</div>
</div>
)
}
}
export default Character
Thanks in advance!!

Wrap a div dynamically using jQuery depending on screen size

I have a bootstrap carousel. Here if window width i more than 400px, I need to show all inner divs in same item. But if the window width is less than 400px, I need to show every 3 inner divs in
one <div class="item">. I have this code:
function item_wrap() {
var width = $(window).width();
console.log(width);
if (width > 400) {
$('.inner').unwrap();
$('.inner').wrapAll('<div class="item active">');
} else {
$('.inner').unwrap();
$('.inner:lt(3)').wrapAll('<div class="item active">');
$('.inner:gt(2)').wrapAll('<div class="item">');
}
}
item_wrap();
$(window).resize(function() {
item_wrap();
});
.item {
background: #ccc;
}
.active {
color: red
}
.inner {
float: left;
width: 20%;
border: 1px solid black;
margin: 2px;
}
#media screen and (max-width: 400px) and (min-width: 300px) {
.inner {
width: 30%;
}
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div id="myCarousel" class="carousel" data-ride="carousel" data-interval="false">
<div class="carousel-inner" role="listbox">
<div>
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
<div class="inner">4</div>
<div class="inner">5</div>
<div class="inner">6</div>
<div class="inner">7</div>
<div class="inner">8</div>
<div class="inner">9</div>
<div class="inner">10</div>
<div class="inner">11</div>
<div class="inner">12</div>
</div>
</div>
<a class="carousel-control left-carousel" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true" style="display:block"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control right-carousel" href="#myCarousel" role="button" data-slide="next" style="background: inherit !important;display: block;height: auto;opacity: 0.5;right: -4%;">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>
If window width is greater than 400px it is working correctly. But if the window width is less than 400px the first 3 inner divs are showing correct
but other inner div are not correctly wrappped in <div class="item">
what i need is if in window width less than 400px then first 3 inner
div is need wrap in <div class="item active"> and all other ecah 3
inner div is need to wrap in <div class="item">.
ie , if window width less than 400px i need to get the following structure
<div class="carousel-inner" role="listbox">
<div>
<div class="item-active">
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
</div>
<div class="item">
<div class="inner">4</div>
<div class="inner">5</div>
<div class="inner">6</div>
</div>
<div class="item">
<div class="inner">7</div>
<div class="inner">8</div>
<div class="inner">9</div>
</div>
<div class="item">
<div class="inner">10</div>
<div class="inner">11</div>
<div class="inner">12</div>
</div>
</div>
</div>
Please help to solve this .
Try this
<script type="text/javascript">
function item_wrap(){
var width = $(window).width();
console.log(width);
if(width > 400) {
$('.inner').unwrap();
$('.inner').wrapAll('<div class="item active">');
} else {
$('.inner').unwrap();
var divs = $(".inner");
for(var i = 0; i < divs.length; i+=3) {
if(i===0){
$('.inner:lt(3)').wrapAll('<div class="item active">');
}
else{
divs.slice(i, i+3).wrapAll("<div class='item'></div>");
}
}
}
}
item_wrap();
$(window).resize(function(){
item_wrap();
});
</script>
Idea
Here's the code that works. The idea is that you loop through the remaining items after the first three, taking three items at a time, and wrap them into the div. Then take the next three and wrap them again, and so forth.
Main code:
for (var i = 0; i < others.length; i += 3) {
var nextThree = [others[i], others[i+1], others[i+2]]'
$(nextThree).wrapAll('<div class="item">');
}
Full code:
function item_wrap() {
var width = $(window).width();
console.log(width);
if (width > 400) {
$('.inner').unwrap();
$('.inner').wrapAll('<div class="item active">');
} else {
$('.inner').unwrap();
var firstThree = $('.inner:lt(3)');
var others = $('.inner:gt(2)');
$(firstThree).wrapAll('<div class="item active">');
for (var i = 0; i < others.length; i += 3) {
var nextThree = [others[i], others[i+1], others[i+2]]'
$(nextThree).wrapAll('<div class="item">');
}
}
}
item_wrap();
$(window).resize(function() {
item_wrap();
});
.item {
background: #ccc;
}
.active {
color: red
}
.inner {
float: left;
width: 20%;
border: 1px solid black;
margin: 2px;
}
#media screen and (max-width: 400px) and (min-width: 300px) {
.inner {
width: 30%;
}
}
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
<div class="container">
<div class="row">
<div id="myCarousel" class="carousel" data-ride="carousel" data-interval="false">
<div class="carousel-inner" role="listbox">
<div>
<div class="inner">1</div>
<div class="inner">2</div>
<div class="inner">3</div>
<div class="inner">4</div>
<div class="inner">5</div>
<div class="inner">6</div>
<div class="inner">7</div>
<div class="inner">8</div>
<div class="inner">9</div>
<div class="inner">10</div>
<div class="inner">11</div>
<div class="inner">12</div>
</div>
</div>
<a class="carousel-control left-carousel" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true" style="display:block"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control right-carousel" href="#myCarousel" role="button" data-slide="next" style="background: inherit !important;display: block;height: auto;opacity: 0.5;right: -4%;">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
</div>
</div>

CSS multiple brand name slider

i was wondering if its possible to make a carousel displaying text instead of images, i tried to make something but it doesn't work well... only displays 1 item at a time, so if anyone can assist me that would be great.
For example i would like to have 8 brand names displayed:
< BRAND 1 | BRAND 2 | BRAND 3 | BRAND 4 >
and after i click the arrow:
< BRAND 2 | BRAND 3 | BRAND 4 | BRAND 5 >
I want to use pure text instead of images.
my current html:
<div id="myCarousel" class="carousel slide">
<div class="carousel-inner">
<div class="item active">
<div class="col-xs-4">JavaScript</div>
</div>
<div class="item">
<div class="col-xs-4">HTML</a></div>
</div>
<div class="item">
<div class="col-xs-4">CSS</a></div>
</div>
<div class="item">
<div class="col-xs-4">JSON</div>
</div>
<div class="item">
<div class="col-xs-4">AngularJS</div>
</div>
</div>
<!-- Controls -->
<a class="left carousel-control" href="#myCarousel" role="button" data-slide="prev">
<span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span>
<span class="sr-only">Previous</span>
</a>
<a class="right carousel-control" href="#myCarousel" role="button" data-slide="next">
<span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span>
<span class="sr-only">Next</span>
</a>
</div>
my css for the carousel:
.carousel-inner .active.left { left: -33%; }
.carousel-inner .active.right { left: 33%; }
.carousel-inner .next { left: 33% }
.carousel-inner .prev { left: -33% }
.carousel-control.left { background-image: none; }
.carousel-control.right { background-image: none; }
.carousel-inner .item { background: white; }
script:
$('#myCarousel').carousel({
interval: 2000
})
$('.carousel .item').each(function(){
var next = $(this).next();
if (!next.length) {
next = $(this).siblings(':first');
}
next.children(':first-child').clone().appendTo($(this));
if (next.next().length>0) {
next.next().children(':first-child').clone().appendTo($(this));
}
else {
$(this).siblings(':first').children(':first-child').clone().appendTo($(this));
}
});
The problem is right now it displays only 1 item at a time for me, and i would like 4...

Bootstrap 3: Hidding carousel controls on first and last items not working

I did get the JS code from: netgloo
JS:
var checkitem = function() {
var $this;
$this = $("#");
if ($("#diapos .carousel-inner .item:first").hasClass("active")) {
$this.children(".left").hide();
$this.children(".right").show();
} else if ($("#diapos .carousel-inner .item:last").hasClass("active")) {
$this.children(".right").hide();
$this.children(".left").show();
} else {
$this.children(".carousel-control").show();
}
};
checkitem();
$("#diapos").on("slid.bs.carousel", "", checkitem);
HTML:
<div id="diapos" class="carousel paper2 slide" data-ride="carousel">
<!-- diapos -->
<div class="carousel-inner" role="listbox">
<div class="overlay"></div>
<div class="item active" id="first">
<img src="img/01.jpg" alt="...">
</div>
<div class="item" id="second">
<img src="img/02.jpg" alt="...">
</div>
<div class="item" id="last">
<img src="img/03.jpg" alt="...">
</div>
</div>
</div>
<a class="left carousel-control" href="#diapos" role="button" data-slide="prev"><span class="glyphicon glyphicon-chevron-left" aria-hidden="true"></span><span class="sr-only">Previous</span></a>
<a class="right carousel-control" href="#diapos" role="button" data-slide="next"><span class="glyphicon glyphicon-chevron-right" aria-hidden="true"></span><span class="sr-only">Next</span></a>
The code is not hidding the respective controls.
There are no other carousels in the document.
By the way, what's the function of this piece of HTML?:
<div class="overlay"></div>
The id of the carousel div is "diapos". So this on the third line should be assigned to that, as 'left' and 'right' are its immediate children :
var checkitem = function() {
var $this;
$this = $("#diapos"); // this line needs to be changed
if ($("#diapos .carousel-inner .item:first").hasClass("active")) {
$this.children(".left").hide();
//continue as before from here
Also, you probably forgot to close the 'diapos' div!

Categories