Clients often request for anchor links to automatically open tabs or accordions. This has changed A LOT throughout the years, so the how-to will be displayed by the version of bootstrap it works with, starting with the most recent.
With most/all of these, the console logs from debugging have been left in place, but commented out, so they can be uncommented for testing if needed.
Bootstrap 5
Probably needs work/refining/refactoring, but worked on Shore United’s remake.
How To
banno-functions.js
Add the following into the methods section of the banno-functions.js file.
accordionTabAnchor: function() {
// console.log('inside top of accordiontabanchor function')
let hash = window.location.hash.substring(1);
// Determine if hash is going to tab or accordion
if (document.querySelectorAll('.nav.nav-tabs').length > 0) {
//tabs exist, make sure hash link is within tab
let closestPaneId = document.getElementById(hash).closest('.tab-pane');
if (closestPaneId) {
// console.log('anchor tag with ID same as # in URL has been found')
let closestPaneIdLabel = closestPaneId.getAttribute('aria-labelledby');
document.getElementById(closestPaneIdLabel).click();
const scrollIntoViewWithOffset = (selector, offset) => {
setTimeout(function() {
window.scrollTo({
behavior: 'smooth',
top: document.getElementById(selector).getBoundingClientRect().top - document.body.getBoundingClientRect().top - offset,
})
},1000)
}
scrollIntoViewWithOffset(hash,150);
} else {
// console.log('hash link exists but is not within tab');
}
} else {
// console.log('no tabs on the page');
}
// URL includes link to accordion
if (document.querySelectorAll('.accordion').length > 0) {
let closestAccordionId = document.getElementById(hash).closest('.collapse');
if (closestAccordionId) {
// console.log('anchor tag with ID same as # in URL has been found')
let closestAccordionIdLabel = closestAccordionId.getAttribute('aria-labelledby');
document.getElementById(closestAccordionIdLabel).click();
const scrollIntoViewWithOffset = (selector, offset) => {
setTimeout(function() {
window.scrollTo({
behavior: 'smooth',
top: document.getElementById(selector).getBoundingClientRect().top - document.body.getBoundingClientRect().top - offset,
})
},1000)
}
scrollIntoViewWithOffset(hash,150);
} else {
// console.log('hash link exists but is not within tab');
}
} else {
// console.log('no accordions on the page');
}
if (document.querySelectorAll('.modal').length > 0) {
// console.log("there are modals");
document.querySelectorAll('.modal').forEach(function(modal) {
if (hash) {
let anchor = modal.querySelector('a#' + hash);
if (anchor && modal.contains(anchor)) {
const modalInit = new bootstrap.Modal(modal)
modalInit.show();
} else {
// console.log('hash link exists but is not within modal');
}
}
})
}
},
scripts.js
Within the window.addEventListener('load', function() { section (scripts when the page is fully loaded), inside of the “if not in CMS” function, put this to call the method whenever a link with an anchor is clicked.
//Open accordion on click of anchor link
if(window.location.hash) {
banno.methods.accordionTabAnchor();
} else {
//no anchor, so do nothing
}
Example Sites
- Shore United 2023 remake (anchor to tab | anchor to accordion)
Bootstrap 4
This one was particulary intense. It works for both anchors and tabs. In terms of functionality, you can just create an anchor in the CMS as the first item within the main body content of the anchor or tab. Then, the script will find that anchor and open the associated accordion/tab for you on page load.
The code below is from Limestone, because it includes the most recent addition of anchoring to slides.
How To - Scripts
banno-functions.js
Place this code anywhere in your banno-functions.js file.
// Detect anchors, so you can do other things with them
$('a[href*="#"]').each(function() {
$(this).addClass('anchor');
});
// Functionality for accordions and tabs that are linked to from the menu
banno.site.accordionTabAnchor = function() {
console.log('inside top of accordiontabanchor function')
var hash = window.location.hash;
var anchor = $('a' + hash);
// Link to Accordion
if ($('.card.accordion').length > 0) {
// console.log('there are visible accordions');
$('.collapse').each(function() {
if($(this).has(anchor).length) {
$(this).collapse('show');
setTimeout(function() {
$('html, body').animate({
scrollTop: $(hash).offset().top - 60 //sticky header space and/or accordion heading
}, 500);
}, 500);
} else {
// console.log('anchor does not exist in accordion');
}
})
} else {
// console.log('no accordions on the page');
}
// Link to Tab
if ($('.nav.nav-tabs').length > 0) {
// console.log('there are visible tabs');
$('.tab-content .tab-pane').each(function() {
if($(this).has(anchor).length) {
var tabID = $(this).attr('aria-labelledby');
$('.nav.nav-tabs .nav-item .nav-link#' + tabID).tab('show');
// console.log('tab should be open now');
setTimeout(function() {
$('html, body').animate({
scrollTop: $(hash).offset().top - 60 //sticky header space and/or accordion heading
}, 500);
// console.log('scroll complete');
}, 500);
} else {
// console.log('anchor does not exist in tab pane');
}
});
} else {
// console.log('no tabs on the page');
}
// Link to Slick Slide
if ($('.slick-slider').length > 0) {
// console.log('there are visible slides');
$('.slick-slide').each(function() {
if($(this).has(anchor).length) {
setTimeout(function() {
$('html, body').animate({
scrollTop: $(hash).offset().top - 60 //sticky header space and/or accordion heading
}, 500);
// console.log('scroll complete');
}, 500);
var thisSlideId = $(this).attr("data-slick-index"),
thisSlideFullSlider = $(this).parents('.slick-slider');
// console.log(thisSlideId);
thisSlideFullSlider[0].slick.slickGoTo(parseInt(thisSlideId));
} else {
// console.log('anchor does not exist in slide');
}
});
} else {
// console.log('no slides on the page');
}
}
scripts.js
Place this code within the ELSE of the window load function so that it runs only on the published page.
//Open accordion on click of anchor link
if(window.location.hash) {
banno.site.accordionTabAnchor();
} else {
//no anchor, so do nothing
}
Example Sites
- Busey Bank (anchors to tab)
- TLC Community Credit Union (code exists on site, but not currently being used)
- Limestone Bank
Bootstrap 3
It sees if there is an anchor in the URL once the page is loaded, and then finds the closest panel-collapse and opens it, and then scrolls to show the full thing.
How To
The code should be placed in the ELSE statement of the script.js file.
//Open accordion on click of anchor link on a SEPARATE page
if(window.location.hash) {
var hash = window.location.hash;
$('a' + hash).closest('.panel-collapse').collapse('show');
var id = window.location.hash;
if( id.charAt(1) != "!") {
if (window.location.hash.length > 0 && $(' ' + id + ' ').length == 1) {
$('html, body').animate({
scrollTop: $(id).offset().top - 85 // normally this would be used for sticky header but I'm using it for accordion heading
}, 500);
}
}
} else {
//no anchor, so do nothing
}
//Open accordion on click of anchor link - this section should work if anchor and accordion are on the same page
$('a[data-link-type-id="anchor"]').click(function(e) {
var anchor = $(this).attr('href').split('#')[1];
$('#checkingpanels .panel .panel-body a#' + anchor).closest('.panel-collapse').collapse('show');
$('#checkingpanels .panel .panel-body a#' + anchor).closest('.panel-collapse').parents('.panel').siblings('.panel').children('.panel-collapse').collapse('hide');
});
Example Sites
- First Heritage Federal Credit Union (Open a specific accordion based on an anchor. “View all rates” link takes you directly to a specific accordion on the rates page.)
- Honesdale Bank
Bootstrap 2
Example Sites
- Self Reliance NY AND second example link on same site (Open a specific tab based on anchor. Links with anchors set in menu builder, and it opens a different tab depending on what the anchor is.)
Tags: bs2, bs3, bs4, bs5 anchor, tab, slide, script, js, jquery, javascript, modal, accordion, scroll, slider, slick