Bootstrap carousel keyboard buttons only work after clicking arrow on screen - javascript

Does anyone know how to override the default bootstrap carousel functionality of keyboard left and right buttons working only after first clicking one of the arrows on the screen.
I have rows of cards which when clicked opens a modal and inside that modal I have my carousel. I'd like the user to immediately be able to use the keyboard arrows and not have to click the arrows on the screen to enable the keyboard arrows to work. This appears to be the default behavior.
I've tried using $(#exampleId).focus() on various elements in the modal and carousel but no luck getting it to work thus far.
The default behavior can be seen in the bootstrap carousel doc:
https://getbootstrap.com/docs/5.0/components/carousel/#with-controls
Bootstrap-5 Carousel with controls code:
<div id="carouselExampleControls" class="carousel slide" data-bs-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img src="..." class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
</div>
<div class="carousel-item">
<img src="..." class="d-block w-100" alt="...">
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleControls" data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
Edit:
After following bootstrap documentation link you'll see that you can only slide the carousel using the keyboard after clicking one of the controls on the carousel "<" or ">". If you just start by using your left or right arrow keyboard buttons the carousel doesn't respond.

Related

How to test carousel with image in Cypress?

I need to write automation tests in Cypress for carousel with images.
I have something like this:
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="..." alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Third slide">
</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" 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>
The carousel change automatically. The active image gets class "slider_wrapper__activeSlide__2LNke", and the other image has class "slider_wrapper__nextSlide__1Vnk4". I would like to check whether the carousel is displayed on the page and whether the active image has the correct class.
I try with .should ('include') but it does not work :(
You can use .find() to query for elements underneath a yielded element.
cy.get('.carousel-item.active') // get the active div
.find('img') // get the img element underneath the above div
.should('be.visible') // check that the element is visible
.and('have.class', 'slider_wrapper__activeSlide__2LNke'); // check for the active image class.
If you need to check each of the carousel items, you'll have to use JQuery's hasClass.
cy.get('.carousel-item') // retrieve all elements with carousel-item class
.each(($item) => { // iterate through all elements
cy.wrap($item) // wrap the yielded element
.find('img') // find the img
.should('have.class', $item.hasClass('active') ? 'slider_wrapper__activeSlide__2LNke' : 'slider_wrapper__nextSlide__1Vnk4');
// ^ ternary to determine which class we are checking for
The carousel change automatically. To test that aspect, use cy.clock() to "freeze" the movement, then cy.tick(3000) to slide to next image (assuming 3 second delay).
cy.clock()
cy.get('div#carouselExampleControls')
.find('div.carousel-item.active')
.invoke('index')
.should('eq', 0) // first image is active
cy.tick(3000)
cy.get('div#carouselExampleControls')
.find('div.carousel-item.active')
.invoke('index')
.should('eq', 1) // second image is active
Try not to use classes with suffixes like __2LNke, they could be generated by the framework and change on next build.
If you want to check then, use the prefix part slider_wrapper__activeSlide and slider_wrapper__nextSlide
cy.get('[class*="slider_wrapper__nextSlide"]') // partial matching, more robust

Display images in a folder, slider style (one by one) by swiping or clicking, with multiple select

I have a website coded with standard stuff (html, javascript, jquery, php). I have a folder that I will dump images into throughout the day. I need to be able to access the website on a tablet, swipe from image to image and be able to select one or more (by filename) and then pass that list to the next procedure.
I do primarily database forms and such, not sure about the displaying of images and the swiping and keeping track of the selected images. Any help to point me in the right direction would be appreciated! I don't really expect anyone to do my work...just not sure where to start (yes, I've been Googling for a while).
Thanks!
There's many different possibilities in solving your issue. You can use Bootstrap's Carousel. It works fairly well; and assuming you're using PHP, you can create elements based on the directory content.
Your base code for the Carousel - straight from Bootstrap's content:
<div id="carouselExampleControls" class="carousel slide" data-ride="carousel">
<div class="carousel-inner">
<div class="carousel-item active">
<img class="d-block w-100" src="..." alt="First slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Second slide">
</div>
<div class="carousel-item">
<img class="d-block w-100" src="..." alt="Third slide">
</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" 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>
To make a automated PHP script you could use scandir and use a foreach loop to loop through the content:
<?php
$dir = './images/';
$file_list = array_diff(scandir($dir), array('..', '.'));
foreach($file_list as $item)
{
echo '<div class="carousel-item">';
echo '<img="' . $item . '" class="d-block w-100">';
echo '</div>';
}
?>
That will create a loop based on the files in that directory.

Angular routing navigation issues with Bootstrap Carousel tabs

I have created 4 tabs on a page with previous and next elements to traverse through the carousel items.
Each tab is a different page , so each tab has a different URL. When I click on Next, the tab header changes to the next tab but the URL doesnt change. So the content does not get loaded when the tab is changed. Likewise for Previous.
Also I'm using <router-outlet>. How do I make the tabs function when I click Next or Previous?
Here is my code
<div id="carouselId" class="carousel slide" data-ride="'carousel'" data-interval="false">
<div class="carousel-inner nav-tabs" role="listbox">
<div *ngFor="let tab of tabs; let i = index"
class="carousel-item" routerLinkActive="active">
<a id="activeHeader" class="nav-link" [routerLink]="[tab.tabRoute]"> {{tab.tabName}}</a>
</div>
</div>
</div>
<a class="carousel-control" href="#carouselId" role="button" data-slide="prev">
Previous
</a>
<a class="carousel-control" href="#carouselId" role="button" data-slide="next">
Next
</a>
<div>
<router-outlet></router-outlet>
</div>

Bootstrap Carousel interval is not working properly in IE8

I am facing interval issue with Bootstrap Carousel in IE8. When I land on the carousel page the slider image should be moved every 15 sec but it's not moving. Auto scrolling is less then 15 seconds when manually clicked on '>' icon on any image screen. This issue occurs before refreshing the page. Once I refresh the page then this issue doesn't occur. Next screen is not displaying for 15 seconds. This issue is happening for backward navigation also. This is occuring in IE 8 only.
My HTML:
<div id="myCarousel" class="carousel slide">
<div class="carousel-inner">
<div class="active item">
<img src="http://placehold.it/300x200/888&text=Item 1" />
</div>
<div class="item">
<img src="http://placehold.it/300x200/aaa&text=Item 2" />
</div>
<div class="item">
<img src="http://placehold.it/300x200/444&text=Item 3" />
</div>
</div>
<a class="carousel-control left" href="#myCarousel" data-slide="prev">‹</a>
<a class="carousel-control right" href="#myCarousel" data-slide="next">›</a>
</div>
My JavaScript:
$('.carousel').each(function(){
$(this).carousel({
interval: 15000
});
});

Dynamic background color in Bootstrap Carousel with AngularJS

I have a strange behaviorin Bootstrap Carousel which I am using with AngularJS. Below is the HTML code where I am trying to dynamically add background color to each thumbnail. What I observe is the following:
Initially, the "active" part of carousel adds background color dynamically to each thumbnail as expected.
However, once I start rotating the carousel, all thumbnails lose their background color.
Now, when I reload the page, all thumbnails get background color again.
So I cannot understand what causing the loss of background color initially during rotation? Thanks.
<div class="well">
<div id="myCarousel" class="carousel slide">
<!-- Carousel items -->
<div class="carousel-inner">
<div ng-repeat="imgSet in imgSets" ng-class="{item: true, active : $first}">
<div ng-class="row">
<div ng-repeat="img in imgSet track by img.id" class="col-sm-3">
<a href="/appDetail/{{img.id}}" class="thumbnail" style="background-color: {{img.tile_color}};">
<img ng-src="{{uri}}/{{img.image}}" alt="Image" class="img-responsive" height="{{img.tile_height}}" width="{{img.tile_width}}">
</a>
</div>
</div>
<!--/row-->
</div>
<!--/item-->
</div>
<!--/carousel-inner-->
<a class="left carousel-control" href="#myCarousel" data-slide="prev">‹</a>
<a class="right carousel-control" href="#myCarousel" data-slide="next">›</a>
</div>
<!--/myCarousel-->
</div>
<!--/well-->
Well I found how to fix it, but I still do not understand why the original is not working (and why the fix is working):
my {{img.tile_color}} is a string of the form "#1956B7" (or any other #). I thought one must have "#" sign in front of the number. When I removed the "#" it started working.

Categories

Resources