Turbolinks and Bootstrap Tab activation - javascript

I am basically facing the same problem as described here, under the additional context of Rails' Turbolinks.
I am using this piece of code
$(document).on('ready page:change', function() {
/* Show tab from anchor */
var hash = window.location.hash;
hash && $('ul.nav a[href="' + hash + '"]').tab('show');
/* Update URL anchor after selecting tab */
$('.nav-tabs a').click(function (e) {
$(this).tab('show');
var scrollmem = $('body').scrollTop();
window.location.hash = this.hash;
$('html,body').scrollTop(scrollmem);
});
Which does work for manual page reload (F5) and for cache restore, but not after reloading the page from a Turbolinks click*.
*When clicking a turbolinks link, if there is some cache of the page, then that cache is first restored and the good tab is shown, but then thre is still a request to the server to get the last contents, and once that request arrives and is parsed, the tab "switches back" to the original one
My bootstrap code looks like this
<ul class="nav nav-tabs" role="tablist">
<li class="nav-item">
<a class="nav-link active" data-toggle="tab" href="#student" role="tab"></a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#mentor" role="tab"><%= </a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#company" role="tab"></a>
</li>
</ul>
<!-- Tab panes -->
<div class="tab-content">
<br />
<div class="tab-pane fade in active" id="student" role="tabpanel">
...
</div>
<div class="tab-pane fade" id="mentor" role="tabpanel">
...
</div>
<div class="tab-pane fade" id="company" role="tabpanel">
...
</div>
</div>

Rails 5 comes with Turbolinks 5. The solution was just to change the name of the event listener
$(document).on('ready turbolinks:load', function() {

Related

Bootstrap Tabs with Next Arrow If Multiple tabs exist

I hope someone will be able to help me on this issue. I'm having hard time converting it to latest bootstrap 4 tabs.
Here's the source: https://codepen.io/srees/pen/pgVLbm
But the problem is that it used the bootstrap 3 version and it doesn't have tab content.
Basically what i need to do is this
If there's a multiple tabs you can click the arrow to slide to another tabs, just like in the browser
This is where i want to do
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="contact-tab" data-toggle="tab" 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">...</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">...</div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">...</div>
</div>
I hope this will help you out
assign data-id to anchor tags with number like
HTML
Home
Home
Home
JQuery
$(document).ready(function(){
var maxTabs = $(".nav-item").length; //Get total number of Tabs
$("#next").click(function(e){
e.preventDefault();
var activeAnchor = $("ul").find("a").hasClass("active"); //Get a tag with class active
// OR you can use var activeAnchor = $("li > a").hasClass("active");
if(activeAnchor === true){ // check if any "a" has class "active"
$(this).removeClass("active"); // remove "active" class for current element
var current = $(this).attr("data-id"); // get the data-id of current element
if(current < maxTabs){ // checks if id is the last one
var nextId = current + 1; //adding 1 to current id to get the next element
$("#nextId").addClass("active"); //Adding the active class to next element
}
}
});
});
Please let me know if it works. I am not sure but maybe you encounter problem on line $(this).removeClass("active");. If you come across this issue. Please let me know I will provide an alternative solution.

Open previous tab when reloading

I'm having an issue with my site. It has a page with two tabs. In the second tab, there is a pagination and I'm using bootstrap. The issue I'm having is when I click a different page on the pagination, it goes back to the 1st tab.
I have tried to fix it using hash links. When I do that, it flashes the 1st tab for milliseconds and then shows the 2nd tab which is not what I want. I want it to show the same tab even after clicking the pagination. Also, note that I'm using Ajax.
<ul class="nav nav-tabs" id="resumes-tab">
<li class="active"><a data-toggle="tab" href="#shortlisted-resumes-list" aria-expanded="true">Shortlisted</a></li>
<li class=""><a data-toggle="tab" href="#download-resumes-list" aria-expanded="false">Downloads</a></li>
</ul>
<div class="tab-content">
<div id="shortlisted-resumes-list" class="tab-pane fade active in">
<div class="cs-resumes" data-adminurl="https://example.com/wp-admin/admin-ajax.php"></div>
</div>
<div id="download-resumes-list" class="tab-pane fade">
<div class="cs-resumes" data-adminurl="https://example.com/wp-admin/admin-ajax.php">
<nav>
<ul class="pagination">
<li><a aria-label="Previous"><span aria-hidden="true"><i class="icon-angle-left"></i>Previous</span></a></li>
<li><a class="active">1</a></li>
<li><span aria-hidden="true">Next <i class="icon-angle-right"></i></span></li>
</ul>
</nav>
</div>
</div>
</div>
Here's my jQuery snippet
<script>
// Javascript to enable link to tab
var hash = document.location.hash;
var prefix = "";
if (hash) {
jQuery('.nav-tabs a[href="' + hash.replace(prefix, "") + '"]').tab('show');
}
// Change hash for page-reload
jQuery('.nav-tabs a').on('shown.bs.tab', function (e) {
var hash = document.location.hash;
window.location.hash = e.target.hash.replace("#", "#" + prefix);
jQuery("html, body").animate({ scrollTop: $(".cs-dash-resumes-tabs").offset().top }, "slow");
});
</script>
Why does this happen? Because I'm using Ajax?

How can I open a bootstrap 3 tab from external link?

I want to create a link that will target a specific tab, in another page of my site.
I have tried to create link like this: www.example.com/test.html#tab2, but it always targets the first tab (I guess the tab with show class).
index.html
link for catalog
text.html
<ul class="nav nav-tabs">
<li id="homeTab" class="active"><a data-toggle="tab" href="#home" aria-expanded="true">menu 1</a></li>
<li id="menu1Tab"><a data-toggle="tab" href="#menu1">menu 2</a></li>
<li id="menu2Tab"><a data-toggle="tab" href="#menu-catalog">menu 3</a></li>
<li id="menu3Tab"><a data-toggle="tab" href="#menu3">menu 4</a></li>
</ul>
<div class="tab-content">
<div id="home" class="tab-pane fade in active">
...
</div>
<div id="menu1" class="tab-pane fade">
....
</div>
<div id="menu-catalog" class="tab-pane fade">
...
</div>
<div id="menu3" class="tab-pane fade">
...
</div>
</div>
When I click the link from index.html to target and open the tab with the right ID.
If you're using the bootstrap + jquery setup, you can get this behavior pretty easily with the following:
$(() => {
const {
hash
} = document.location;
if (!hash) return false;
$(`.nav.nav-tabs [href="${hash}"]`).tab('show');
});
Try this
$(function(){
var hash = window.location.hash;
hash && $('ul.nav a[href="' + hash + '"]').tab('show');
$('.nav-tabs a').click(function (e) {
$(this).tab('show');
var scrollmem = $('body').scrollTop();
window.location.hash = this.hash;
$('html,body').scrollTop(scrollmem);
});
});

Prevent show first active tab on tab change bootstrap 4

I have code:
if (location.hash) {
$('a[href=\'' + location.hash + '\']').tab('show');
}
var activeTab = localStorage.getItem('activeTab');
if (activeTab) {
$('a[href="' + activeTab + '"]').tab('show');
}
$('body').on('click', 'a[data-toggle=\'tab\']', function (e) {
e.preventDefault()
var tab_name = this.getAttribute('href');
if (history.pushState) {
history.pushState(null, null, tab_name)
}
else {
location.hash = tab_name
}
localStorage.setItem('activeTab', tab_name)
$(this).tab('show');
return false;
});
$(window).on('popstate', function () {
var anchor = location.hash ||
$('a[data-toggle=\'tab\']').first().attr('href');
$('a[href=\'' + anchor + '\']').tab('show');
});
<!-- Bootstrap CSS -->
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/css/bootstrap.min.css" integrity="sha384-GJzZqFGwb1QTTN6wy59ffF1BuGJpLSa9DkKMp0DgiMDm4iYMj70gZWKYbI706tWS" crossorigin="anonymous">
<!-- Optional JavaScript -->
<!-- jQuery first, then Popper.js, then Bootstrap JS -->
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script>
<ul class="nav" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="home-tab" data-toggle="tab" href="#home" role="tab" aria-controls="home" aria-selected="true">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" id="profile-tab" data-toggle="tab" href="#profile" role="tab" aria-controls="profile" aria-selected="false">Profile</a>
</li>
<li class="nav-item">
<a class="nav-link" id="contact-tab" data-toggle="tab" 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">This is home tab</div>
<div class="tab-pane fade" id="profile" role="tabpanel" aria-labelledby="profile-tab">This is profile tab</div>
<div class="tab-pane fade" id="contact" role="tabpanel" aria-labelledby="contact-tab">This is contact tab</div>
</div>
How I can prevent show first active tab, when page reloading with other tab? My tabs save on localstorage, and when I reload page with other tab, he's first display me first tab, and between my tab. How I can prevent this bug?
Remove the active (but keep the show) class from your tabs (both the links and the tabs themselves).
Also, change your "default" (on page load) script to this:
if (location.hash) {
$('a[href="' + location.hash + '"]').tab('show');
} else {
activeTab = localStorage.getItem('activeTab');
if (activeTab) {
$('a[href="' + activeTab + '"]').tab('show');
} else {
$('#home').addClass('active');
}
}
Because for some reason, using $('a[href="#home"]').tab('show'); won't work on page load (it won't show its contents), which has got to be a bug. $('#home').addClass('active'); will add back the active class to your default tab instead (only if there is no tab hash in the URL and nothing in localStorage either).

Bootstrap 3: return to dropdown tab on page refresh

I want to return the user to content that was reached by accessing a dropdown link from a bootstrap pill menu.
This question is similar to this one - but the wrinkle is that that solution does not work when the link is in a dropdown menu.
I have koppor's solution working fine as it relates to the pills themselves, but I'm stumped how to return to the same view after refresh when the content is accessed from the dropdown.
Specifically, when you navigate to the 'xxx' or 'yyy' content from the "Misc" menu, then refresh the page, the page defaults to the "home" content (even though the 'Misc' pill is still active).
<ul class="nav nav-pills" id="myTab">
<li class="active">Home</li>
<li>Profile</li>
<li class="dropdown">
<a class="dropdown-toggle" data-toggle="dropdown" href="#misc">Misc<span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a class="dropdown-toggle" href="#more_x" data-toggle="pill">xxx</a></li>
<li><a class="dropdown-toggle" href="#more_y" data-toggle="pill">yyy</a></li>
</ul>
</li>
<li>Messages</li>
<li>Settings</li>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="home">home</div>
<div class="tab-pane" id="profile">profile</div>
<div class="tab-pane" id="more_x">more info x</div>
<div class="tab-pane" id="more_y">more info y</div>
<div class="tab-pane" id="messages">messages</div>
<div class="tab-pane" id="settings">settings</div>
</div>
<script>
$('#myTab a').click(function (e) {
e.preventDefault()
$(this).tab('show')
});
// store the currently selected tab in the hash value
$("ul.nav-pills > li > a").on("shown.bs.tab", function (e) {
var id = $(e.target).attr("href").substr(1);
window.location.hash = id;
});
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
$('#myTab a[href="' + hash + '"]').tab('show');
</script>
Any/all suggestions welcomed!
I had a similar issue. What I did was create a hidden tab. When the page loads go to that tab first then load the tab you really want to load (what is in your hash).
Edit:
I was thinking of it differently. Try changing your script to this. It should set window.location.hash to the active tab whenever one is clicked.
$('#myTab a').click(function (e) {
e.preventDefault()
$(this).tab('show')
window.location.hash = $(this).attr("href");
});
// on load of the page: switch to the currently selected tab
var hash = window.location.hash;
$('#myTab a[href="' + hash + '"]').tab('show');

Categories

Resources