Finaly, I saw this topic, and used the provided code to make it work.
Solution 1 :
I had to change my radio buttons to classic ul>li tabs.
<div class="tabs">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="left-tab" data-toggle="tab" href="#tab1" role="tab" aria-controls="log-in" aria-selected="true">My first tab</a>
</li>
<li class="nav-item">
<a class="nav-link" id="right-tab" data-toggle="tab" href="#tab2" role="tab" aria-controls="forgot-password" aria-selected="false">My second tab</a>
</li>
</ul>
<div class="tab active" id="tab1"></div>
<div class="tab" id="tab2"></div>
</div>
And changed my js code like so :
1-first, to display maps correctly inside the tabs
$('.nav-item a').on('click', function() {
setTimeout(function() {
map.invalidateSize();
map2.invalidateSize();
}, 0);
});
2-then, to toggle tabs and let external url open the desired tab
$(document).ready(function() {
$('#left-tab').click(function(event) {
event.preventDefault();
$('.tabs .nav-item a').removeClass('active');
$('.tabs .tab').removeClass('active');
$(this).addClass('active');
$('#tab1').addClass('active');
})
$('#right-tab').click(function(event) {
event.preventDefault();
$('.tabs .nav-item a').removeClass('active');
$('.tabs .tab').removeClass('active');
$(this).addClass('active');
$('#tab2').addClass('active');
})
function onHashChange() {// this let me open tabs from an external url
var hash = window.location.hash;
if (hash) {
$(`[data-toggle="tab"][href="${hash}"]`).trigger('click');
}
}
window.addEventListener('hashchange', onHashChange, false);
onHashChange();
});
The problem is partially solved.
- Once on the page, if I click on the tabs, the url/hash does not change anymore.
- Also, the tab opens at the place where the ID is located, which is normal, but in my example I would on the contrary want to disable the anchor jump.
Solution 2 :
So I had to make a few changes :
$(document).ready(function() {
$('#left-tab').click(function(e) {
window.location.hash = $(this).attr("href"); //this put back the hash
if (location.hash) { // this allow to stay on top of the page
setTimeout(function() {
window.scrollTo(0, 0);
}, 1);
}
e.preventDefault()
$('.tabs .nav-item a').removeClass('active');
$('.tabs .tab').removeClass('active');
$(this).addClass('active');
$('#tab1').addClass('active');
})
$('#right-tab').click(function(e) {
window.location.hash = $(this).attr("href");
if (location.hash) {
setTimeout(function() {
window.scrollTo(0, 0);
}, 1);
}
e.preventDefault();
$('.tabs .nav-item a').removeClass('active');
$('.tabs .tab').removeClass('active');
$(this).addClass('active');
$('#tab2').addClass('active');
})
function onHashChange() { // this let me open tabs from an external url
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();
});
Now it works better. When I come from an external url, like mysite.com#tab2, it loads the page with tab2 openned. Then when I click on tab1, it opens the tab1, staying on top of the page. But, it's stil not perfect, it's still glitchy.
Solution 3 :
So I looked for others solutions, and found this topic and @jumois' answer that consist in using
'different id for the target element than what is specified in the
anchor.'
So I changed my code again like this :
$(document).ready(function() {
$('#lefttab').click(function(e) {
$(window).on("hashchange", function(){
var hash = this.location.hash;
var mytab = $(hash + "-tab");
});
$('.tabs .nav-item a').removeClass('active');
$('.tabs .tab').removeClass('active');
$(this).addClass('active');
$('#tab1-tab').addClass('active');
})
$('#righttab').click(function(e) {
$(window).on("hashchange", function(){
var hash = this.location.hash;
var mytab = $(hash + "-tab");
});
$('.tabs .nav-item a').removeClass('active');
$('.tabs .tab').removeClass('active');
$(this).addClass('active');
$('#tab2-tab').addClass('active');
})
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();
});
Of course I had to change the html part also:
<div class="tabs">
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link active" id="lefttab" data-toggle="tab" href="#tab1" role="tab" aria-controls="log-in" aria-selected="true">My first tab </a>
</li>
<li class="nav-item">
<a class="nav-link" id="righttab" data-toggle="tab" href="#tab2" role="tab" aria-controls="forgot-password" aria-selected="false">My second tab</a>
</li>
</ul>
<div class="tab active" id="tab1-tab"></div>
<div class="tab " id="tab2-tab"></div>
</div>
Now it looks much better. I can open a tab from an external url, like mysite.com#tab2
and there is no "jump to anchor" glitchy effect anymore.