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>
Related
im a novice when it comes to this HTML stuff, so im not sure how to get this to work. Ive been following this description of tabs https://www.w3schools.com/howto/howto_js_tabs.asp
Im periodically sending a GET request and receiving a string ID, so i want to create a tab for each unique ID I receive, but im not sure how to do this.
<div class="tab">
<button class="tablinks" onclick="openCity(event, 'London')" id="defaultOpen">SOAP5</button>
<button class="tablinks" onclick="openCity(event, 'Paris')">GDAL</button>
<button class="tablinks" onclick="openCity(event, 'Tokyo')">IDK</button>
</div>
<div id="London" class="tabcontent" style="height:100%;">
<!--#include virtual='navigation.htm' -->
</div>
<div id="Paris" class="tabcontent" style="height:100%;">
<!--#include virtual='navigation.htm' -->
</div>
<div id="Tokyo" class="tabcontent" style="height:100%;">
<!--#include virtual='navigation.htm' -->
</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";
}
// Get the element with id="defaultOpen" and click on it
document.getElementById("defaultOpen").click();
</script>
function RefreshData() {
var xmlhttp = new XMLHttpRequest();
// Periodic data request
var intervalID = setInterval(function GetData() {
xmlhttp.open('GET', 'formInfo.htm', true);
if ((xmlhttp.readyState = xmlhttp.OPENED)) {
xmlhttp.send();
}
}, 1000);
xmlhttp.onreadystatechange = function () {
if (this.readyState === this.DONE) {
UpdateTabs(xmlhttp);
}
};
}
function UpdateTabs(xmlhttp) {
//How to create new tabs here?
}
I have tabs created via <button> and the content of those tabs are in separate <div></div> like this :
function openInfo(evt, toolsName) {
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(toolsName).style.display = "block";
evt.currentTarget.className += " active";
}
<button class="tablinks" onclick="openInfo(event, 'Tab1')">Tab1</button>
<button class="tablinks" onclick="openInfo(event, 'Tab2')">Tab2</button>
<div id="Tab1" class="tabcontent">
<h5>Title</h5>
<div class="a">
<p>Content</p>
</div>
</div>
but it hides all the contents by default. I'd like Tab1 to be displayed by default first. how do i modify the script?
<div id="Tab1" style="display: block;" class="tabcontent">
<h5>Title</h5>
<div class="a">
<p>Content</p>
</div>
</div>
<div id="Tab2" style="display: none;" class="tabcontent">
<h5>Title2</h5>
<div class="a">
<p>Content2</p>
</div>
</div>
If you add more tabs, keep their style display: none. Only tab1 will have style display:block
Use bootstrap tab, in which first tab will always be active if you set it as class="active" and easy to maintain as well.Follow the link to get idea about bootstrap tabs
Except it your code is fine just show or hide tabs while performing onclick event which tab you want to show or hide simple.
function openInfo(val) {
if ($("#" + val).hasClass("ActivTab")) {
$("#" + val).removeClass("ActivTab").addClass("deactivTab")
} else {
$("#" + val).addClass("ActivTab").removeClass("deactivTab")
}
}
.ActivTab {
display: block
}
.deactivTab {
display: none
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<button class="tablinks" onclick="openInfo('Tab1')">Tab1</button>
<button class="tablinks" onclick="openInfo('Tab2')">Tab2</button>
<div id="Tab1" class="tabcontent ActivTab">
<h5>Title</h5>
<div class="a">
<p>Content</p>
</div>
</div>
<div id="Tab2" class="tabcontent deactivTab">
<h5>Title2</h5>
<div class="a">
<p>Content</p>
</div>
</div>
HTML:
On your first tab, add a class of '.open'.
CSS:
.tabcontent {
display: none;
}
.tabcontent.open {
display: block;
}
JavaScript:
Set this up as a click event.
On the click, search for the '.tabcontent.open' element and remove the .open class. Following that up with adding the '.open' class onto the clicked tab. All within the same snippet inside the click.
Easy c:
This code is just to show up data by clicking on any of the tab. What you have to do is I have wrote a corrected JavaScript code, copy and replace your JS code with this code and you are done.
function openInfo(evt, toolsName) {
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(toolsName).style.display = "block";
evt.currentTarget.className += " active";
}
tabcontent = document.getElementsByClassName("tabcontent");
for (i = 1; 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";
}
// 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);
};
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>
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>