Skip to content
Snippets Groups Projects
Commit 645de903 authored by Martin Leblanc's avatar Martin Leblanc Committed by Kevin Paxman
Browse files

ISTWCMS-5650: Add tab indexing to image gallery carousel nav and dots

parent 245ef3bd
No related branches found
No related tags found
No related merge requests found
...@@ -146,8 +146,8 @@ ...@@ -146,8 +146,8 @@
</div> </div>
{% if type == NULL or type == 'slider' %} {% if type == NULL or type == 'slider' %}
<div class="uw-button--wrap"> <div class="uw-button--wrap">
<button class="uw-ig-button--previous"> < Prev</button> <button tabindex="0" class="uw-ig-button--previous"> < Prev</button>
<button class="uw-ig-button--next">Next ></button> <button tabindex="0" class="uw-ig-button--next">Next ></button>
</div> </div>
{% endif %} {% endif %}
</div> </div>
/** /**
* @file * @file
* Provides behavior for the image gallery using Flickity.
*/ */
(function ($, Drupal) { (function ($, Drupal, window) {
'use strict'; 'use strict';
Drupal.behaviors.imagegallery = { Drupal.behaviors.imagegallery = {
attach: function () { attach: function () {
// Ensure code runs after the DOM is fully loaded.
$(document).ready(function () { $(document).ready(function () {
// Step through each FF on the page. // Iterate over each image gallery component.
$('.uw-ig').each(function () { $('.uw-ig').each(function () {
// Get the id to reference the individual FF. // Get the unique ID for each image gallery instance.
// Need this to ensure that if more than one FF on the page,
// that all FFs get the carousel added.
var id = '#uw-ig-' + $(this).data('id'); var id = '#uw-ig-' + $(this).data('id');
// Retrieve configuration options from data attributes.
var imagesNum = $(this).data('images-num') || 1; var imagesNum = $(this).data('images-num') || 1;
var navStyle = $(this).data('nav') || 'both'; var navStyle = $(this).data('nav') || 'both';
// Create carousel config first.
var flickityOptions = {
cellAlign: 'left',
contain: true,
wrapAround: true,
draggable: false,
groupCells: function () {
var width = $(window).width();
return width <= 600 ? 1 : imagesNum;
},
prevNextButtons: false,
pageDots: navStyle === 'pagination' || navStyle === 'both'
};
var $carousel = $(id + ' .carousel'); var $carousel = $(id + ' .carousel');
// Initialize Flickity only if the carousel exists.
if ($carousel.length) { if ($carousel.length) {
$carousel.flickity(flickityOptions); $carousel.flickity({
cellAlign: 'left',
contain: true,
wrapAround: true,
draggable: false,
groupCells: function () {
// Adjust the number of visible images based on screen width.
var width = $(window).width();
if (width <= 600) {
return 1;
}
else if (width <= 1024) {
return Math.min(2, imagesNum);
}
else {
return imagesNum;
}
},
prevNextButtons: false,
pageDots: navStyle === 'pagination' || navStyle === 'both',
});
// Get the Flickity instance from the element.
var flkty = $carousel.data('flickity');
// Handle keyboard navigation for Flickity pagination dots.
var dots = document.querySelectorAll('.uw-ig .flickity-page-dots .dot');
if (!dots.length) {
return;
}
dots.forEach(function (dot) {
dot.setAttribute('tabindex', '0'); // Make dots focusable.
dot.addEventListener('keydown', function (event) {
if (event.key === 'Enter' || event.keyCode === 13) {
var label = dot.getAttribute('aria-label');
// Extract the slide index from the dot label.
var match = label.match(/\d+/);
if (!match) {
return;
}
var targetIndex = parseInt(match[0], 10) - 1;
if (flkty) {
flkty.select(targetIndex); // Move to the selected slide.
}
}
});
});
} }
// previous button
$('.uw-ig-button--previous').on( 'click', function() { // Previous button event listener.
$('.uw-ig-button--previous').on('click', function () {
$carousel.flickity('previous'); $carousel.flickity('previous');
}); });
// next
$('.uw-ig-button--next').on( 'click', function() { // Next button event listener.
$('.uw-ig-button--next').on('click', function () {
$carousel.flickity('next'); $carousel.flickity('next');
}); });
// Set lightbox open button to be unfocusable by default.
$('.uw-lightbox__open').attr('tabindex', -1);
// Activate navigation buttons if required.
if (navStyle === 'navigation' || navStyle === 'both') { if (navStyle === 'navigation' || navStyle === 'both') {
$('.uw-button--wrap').addClass('active'); $('.uw-button--wrap').addClass('active');
} }
// Lightbox enchancements // Lightbox open event.
$('.uw-lightbox__open').on('click', function () { $('.uw-lightbox__open').on('click', function () {
$(id + ' .uw-lightbox').addClass('openLightBox'); $(id + ' .uw-lightbox').addClass('openLightBox');
$('html').addClass('no-scroll'); $('html').addClass('no-scroll');
}); });
// Lightbox close
// Lightbox close event.
$(id + ' .uw-lightbox__close').on('click', function () { $(id + ' .uw-lightbox__close').on('click', function () {
$('.uw-lightbox').removeClass('openLightBox'); $('.uw-lightbox').removeClass('openLightBox');
$('html').removeClass('no-scroll'); $('html').removeClass('no-scroll');
}); });
// If next is clicked
$(id + ' .uw-lightbox__next').on('click', function () { // Ensure the lightbox opens when navigating within it.
if (!$(id + ' .uw-lightbox').hasClass('openLightBox')) { $(id + ' .uw-lightbox__next, ' + id + ' .uw-lightbox__prev').on('click', function () {
$(id + ' .uw-lightbox').addClass('openLightBox');
}
});
// If prev is clicked
$(id + ' .uw-lightbox__prev').on('click', function () {
if (!$(id + ' .uw-lightbox').hasClass('openLightBox')) { if (!$(id + ' .uw-lightbox').hasClass('openLightBox')) {
$(id + ' .uw-lightbox').addClass('openLightBox'); $(id + ' .uw-lightbox').addClass('openLightBox');
} }
...@@ -82,46 +123,39 @@ ...@@ -82,46 +123,39 @@
* @returns {boolean} clicked. * @returns {boolean} clicked.
*/ */
function fakeClick() { function fakeClick() {
//use url to build the fake anchor id
var url = window.location.href; var url = window.location.href;
//Regex to replace the text
// "lightbox" with "ig" a // Construct a fake anchor ID to match the gallery.
// and trim last "-###".
var galleryAnchor = url var galleryAnchor = url
.substring(url.lastIndexOf('/') + 1) .substring(url.lastIndexOf('/') + 1)
.replace( /(?:^|\W)lightbox(?:$|\W)/, '-ig-') .replace(/(?:^|\W)lightbox(?:$|\W)/, '-ig-')
.replace(/-\d+$/, ''); .replace(/-\d+$/, '');
// Create the fake element
var escFake = document.createElement('a');
var linkText = document.createTextNode('fake click'); // Create a temporary link element.
var escFake = document.createElement('a');
escFake.appendChild(linkText);
escFake.title = 'my title text';
escFake.href = galleryAnchor; escFake.href = galleryAnchor;
escFake.classList = 'uw-lightbox__close off-screen'; escFake.classList.add('uw-lightbox__close', 'off-screen');
// Append the fake button // Append and trigger the click.
document.body.appendChild(escFake); document.body.appendChild(escFake);
//Click the button
escFake.click(); escFake.click();
// Remove no scroll
// Cleanup after closing the lightbox.
$('html').removeClass('no-scroll'); $('html').removeClass('no-scroll');
// Remove open class
$('.uw-lightbox').removeClass('openLightBox'); $('.uw-lightbox').removeClass('openLightBox');
// Remove the fake button
document.body.removeChild(escFake); document.body.removeChild(escFake);
} }
// Attach the keyup event to Escape tp close
// Close lightbox when pressing Escape.
$(document).on('keyup', function (evt) { $(document).on('keyup', function (evt) {
if (evt.keyCode === 27) { if (evt.keyCode === 27) {
fakeClick(); fakeClick();
} }
}); });
// If click in outside lightbox div then close
$(document).click( function (evt) { // Close lightbox if clicking outside of the content.
if ($(evt.target).is( $('.uw-lightbox.openLightBox'))) { $(document).click(function (evt) {
if ($(evt.target).is($('.uw-lightbox.openLightBox'))) {
fakeClick(); fakeClick();
} }
}); });
...@@ -129,4 +163,4 @@ ...@@ -129,4 +163,4 @@
}); });
} }
}; };
})(jQuery, Drupal); })(jQuery, Drupal, window);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment