13

I am using Bootstrap 4 for my web page, I am facing problem with the nav-tabs.

I need to open a Forget Password Tab from the Login Tab Content page via hyperlink there.

Below code is working for me in Bootstrap 3 but not in Bootstrap 4

<ul class="nav nav-tabs" role="tablist">
    <li class="nav-item"><a class="nav-link active" href="#log-in" data-toggle="tab">Log in</a></li>
    <li class="nav-item"><a class="nav-link" href="#forgot-password" data-toggle="tab">Forgot password</a></li>
    <li class="nav-item"><a class="nav-link" href="#sign-up" data-toggle="tab">Sign up</a></li>
</ul>
<div class="tab-content">
    <div class="tab-pane fade show active" id="log-in">
        Login tab
        <a href="#forgot-password" data-toggle="tab">Go to Forget Password</a>
    </div>
    <div class="tab-pane fade" id="forgot-password">Forgt password tab</div>
    <div class="tab-pane fade" id="sign-up">sign-up tab</div>
</div>
dferenc
  • 7,918
  • 12
  • 41
  • 49
Note
  • 177
  • 1
  • 1
  • 9

2 Answers2

14

There are two approaches I can think of to solve this issue:

  1. As Bootstrap 4 does not use the url #hashes for tab navigation, a simple javascript can listen to click events on regular links and trigger additional clicks –under the hood– on the corresponding tabs.
  2. Use url #hashes and open tabs based on the change of that value. This approach also have the advantage that the tabs will be directly linkable, so you could use e.g. example.com#sign-up to open a page with a specific tab opened.

Below you will find two snippets for each approach.

1. Under the hood clicks:

$('.tab-link').on('click', function(event) {
    // Prevent url change
    event.preventDefault();
    
    // `this` is the clicked <a> tag
    $('[data-toggle="tab"][href="' + this.hash + '"]').trigger('click');
})
<ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item">
        <a class="nav-link active" id="log-in-tab" data-toggle="tab" href="#log-in" role="tab" aria-controls="log-in" aria-selected="true">Log in</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" id="forgot-password-tab" data-toggle="tab" href="#forgot-password" role="tab" aria-controls="forgot-password" aria-selected="false">Forgot password</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" id="sign-up-tab" data-toggle="tab" href="#sign-up" role="tab" aria-controls="sign-up" aria-selected="false">Sign up</a>
    </li>
</ul>

<div class="tab-content" id="myTabContent">
    <div class="tab-pane fade show active" id="log-in" role="tabpanel" aria-labelledby="log-in-tab">
        Login tab<br />
        <a href="#forgot-password" Xdata-toggle="tab" class="tab-link">Go to Forget Password</a>
    </div>
    
    <div class="tab-pane fade" id="forgot-password" role="tabpanel" aria-labelledby="forgot-password-tab">
        Forgt password tab
    </div>

    <div class="tab-pane fade" id="sign-up" role="tabpanel" aria-labelledby="sign-up-tab">
        Sign-up tab
    </div>
</div>


<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>

2. Using hashes in url:

$(document).ready(function() {
    function onHashChange() {
        var hash = window.location.hash;

        if (hash) {
            // using ES6 template string syntax
            $(`[data-toggle="tab"][href="${hash}"]`).trigger('click');
        }
    }

    window.addEventListener('hashchange', onHashChange, false);
    onHashChange();
});
<ul class="nav nav-tabs" id="myTab" role="tablist">
    <li class="nav-item">
        <a class="nav-link active" id="log-in-tab" data-toggle="tab" href="#log-in" role="tab" aria-controls="log-in" aria-selected="true">Log in</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" id="forgot-password-tab" data-toggle="tab" href="#forgot-password" role="tab" aria-controls="forgot-password" aria-selected="false">Forgot password</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" id="sign-up-tab" data-toggle="tab" href="#sign-up" role="tab" aria-controls="sign-up" aria-selected="false">Sign up</a>
    </li>
</ul>

<div class="tab-content" id="myTabContent">
    <div class="tab-pane fade show active" id="log-in" role="tabpanel" aria-labelledby="log-in-tab">
        Login tab<br />
        <a href="#forgot-password" Xdata-toggle="tab" class="tab-link">Go to Forget Password</a>
    </div>
    
    <div class="tab-pane fade" id="forgot-password" role="tabpanel" aria-labelledby="forgot-password-tab">
        Forgt password tab
    </div>

    <div class="tab-pane fade" id="sign-up" role="tabpanel" aria-labelledby="sign-up-tab">
        Sign-up tab
    </div>
</div>


<link href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"></script>
dferenc
  • 7,918
  • 12
  • 41
  • 49
  • This is also an issue I had to deal with. Glad to have found a working solution! Actually, 2 solutions. Although the second one seems to be a bit buggy. So, I'll use the first. – WebDevBooster Feb 04 '18 at 20:21
  • When I try the first solution, I get two errors. First `Uncaught RangeError: Maximum call stack size exceeded` and `Uncaught TypeError: Cannot read property 'nodeName' of undefined`. Any idea why? I wrapped the script in `jQuery(function ($) { ... });` – Cray Feb 09 '18 at 09:22
  • Hi @Cray based on the error messages, I don't think that those are related to this solution. Especially because, it does not try to read a `nodeName` property. Do you have other scripts running on the page as well? – dferenc Feb 09 '18 at 09:39
  • Yes, but I only get the error in the moment when I click on the link. And I tried it without any other scripts. with the same result :( – Cray Feb 09 '18 at 09:41
  • Doesn't your console tell which line this error is being thrown at? – dferenc Feb 09 '18 at 09:43
  • My fault.... I've linked to the wrong tab pane (the active one with the link inside)! Sorry... :( Now it works but the error is still there. The first error links to the this line of your code: `$('[data-toggle="tab"][href="' + this.hash + '"]').trigger('click');`. The second one adresses the tab.js – Cray Feb 09 '18 at 09:46
  • Sorry for an other question: Is there any chance to move the page (or start of the tab pane) to the top while clicking the link? At the moment the tab changes but the page stays at the same position. – Cray Feb 09 '18 at 09:51
  • @Cray You should give dferenc a chance to answer your question directly here: https://stackoverflow.com/questions/48692280/bootstrap-4-open-tab-from-inside-a-tab-second-link where he can earn some credit for doing so... – WebDevBooster Feb 09 '18 at 11:32
4

This can be achieved with jQuery by triggering a function that changes the tab when the link is clicked.

HTML

<ul class="nav nav-tabs" role="tablist" id="myTabs">
  <li class="nav-item">
    <a class="nav-link active" href="#log-in" data-toggle="tab">Log in</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#forgot-password" data-toggle="tab">Forgot password</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#sign-up" data-toggle="tab">Sign up</a>
  </li>
</ul>
<div class="tab-content">
  <div class="tab-pane fade show active" id="log-in">
    Login tab
    <a href="#forgot-password" data-toggle="tab" class="forgot-password-link">Go to Forget Password</a>
  </div>
  <div class="tab-pane fade" id="forgot-password">Forgt password tab</div>
  <div class="tab-pane fade" id="sign-up">sign-up tab</div>
</div>

Javascript

$( ".forgot-password-link" ).click(function() {
    $('#myTabs li:nth-child(2) a').tab('show')
});

Codepen example: https://codepen.io/Washable/pen/VQYewy

TidyDev
  • 3,470
  • 9
  • 29
  • 51