0

I am trying to achieve deep-linking with bootstrap 5, so that the correct tab will open automatically when using the id in the URL example.com/page#vehicle-finance-calc

<nav>
   <div class="nav nav-tabs" id="nav-tab" role="tablist">
      <button class="nav-link active" id="nav-vehicledata-tab" data-bs-toggle="tab" data-bs-target="#nav-vehicledata" type="button" role="tab" aria-controls="nav-vehicledata" aria-selected="true">All Vehicle Specs</button>
      <button class="nav-link" id="nav-finance-calc-tab" data-bs-toggle="tab" data-bs-target="#nav-finance-calc" type="button" role="tab" aria-controls="nav-finance-calc" aria-selected="false">Finance Calculator</button>
   </div>
</nav>

Thanks

Joshua
  • 25
  • 6

3 Answers3

-1

Based on this answer, you can use the following code (with jquery):

$('document').ready(function(){
    let selectedTab = window.location.hash;
    let tabTrigger = new bootstrap.Tab($('.nav-link[href="' + selectedTab + '"]:first' ));
    tabTrigger.show();
});

Update: With modern browsers, you have the option to use pure JavaScript syntax instead. Additionally, I have added code support for a mode where the tab is activated through the "data" attribute instead of via the link.:

document.addEventListener('DOMContentLoaded', function(){
    let selectedTab = window.location.hash;
    let tabTrigger = new bootstrap.Tab( document.querySelector('.nav-link[href="' + selectedTab + '"]') ?? document.querySelector('button[data-bs-target="' + selectedTab + '"]') );
    tabTrigger.show();
});
איש נחמד
  • 333
  • 2
  • 4
  • 11
  • I've tried all the examples on this thread, and none seem to be working! – Joshua Oct 07 '21 at 20:11
  • Do you use jquery? Be sure to put this code at the bottom of the page. If you have a Firefox browser consider replacing `:first` with `:first-of-type`. – איש נחמד Oct 07 '21 at 20:13
  • Yeah just nothing is working, I'm really not sure why it's not working! – Joshua Oct 07 '21 at 20:32
  • jquery is definately working, tabs are working normally, just need to access the tab with the URL! – Joshua Oct 07 '21 at 20:33
  • A jQuery solution to a Bootstrap 5 question is not ideal, since BS does not rely on jQuery anymore. It's possible, but probably not what people expect, checking the solutions here. – marcus Feb 12 '23 at 10:57
  • As you can see in this thread: https://stackoverflow.com/q/9899372 there is still no replacement for `$('document').ready` that works properly with backwards compatibility for old browsers. Additionally, although Bootstrap is a popular library for building interfaces, it does not provide a comprehensive solution for event handling and does not support certain functions such as Ajax queries. As a result, many developers continue to use the jQuery library. Therefore it is important to note that this code is based on jQuery, but this is not the place to discuss the need to use it. – איש נחמד Feb 12 '23 at 13:26
  • @אישנחמד I removed my downvote since you updated your answer to make it relevant. – marcus Feb 12 '23 at 17:17
-1

I was searching for a few hours and came across this link. It works only for href from what I can see - I did try buttons, but that didn't work.


index.html

<a href="page.html#home">Home</a> | <a href="page.html#profile">Profile</a> | <a href="page.html#contact">Contact</a> | 

page.html

<ul class="nav nav-tabs" id="myTab" role="tablist">
  <li class="nav-item" role="presentation">
    <a class="nav-link active" id="home-tab" data-bs-toggle="tab" data-bs-target="#home" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="profile-tab" data-bs-toggle="tab" data-bs-target="#profile" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
  </li>
  <li class="nav-item" role="presentation">
    <a class="nav-link" id="contact-tab" data-bs-toggle="tab" data-bs-target="#contact" href="#contact" role="tab" aria-controls="contact" aria-selected="false">Contact</a>
  </li>
</ul>
<div class="tab-content" id="myTabContent">
  <div class="tab-pane fade show active" id="home" role="tabpanel" aria-labelledby="home-tab">home</div>
  <div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">profile</div>
  <div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">contact</div>
</div>

Javascript (vanilla)

// deep linking - load tab on refresh
let url = location.href.replace(/\/$/, '');
if (location.hash) {
  const hash = url.split('#');
  const currentTab = document.querySelector('#myTab a[href="#' + hash[1] + '"]');
  const curTab = new bootstrap.Tab(currentTab);
  curTab.show();
  url = location.href.replace(/\/#/, '#');
  history.replaceState(null, null, url);
  setTimeout(() => {
    window.scrollTop = 0;
  }, 400);
}
// change url based on selected tab
const selectableTabList = [].slice.call(document.querySelectorAll('a[data-bs-toggle="tab"]'));
selectableTabList.forEach((selectableTab) => {
  const selTab = new bootstrap.Tab(selectableTab);
  selectableTab.addEventListener('click', function () {
    var newUrl;
    const hash = selectableTab.getAttribute('href');
    if (hash == '#home-tab') {
      newUrl = url.split('#')[0];
    } else {
      newUrl = url.split('#')[0] + hash;
    }
    history.replaceState(null, null, newUrl);
  });
}); 

In my case I didn't want all my UL using the same ID. So I changed it to class instead in the JS and added the class to my ul.

JS

const currentTab = document.querySelector('.deepLink a[href="#' + hash[1] + '"]');

html

<ul class="nav nav-pills nav-fill deepLink" role="tablist">

And the award goes to Viper

https://www.viperswebdesign.com/blog/how-to-add-deep-linking-to-the-bootstrap-5-tabs-component

Marina
  • 101
  • 1
  • 7
-1

Here is a modern vanilla js version for Bootstrap 5. https://codepen.io/localhorst/pen/dyqbboY

(function () {
    'use strict'
    // deep linking
    if(location.hash){
        const triggerEl = document.querySelector(location.hash)
        bootstrap.Tab.getOrCreateInstance(triggerEl).show() // Select tab by name
    }
    // add hash to url when changing tabs
    const selectableTabList = [].slice.call(document.querySelectorAll('[data-bs-toggle="tab"]'))
    selectableTabList.forEach((selectableTab) => {
        selectableTab.addEventListener('shown.bs.tab', event => {
            console.log('Previous URL: ' + location.href);
            history.replaceState(null, null, '#' + event.target.id);
        })
    });
})()
marcus
  • 699
  • 11
  • 33