From 1d3ef0bba2ba6fac4b468b52fc50c2ae11bd4b3d Mon Sep 17 00:00:00 2001 From: Damien Wilson <47327051+wilson1000-MoJ@users.noreply.github.com> Date: Mon, 25 Sep 2023 09:55:36 +0100 Subject: [PATCH] CDPT 900 - link to content inside tab (#458) * camelCase name * Refactor and deep-linking feature * Remove console.log() --- .../c-tabbed-content/tabbed-content.js | 124 ++++++++++++++---- .../clarity/src/globals/js/script-loader.js | 2 +- 2 files changed, 97 insertions(+), 29 deletions(-) diff --git a/web/app/themes/clarity/src/components/c-tabbed-content/tabbed-content.js b/web/app/themes/clarity/src/components/c-tabbed-content/tabbed-content.js index 482ba03f2..0905c8062 100644 --- a/web/app/themes/clarity/src/components/c-tabbed-content/tabbed-content.js +++ b/web/app/themes/clarity/src/components/c-tabbed-content/tabbed-content.js @@ -1,37 +1,105 @@ -export default (function ($) { - $.fn.moji_tabbedContent = function () { +/* global console */ +/* jshint esversion: 6 */ +export default (($) => { + const tabbed = { + panels: {}, + tabs: {}, + hash: null, + /** + * Get the hash fragment + * @returns {string} + */ + getHash: () => { + return tabbed.hash || (tabbed.hash = window.location.hash.substring(1)); + }, + /** + * Show a tab and panel + * Supports accessibility + * @param tab jquery object + */ + show: (tab) => { + // hide first + tabbed.hide(); + + // then show + tab.addClass('u-current').attr('aria-selected', 'true'); + tabbed.panels.filter('[data-tab-title="' + tab.text() + '"]').show().addClass('u-current'); + }, + /** + * Hide all tabs + * Supports accessibility + */ + hide: () => { + // Hide panel + tabbed.tabs.removeClass('u-current').attr('aria-selected', 'false'); + tabbed.panels.removeClass('u-current'); + tabbed.panels.hide(); + }, + /** + * Handle hash fragments, locates named anchors or elements with IDs + * Switches the tab and activates scroll + */ + findAndDeliver: () => { + /** F I N D */ + let target = $("a[name='" + tabbed.getHash() + "']"); + + // test target ~ .get(0) reduces object to DOM element + if (typeof target.get(0) === 'undefined') { + target = $("#" + tabbed.getHash()); + } + + // attempt to match the tab title + const title = target.closest('.c-tabbed-content').data('tab-title'); + + /** D E L I V E R */ + if (typeof title !== 'undefined') { + tabbed.tabs.each(function(){ + if ($(this).text() === title) { + + // show the right tab + tabbed.show($(this)); + + // scroll to the item + $('html,body').animate({ + scrollTop: (target.offset().top - 20) + }, 'slow'); + return false; + } + }); + } + } + }; + + $.fn.mojTabbedContent = () => { // create panels var then assign u-current to first panel to display first panel - var panels = $('.js-tabbed-content') - panels.filter(':first-of-type').show().addClass('u-current') + tabbed.panels = $('.js-tabbed-content'); + tabbed.panels.filter(':first-of-type').show().addClass('u-current'); // create tabs var then assign u-current to first tab to display first tab - var tabs = $('.c-tabbed-content__nav li') - tabs.attr("tabindex", "0").attr('aria-selected', 'false') - $('.c-tabbed-content__nav li:first-child').addClass('u-current').attr('aria-selected', 'true') + tabbed.tabs = $('.c-tabbed-content__nav li'); + tabbed.tabs.attr("tabindex", "0").attr('aria-selected', 'false'); + $('.c-tabbed-content__nav li:first-child').addClass('u-current').attr('aria-selected', 'true'); - // remove nav styling if there is less than 1 tab - if (tabs.length < 1) { - $('.c-tabbed-content__nav').hide() - } - function showhidetab (tab) { - // Hide panel - tabs.removeClass('u-current').attr('aria-selected', 'false') - panels.removeClass('u-current') - panels.hide() - - // show panel - tab.addClass('u-current').attr('aria-selected', 'true') - var thisTab = tab.text() - panels.filter('[data-tab-title="' + thisTab + '"]').show().addClass('u-current') + // remove nav styling if there is less than 1 tab + if (tabbed.tabs.length < 1) { + $('.c-tabbed-content__nav').hide(); } - tabs.click( + + // try and follow hash fragments + tabbed.findAndDeliver(); + + // set up user interaction + tabbed.tabs.click( function () { - showhidetab($(this)); + tabbed.show($(this)); } - ).keyup(function (quay){ - if (quay.keyCode && quay.keyCode == "13" ){ - showhidetab($(this)); + ).keyup(function (event) { + // https://api.jquery.com/event.which/ + if (event.which === 13) { + tabbed.show($(this)); } - }) - } + }); + }; + + return null; })(jQuery); diff --git a/web/app/themes/clarity/src/globals/js/script-loader.js b/web/app/themes/clarity/src/globals/js/script-loader.js index e814ca4e6..1717c40dc 100644 --- a/web/app/themes/clarity/src/globals/js/script-loader.js +++ b/web/app/themes/clarity/src/globals/js/script-loader.js @@ -34,7 +34,7 @@ jQuery(function ($) { $('.c-news-list > .js-article-item').moji_equaliser(); // Load component scripts - $('.js-tabbed-content-container').moji_tabbedContent(); + $('.js-tabbed-content-container').mojTabbedContent(); $('.js-reveal').moji_feedbackForm(); $('.js-blog-content-ajaxfilter').moji_ajaxFilter(); $('.js-condolences-filter').moji_condolencesFilter();