I am fairly new to Java but can't seem to fix this problem;
When using getElementsByClassName("") the toggle is not working I get the error "Cannot set property 'display' of undefined"
Also when testing this JS with getElementByID("") when double clicking on the English button the text disappeared completely. I want to keep one visible at all time (so either English/ German)
Is there a solution to fix this?
Thank you in advance :)
function showHideEnglish() {
var english = document.getElementsByClassName("text__english");
var german = document.getElementsByClassName("text__german");
german.style.display = "none";
if (english.style.display == "block") {
english.style.display = "none";
} else {
english.style.display = "block";
}
}
function showHideGerman() {
var english = document.getElementsByClassName("text__english");
var german = document.getElementsByClassName("text__german");
english.style.display = "none";
if (german.style.display == "block") {
german.style.display = "none";
} else {
german.style.display = "block";
}
}
<button onclick="return showHideEnglish();">English</button>
<button onclick="return showHideGerman();">German</button>
<div class="text__english" style="display:block;">This text is English</div>
<div class="text__german" style="display:none;">dieser Text ist auf Deutsch</div>
getElementsByClassName return a a collection of all elements with this class name
you need to access the elements inside the list
if you don't have other elements with the same class name this will work
var english = document.getElementsByClassName("text__english")[0];
var german = document.getElementsByClassName("text__german")[0];
Related
I have multiple HTML elements on the same page and I only want to show a specified 3 elements at a time. Below, I have some code that I got to work. But I have 2 functions for each button and 9 buttons. So I have been trying to figure out what I can do to reduce the bulk. By my estimate it would be 1008 lines of code for this table of contents of 9 buttons.
function clickInfoCampfer() {
var x = document.getElementById("campferfullcard1");
if (x.style.display === "block") {
x.style.display = "block";
} else {
x.style.display = "block";
}
}
function clickInfoCampferClose() {
var x = document.getElementById("pinefullcard1");
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "none";
}
}
This was my best attempt using forEach. It returns an error saying "opencard.forEach is not a function." The first part of the function is working and manages to close all the elements.
const squares = document.querySelectorAll('.table-of-contents-college-all label');
const allwoodcards = document.querySelectorAll('.all-wood-cards');
squares.forEach(square => {
square.addEventListener('click', clickOutcome)
})
function clickOutcome() {
const opencards = this.getAttribute("opencard");
//opencard=".full-card-campfer"//
allwoodcards.forEach(woodcard => {
woodcard.style.display = "none"
});
opencards.forEach(openup => {
openup.style.display = "block";
});
}
Thanks for your thoughts.
Edit
HTML was requested. This HTML is supporting the forEach Java I have above. It was altered slightly from supporting the first HTML I had. There are many more div elements, I just included Pine and Campfer as the examples.
<body>
<div class="tableofcontentscollege1 table-of-contents-college-all">
<label type="button"
id="campfer-table-button"
opencard=".full-card-campfer"
>
Campfer
</label>
<label type="button"
opencard=".full-card-pine"
>
Pine
</label>
</div>
<div class="full-card-campfer all-wood-cards"
id="campferfullcard1">
</div>
<div class="full-card-campfer all-wood-cards"
id="campferfullcard2">
</div>
<div class="full-card-campfer all-wood-cards"
id="campferfullcard3">
</div>
<div class="full-card-pine all-wood-cards"
id="pinefullcard1">
<div class="full-card-pine all-wood-cards"
id="pinefullcard2">
<div class="full-card-pine all-wood-cards"
id="pinefullcard3">
</div>
</body>
The goal here is to open the 3 div elements related (in name only) to the button, while closing any other div elements amongst the wood list.
Campfer button opens the 3 divs for the campfer information
Pine button opens the 3 divs for the pine information
Walnut button opens the 3 divs for the walnut information
and so on.
Hopefully that clears up any confusion.
I'm just guessing what you want. In the future, supply more context such as the effect you intend, your HTML, etc.
You just need to put the code you had repeated in the event listener:
const squares = document.querySelectorAll('.table-of-contents-college-all label');
squares.forEach(square => {
square.addEventListener('click', handleClick)
})
function handleClick() {
if (this.style.display === "block") {
this.style.display = "none";
} else {
this.style.display = "none";
}
}
I'm just going to create a function that allows me to hide some elements (filters on my website), while the other element ( All Categories) is selected. I'm using Sharetribe - marketplace CMS, here's mine https://rentim.sharetribe.com/
Here's piece of code I wrote to make it happen, but it's not working
document.querySelectorAll('a.home-categories-main:first-child.selected'),
function hideFilters() {
document.getElementById('filters').style.display = 'none';
};
Here is a working example on JSFiddle.
This is a simple example to what you are trying to do using the most basic HTML and JS combination.
Nothing fancy, but it works.
HTML:
<div id="first" onclick="hideFilters();">All</div>
<div id="filters">
<div>Price</div>
<div>Model</div>
<div>Date</div>
<div>Color</div>
</div>
Javascript:
var a = true;
function hideFilters(){
let x = document.getElementById("filters");
if(a){
x.style.display = "none";
}else{
x.style.display = "block";
}
a = !a;
}
Here is a working example on JSFiddle.
In Rentim you should add custom scripts with onDocumentReady function. It's executed after HTML is parsed and all elements rendered.
onDocumentReady(function() {
var filters = document.querySelector('#filters');
var allCategories = document.querySelector('.home-categories-main:first-child.selected');
filters.style.display = allCategories ? 'block' : 'none';
});
I'm learning javascript, and this simple piece of code just won't work the way I need it to.
All I need is to display the main tag at the click of a button. HOWEVER, it doesn't want to display until the SECOND click.
So the first click doesn't display the main. The second click does.
I've tried moving my coding around the html document (before/after body closing tag, etc).
I've looked through stack overflow, and similar questions don't really help my case. Or at least I don't understand how they can help me as a beginner.
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain(){
var mainSection = document.getElementsByTagName("main")[0];
if (mainSection.style.display === "none"){
mainSection.style.display = "grid";
}
else{
mainSection.style.display = "none";
}
}
main{display:none;}
<main> ... </main>
<button type="button" id="aboutLink">About</button>
There has to be something I'm missing that prevents that 1st click from firing the code. I mean, it seems simple enough???
if (mainSection.style.display === "none") is looking for an inline style tag, so instead of setting display:none; in your CSS, just set it inline on the element:
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain(){
var mainSection = document.getElementsByTagName("main")[0];
if (mainSection.style.display === "none"){
mainSection.style.display = "grid";
}
else{
mainSection.style.display = "none";
}
}
<main style="display:none;"> ... </main>
<button type="button" id="aboutLink">About</button>
As has been answered, mainSection.style.display is empty. Another option is to get the computed style of the element:
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain() {
var mainSection = document.getElementsByTagName("main")[0];
if (window.getComputedStyle(mainSection).getPropertyValue('display') === "none") {
mainSection.style.display = "grid";
} else {
mainSection.style.display = "none";
}
}
main {
display: none;
}
<main> ... </main>
<button type="button" id="aboutLink">About</button>
var aboutShow = document.getElementById("aboutLink");
aboutShow.addEventListener("click", displayMain);
function displayMain(){
var mainSection = document.getElementsByTagName("main")[0];
if (mainSection.style.display || "none" === "none"){
mainSection.style.display = "grid";
}
else{
mainSection.style.display = "none";
}
}
main{display:none;}
<main>text</main>
<button type="button" id="aboutLink">About</button>
Initially mainSection.style.display is empty, so it falls on the else part of the if statement and changes the property to none.
On the second click, the property now has the value of none, that's why it works on the second click.
The HTMLElement.style property is used to get as well as set the inline style of an element.
I have a foreach loop going through my posts and each loop produces an html card with info inside from each post.
I want to show and hide items within the card on only that one card not every card that has been loaded. But I will need something to differentiate between the individual cards so the javascript doesn't hide all the info on all of the cards.
I wanted to know if anyone knows how I can achieve this with a javascript function to search only in elements within that element and not search the whole page.
My current show hide method
function show_hide_button_one() {
var a = document.getElementById("grid-item-1");
var b = document.getElementById("grid-item-2");
a.style.display = "block";
b.style.display = "none";
}
}
function show_hide_button_two() {
var x = document.getElementById("grid-item-1");
var y = document.getElementById("grid-item-2");
y.style.display = "block";
x.style.display = "none";
}
}
But with that method it shows and hides everything with the relative class
and not just for the card in use.
Its for lot's of posts. So I need a smarter route than my own method xD
pls help.
You have a couple of different options. You can use HTML data attributes to give each card unique identifiers beyond just ID or class name, or you can just make each card's ID's unique based on the post info. (Be careful not to give more than one card the same ID, as that will mess up your code!)
Here is a good artice on HTML data attributes:
https://www.sitepoint.com/how-why-use-html5-custom-data-attributes/
PS - Also, do this instead:
function show_hide_button(c1, c2) {
var a = document.getElementById(c1);
var b = document.getElementById(c2);
a.style.display = a.style.display === "block" ? "none" : "block";
b.style.display = b.style.display === "block" ? "none" : "block";
}
}
You must be having same id for all card. Have separate id for each card/button (whatever you are trying to hide). You will achieve what you desire.
Try doing this
//HTML
<div id="card1>
...
<button id="card1id1"></button>
<button id="card1id2"></button>
</div>
<div id="card2>
...
<button id="card2id1"></button>
<button id="card2id2"></button>
</div>
// JS
function show_hide_button_one(id1,id2) {
var a = document.getElementById(id1);
var b = document.getElementById(id2);
a.style.display = "block";
b.style.display = "none";
}
}
function show_hide_button_two(id1,id2) {
var x = document.getElementById(id1);
var y = document.getElementById(id2);
y.style.display = "block";
x.style.display = "none";
}
}
// calling
show_hide_button_one("card1id1", "card1id1")
show_hide_button_two("card1id1", "card1id1")
Yesterday I asked a question about improving efficiency in my code. Today I have another question in the same spirit of trying to write less lines of code to accomplish repetitive tasks.
I have the following code:
function myIntroductionText() {
introPos.style.display = 'block';
posOne.style.display = 'none';
posTwo.style.display = 'none';
posThree.style.display = 'none';
posFour.style.display = 'none';
posFive.style.display = 'none';
posSix.style.display = 'none';
posSeven.style.display = 'none';
posEight.style.display = 'none';
posNine.style.display = 'none';
posTen.style.display = 'none';
posEleven.style.display = 'none';
backButton.style.visibility = 'hidden';
}
function myPositionOne() {
introPos.style.display = 'none';
posOne.style.display = 'block';
posTwo.style.display = 'none';
posThree.style.display = 'none';
posFour.style.display = 'none';
posFive.style.display = 'none';
posSix.style.display = 'none';
posSeven.style.display = 'none';
posEight.style.display = 'none';
posNine.style.display = 'none';
posTen.style.display = 'none';
posEleven.style.display = 'none';
backButton.style.visibility = 'visible';
}
function myPositionTwo() {
introPos.style.display = 'none';
posOne.style.display = 'none';
posTwo.style.display = 'block';
posThree.style.display = 'none';
posFour.style.display = 'none';
posFive.style.display = 'none';
posSix.style.display = 'none';
posSeven.style.display = 'none';
posEight.style.display = 'none';
posNine.style.display = 'none';
posTen.style.display = 'none';
posEleven.style.display = 'none';
}
The HTML looks something like this:
<p class="textContent" id="introductionText">Introduction Text Goes Here</p>
<p class="textContent" id="position1">content1</p>
<p class="textContent" id="position2">content2</p>
<p class="textContent" id="position3">content3</p>
Each position (i.e. introPos, posOne, posTwo) also has a corresponding function that looks essentially the same as the function above, except it changes the display based on which position it is in.
I'm thinking that I could use a loop and/or an if/else statement to make this task more efficient. I tried by using getElementsByClassName('textContent'), which (I think) produced an array containing all of the elements with that class. According to the console.log is contains [p#introductionText.textContent, p#position1.textContent, so on and so on...]. So, I wrote the following code to try to loop through it:
var blanks = document.getElementsByClassName("textContent") // this creates the array that I mentioned
for (item in blanks) {
if (blanks[0] === introductionText.textContent) {
blanks[0].style.display = 'block';
} else {
blanks[item].style.display = 'block';
}
}
I tried using p#introductionText.textContent but that returned an error. I'm very new to JavaScript so I fully recognize that I could be doing something very silly here, but any help would be appreciated.
EDIT:
The error message says Uncaught SyntaxError: Unexpected tocken ILLEGAL
I should also add that my goal is to have only one position be visible at each time. I have a "Back" and "Next" button that allows users to go from posOne to posTwo, to posThree, and so on. So, in addition to making posTwo visible, I also need to make posOne and/or posThree not visible.
Thanks!
The first thing is moving all those Javascript style expressions to CSS:
#introPos,
#posOne,
#posTwo,
#posThree,
#posFour,
#posFive,
#posSix,
#posSeven,
#posEight,
#posNine,
#posTen,
#posEleven {
display: none;
}
Or even shorter
#introductionText>.textContent {
display: none;
}
This would enable you to shorten each function considerably:
function myPositionOne() {
posOne.style.display = 'block';
backButton.style.visibility = 'visible';
}
Instead of setting each style via JS again and again, you'd simply set those that change.
The next step would be to rewrite all those functions into one that accepts a parameter which element you are targeting:
function myPosition(pos) {
var parent = document.getElementById("text-container");
var children = parent.getElementsByClassName("textContent");
var element;
// first hide all <p class="textContent"> children
for (var i = 0; i < children.length; i++) {
children[i].style.display = 'none';
if (i == pos) {
element = children[i];
}
}
// then show the right one
if (element) {
element.style.display = 'block';
}
// show or hide the back button depending on which child we are dealing with
if (pos > 0) {
document.getElementById("backButton").style.visibility = 'visible';
} else {
document.getElementById("backButton").style.visibility = 'hidden';
}
if (pos >= children.length-1) {
document.getElementById("nextButton").style.visibility = 'hidden';
} else {
document.getElementById("nextButton").style.visibility = 'visible';
}
}
This sets only the child number #pos visible and adjusts the visibility of the back button (assuming the back button has the ID "backButton").
Maybe this:
All paragraphs also have the class "textContent". Make this display none and display the correct paragraph via given paragraph-id:
function myFunction(classDisplay) {
var elems = document.getElementsByClassName('textContent');
for (var i=0;i<elems.length;i+=1){
elems[i].style.display = 'none';
}
document.getElementById(classDisplay).style.display = "block";
}
The following will hide all but position 2:
myFunction("position2");
I don't know about the back-button, this is always be visible?
EDIT: I've tested this and corrected the code.
If you use JQuery, you can also use the following instead of the for loop:
$('.textContent').css('display','none');
In newer versions of JavaScript you can use:
Array.from(document.getElementsByClassName('myclass')).forEach((item) => {
item.style.backgroundColor = "blue";
})