HTML tabs with content in separate files - javascript

I am at the moment using this code for HTML/JS tabs.
But the code gets way to messy since it is all in one file, is it possible to separate the code in tab one, tab two etc?
<!-- Tab links -->
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'London')">London</button>
<button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<!-- Tab content -->
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of Japan.</p>
</div>
And the JavaScript
function openCity(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
Also, at the moment it does not show which tab you are on. Ideally would be to have /#tab1, /#tab2 etc.
Any suggestions?

Well, that code is OK. So this should mean your not including your JS correctly.
I just copied your code and pasted ( I just modified the begining of the script to hide all tabcontents)
var tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
function openCity(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'London')">London</button>
<button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<!-- Tab content -->
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of Japan.</p>
</div>

Related

onclick show all hidden elements

On click of the different letters the following code is showing the corresponding elements. But I'm struggling to to show all elements when someone clicks "All".
How could I achieve this?
function openCity(evt, cityName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(cityName).style.display = "block";
if (evt) {
evt.currentTarget.className += " active"
}
}
<a class="tablinks" onclick="openCity(event, 'All')">All</a>
<a class="tablinks" onclick="openCity(event, 'A')">A</a>
<a class="tablinks" onclick="openCity(event, 'B')">B</a>
<a class="tablinks" onclick="openCity(event, 'C')">C</a>
<div id="A" class="tabcontent">
<h3>A</h3>
Abschreibung
</div>
<div id="B" class="tabcontent">
<h3>B</h3>
Bauvorhaben
</div>
<div id="C" class="tabcontent">
<h3>C</h3>
</div>
document.getElementById(cityName).style.display = "block";
So the problem is this line errors out when the "cityName" argument is "All".
So you just need to handle that scenario, and whenever you get "All" in that variable you can instead display all elements.
I have fixed the code in snippet below:
function openCity(evt, cityName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
if (cityName != 'All') {
document.getElementById(cityName).style.display = "block";
} else {
// Display all
var elements = document.querySelectorAll(".tabcontent");
for (var i = 0; i < elements.length; i++) {
elements[i].style.display = "block";
}
}
if (evt) {
evt.currentTarget.className += " active"
} else {
document.getElementById("defaultOpen").className += " active"
}
}
<a class="tablinks" id="defaultOpen" onclick="openCity(event, 'All')">All</a>
<a class="tablinks" onclick="openCity(event, 'A')">A</a>
<a class="tablinks" onclick="openCity(event, 'B')">B</a>
<a class="tablinks" onclick="openCity(event, 'C')">C</a>
<div id="A" class="tabcontent">
<h3>A</h3>
Abschreibung
</div>
<div id="B" class="tabcontent">
<h3>B</h3>
Bauvorhaben
</div>
<div id="C" class="tabcontent">
<h3>C</h3>
</div>
I would use a separate function for the all and just loop through the tab content divs to show them all:
function openAll() {
// show all tab content divs
var tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "block";
}
// add active class to all as they are all open
var tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.add("active");
}
}
function openCity(evt, cityName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].classList.remove("active");
}
document.getElementById(cityName).style.display = "block";
if (evt) {
evt.currentTarget.classList.add("active");
}
}
.tabcontent {
display:none;
}
.active {
color:green;
}
<a class="tablinks" onclick="openAll()">All</a>
<a class="tablinks" onclick="openCity(event, 'A')">A</a>
<a class="tablinks" onclick="openCity(event, 'B')">B</a>
<a class="tablinks" onclick="openCity(event, 'C')">C</a>
<div id="A" class="tabcontent">
<h3>A</h3>
Abschreibung
</div>
<div id="B" class="tabcontent">
<h3>B</h3>
Bauvorhaben
</div>
<div id="C" class="tabcontent">
<h3>C</h3>
</div>
I would also use .classList to add and remove classes properly (rather than appending and then replacing them)
You have to check the condition for which the parameter is all and not anything else. If it is anything else then display that id. Added a switch statement. Loop over every class and display them when "All" is clicked, else add a default option and first hide everything and display what is clicked.
function openCity(evt, cityName) {
Array.from(document.getElementsByClassName("tablinks")).forEach(ele => ele.classList.remove('active'))
evt.target.classList.add('active')
switch (cityName) {
case "All":
Array.from(document.getElementsByClassName("tabcontent")).forEach(ele => ele.style.display = 'block')
break;
default:
Array.from(document.getElementsByClassName("tabcontent")).forEach(ele => ele.style.display = 'none');
document.getElementById(cityName).style.display = 'block'
break;
}
}
.tabcontent {
display: none;
}
.active {
color:green;
}
<a class="tablinks" onclick="openCity(event, 'All')">All</a>
<a class="tablinks" onclick="openCity(event, 'A')">A</a>
<a class="tablinks" onclick="openCity(event, 'B')">B</a>
<a class="tablinks" onclick="openCity(event, 'C')">C</a>
<div id="A" class="tabcontent">
<h3>A</h3>
Abschreibung
</div>
<div id="B" class="tabcontent">
<h3>B</h3>
Bauvorhaben
</div>
<div id="C" class="tabcontent">
<h3>C</h3>
</div>

How can this inline onClick code can replaced with addEventListner?

function openCity(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the button that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'London')">London</button>
<button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<!-- Tab content -->
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of Japan.</p>
</div>
The code given utilizes old methods and ES5. But, I am unable to convert it in ES6 by using addEventListner.
I am facing problem regarding parameters such as different city names used in onClick() function.enter code here
I think there's nothing wrong with your comment, but rather that there literally is no element on the page with the id "defaultOpen", so this is where the error comes from.
For the JavaScript part:
let elements = document.querySelectorAll('.tablinks');
for(var i = 0;i < elements.length; i++){
elements[i].addEventListener('click', function(){
var target = elements[i].getAttribute('data-target');
openCity(evt, document.querySelector(target));
}, false);
}
Edit your HTML to look like this:
<div class="tab">
<button class="tablinks" data-target="#London">London</button>
<button class="tablinks" data-target="#Paris">Paris</button>
<button class="tablinks" data-target="#Tokyo">Tokyo</button>
</div>
Why are we using querySelector and querySelectorAll? So that we can use any CSS selector to target our tabs. E.g. #tabs .pages.
Why are we using data-target? So that we can type anything we want into the element body.
Haven't tested it, but this might work:
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].removeAttribute('onclick');
tablinks[i].addEventListener('click', function() {
openCity(evt, evt.currentTarget.innerHTML());
}, false);
};

How to add onmouseout for tabs so that the tab content won't show up when the mouseout?

I'm trying to add an onmouseout for a tab function and I'm using w3schools tab example, which has an onmouseover and that would show the tabcontent when hovering on tablink, but the content stays in, and an onmouseout would probably solve my question, the only problem is that I have no idea how to get around that. Thanks!
Example
function openCity(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the link that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
<div class="tab">
<button class="tablinks" onmouseover="openCity(event, 'London')">London</button>
<button class="tablinks" onmouseover="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onmouseover="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital city of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital city of Japan.</p>
</div>
see how it works here
add mouseout listener to your tab div
const tabs = document.querySelector('.tab');
tabs.addEventListener("mouseout", function( event ) {
// Get all elements with class="tabcontent" and hide them
const tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "block";
}
}, false)
function openCity(evt, cityName) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the link that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
const tabs = document.querySelector('.tab');
tabs.addEventListener("mouseout", function( event ) {
// Get all elements with class="tabcontent" and hide them
const tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "block";
}
}, false)
<div class="tab">
<button class="tablinks" onmouseover="openCity(event, 'London')">London</button>
<button class="tablinks" onmouseover="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onmouseover="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital city of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital city of Japan.</p>
</div>

how to get the activated tab name using javascript

I have a tabs like a nav bar if i click on the tab the tab content will change i want to get the tab name of the activated tab how to do.
here is the code.
html:
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'London')" id="defaultOpen">London</button>
<button class="tablinks" onclick="openCity(event, 'Paris')">Paris</button>
<button class="tablinks" onclick="openCity(event, 'Tokyo')">Tokyo</button>
</div>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the capital city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of France.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of Japan.</p>
</div>
script:
function openCity(evt, cityName) {
var i, tabcontent, tablinks;
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
}
here is the reference enter link description here
var activeTabname = "";
function openCity(evt, cityName) {
activeTabname = cityName;
...
...
}
Use activeTabname whereever you need it.
OR
Find the active tab by checking the class .active
var activeTab = document.querySelector(".tabcontent.active");

How to print / append on the middle of the html div a value from a button click?

On a nav menu with onclick function (example here) that displays a div tab content I would like to pass an additional value to load a specific content. This is the current code:
<ul class="tab">
<li>London</li>
<li>Paris</li>
<li>Tokyo</li>
</ul>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the <script>document.write(ThirdValue)</script> city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of <script>document.write(ThirdValue)</script>.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of <script>document.write(ThirdValue)</script>.</p>
</div>
And this is the Javascript:
function openCity(evt, cityName, ThirdValue) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the link that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
alert(ThirdValue);
}
I am not able to get the third variable within the div. I am able to see it with alert(ThirdValue);, but using <script>document.write(ThirdValue)</script> I am not able to add it within the html.
I need to add this value within the html. How can I print / append this value within the html?
You shouldn't use document.write, since it is only working while the DOM is loading, after the DOM is ready, it won't work.
Instead place a placeholder inside the html (eg: <p>London is the {var} city of England.</p>), and replace it with ThirdValue. Here is how:
var text = document.getElementById(cityName).querySelector('p');
text.innerHTML = text.innerHTML.replace('{var}',ThirdValue);
Full code:
function openCity(evt, cityName, ThirdValue) {
// Declare all variables
var i, tabcontent, tablinks;
// Get all elements with class="tabcontent" and hide them
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 0; i < tabcontent.length; i++) {
tabcontent[i].style.display = "none";
}
// Get all elements with class="tablinks" and remove the class "active"
tablinks = document.getElementsByClassName("tablinks");
for (i = 0; i < tablinks.length; i++) {
tablinks[i].className = tablinks[i].className.replace(" active", "");
}
// Show the current tab, and add an "active" class to the link that opened the tab
document.getElementById(cityName).style.display = "block";
evt.currentTarget.className += " active";
var text = document.getElementById(cityName).querySelector('p');
text.innerHTML = text.innerHTML.replace('{var}',ThirdValue);
}
<ul class="tab">
<li>London</li>
<li>Paris</li>
<li>Tokyo</li>
</ul>
<div id="London" class="tabcontent">
<h3>London</h3>
<p>London is the {var} city of England.</p>
</div>
<div id="Paris" class="tabcontent">
<h3>Paris</h3>
<p>Paris is the capital of {var}.</p>
</div>
<div id="Tokyo" class="tabcontent">
<h3>Tokyo</h3>
<p>Tokyo is the capital of {var}.</p>
</div>

Categories