Show/hide div in JS - javascript

I'm pretty fresh to JS.
For n amount of bar divs I have n amount foo divs. By clicking on bar[1], I want foo[1] to show or hide. The same goes for bar[2]/foo[2], bar[5]/foo[5], bar[3]/foo[3],...bar[n]/foo[n] in no exact order.
With this code I am able to show and hide, but only all of the divs at the same time. What should I change, so that I am able to hide or show only one of the divs?
function getContent() {
var x = document.getElementsByClassName("foo");
for (var i = 0; i < x.length; i++) {
if (x[i].style.display === "none") {
x[i].style.display = "block";
} else {
x[i].style.display = "none";
}
}
}
document.querySelector(".bar").addEventListener("click", getContent);
.foo {
display: none;
}
.bar {
padding: 5px;
display: block;
}
<div>
<div class="bar" onclick="getContent()">bar</div>
</div>
<div class="foo">foo</div>

No need to use JS here, HTML is more powerful than you think: if you want to show-or-hide information, the <details> element's got you covered.
.all-or-nothing summary {
display: inline-block;
cursor: pointer;
}
<details class="all-or-nothing">
<summary>Toggle all divs</summary>
<div>
The first div
</div>
<div>
The second div
</div>
<div>
The third div
</div>
</details>

Use a variable to hold the index of the current DIV to show, rather than looping over all the DIVs.
let fooIndex = 0;
let allFoo = document.querySelectorAll(".foo");
function getContent() {
if (fooIndex < allFoo.length) {
allFoo[fooIndex].classList.toggle("foo");
allFoo[fooIndex].classList.toggle("bar");
fooIndex++;
}
}
document.querySelector(".bar").addEventListener("click", getContent);
.foo {
display: none;
}
.bar {
padding: 5px;
display: block;
}
<div>
<div class="bar">bar</div>
</div>
<div class="foo">foo1</div>
<div class="foo">foo2</div>
<div class="foo">foo3</div>
<div class="foo">foo4</div>

//let fooIndex = 0;
function getContent() {
var x = $(".card");
x.append('<div class="foo" onclick="hideContent(this)">foo1</div>');
//$(this).addClass('bar');
}
function hideContent(a) {
$(a).removeClass('foo');
$(a).addClass('bar');
}
.foo {
display: none;
}
.bar {
padding: 5px;
display: block;
}
<div class="card">
<div onclick="getContent();" class="bar">bar</div>
</div>

Related

Changing display after animation

I'm trying to change an element's display to none after a CSS transition. This is because I want elements below the removed to move up (or down) to take the removed element's place. The transition is working, but it doesn't change the display.
.glossary-item {
margin: 20px 0;
padding: 20px;
box-sizing: border-box;
border: 1px solid;
opacity: 1;
}
.hidden {
display: none;
}
.transition.hidden {
display: block;
opacity: 0;
}
.transition {
transition: opacity 1s ease;
}
<input type="text" id="glossaryFilter" onkeyup="myFunction()" placeholder="Search..">
<div id="glossary-container">
<div class="glossary-item">
<div class="glossary-body">
<h5 class="glossary-title">Title</h5>
<p>Content</p>
</div>
</div>
<div class="glossary-item">
<div class="glossary-body">
<h5 class="glossary-title">Other</h5>
<p>Stuff</p>
</div>
</div>
</div>
function myFunction() {
var input, filter, cards, cardContainer, h5, title, i;
input = document.getElementById("glossaryFilter");
filter = input.value.toUpperCase();
cardContainer = document.getElementById("glossary-container");
cards = cardContainer.getElementsByClassName("glossary-item");
for (i = 0; i < cards.length; i++) {
title = cards[i].querySelector(".glossary-body h5.glossary-title");
if (title.innerText.toUpperCase().indexOf(filter) > -1) {
cards[i].classList.add('transition');
cards[i].classList.remove('hidden');
} else {
cards[i].classList.add('transition');
cards[i].classList.add('hidden');
}
}
}
the class:
displayNone{
display: none;
}
some js:
const afterAnimate = (()=>{
setTimeout(()=>{
//change "elem" to the fitting element
elem.classList.add("displayNone");
}, 1000);
})
//add the function-call to your event which triggers the animation
afterAnimate();

How to chain javascript hide/show function for each div ID?

I have many <p>s with the same function.
document.getElementById("minus").onclick = function() {
functionHide()
};
function functionHide() {
document.getElementById("plus").style.display = "block";
document.getElementById("minus").style.display = "none";
}
document.getElementById("plus").onclick = function() {
functionShow()
};
function functionShow() {
document.getElementById("plus").style.display = "none";
document.getElementById("minus").style.display = "block";
}
#plus {
display: none;
cursor: pointer;
}
#minus {
cursor: pointer;
}
.floatright {
float: right
}
.w50 {
width: 50%;
text-align: center;
}
<div class="w50">
<p>What paperwork do I need to complete to file for divorce ?
<span class="floatright inlineb" id="minus">- </span>
<span class="floatright inlineb" id="plus">+</span>
</p>
<p>How do I change my custody and suport orders ?
<span class="floatright inlineb" id="minus">- </span>
<span class="floatright inlineb" id="plus">+</span>
</p>
</div>
When I click on the first minus ( "-" ) it works correctly.
but for the second, it doesn't work.
I want to know how can I automatically chain for all others divs. they have the same typing code.
Also, I would know how can I change the last element (" - ") when an another + is clicked?
Here is a preview of what I want to do
And a fiddle: https://jsfiddle.net/khrismuc/prsebqg3/15/
You are using duplicate IDs, which is a no-no. Here is an example using classes and .querySelectorAll.
var minuses = document.querySelectorAll(".minus");
var pluses = document.querySelectorAll(".plus");
minuses.forEach(function(minus) {
minus.addEventListener('click', functionHide);
});
pluses.forEach(function(plus) {
plus.addEventListener('click', functionShow);
});
function functionHide() {
pluses.forEach(function(plus) {
plus.style.display = "block";
});
minuses.forEach(function(minus) {
minus.style.display = "none";
});
}
function functionShow() {
pluses.forEach(function(plus) {
plus.style.display = "none";
});
minuses.forEach(function(minus) {
minus.style.display = "block";
});
}
You can modify for your particular uses.
Your logic needs to be slightly more complex:
var current = -1;
function handleClick(clicked) {
$(".w50 p").removeClass("active").find("span").text("+");
$("#box p").hide();
if (current === clicked) {
current = -1;
return;
}
current = clicked;
$(".w50 p").eq(current).addClass("active").find("span").text("-");
$("#box p").eq(current).show();
}
$(document).ready(function() {
$(".w50 p").each(function(i, el) {
$(this).append($("<span>").text("+"));
$(this).click(function() {
handleClick(i);
});
});
$(".w50 p").eq(0).click();
});
.w50 {
width: 80%;
text-align: center;
}
.w50 p {
cursor: pointer
}
.w50 p.active {
color: orange
}
.w50 p span {
float: right;
width: 1em;
display: inline-block;
}
#box {
background-color: orange;
margin: 20px;
min-height: 6em;
}
#box p {
display: none;
padding: 1em
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="w50">
<p>What paperwork do I need to complete to file for divorce?</p>
<p>How do I change my custody and support orders?</p>
</div>
<div id="box">
<p>Paperwork description</p>
<p>Custody description</p>
</div>

Style is being added to the last child among a set of elements, instead of the last child of the selected element

var NavLinks = document.querySelectorAll('.nav-link');
var circuses = document.querySelectorAll('.circle');
for (var i = 0; i < NavLinks.length; i++) {
var navLink = NavLinks[i];
navLink.addEventListener('click', function () {
for (var i = 0; i < circuses.length; i++) {
var circle = circuses[i];
circle.style.display='none';
}
var theLastChild = navLink.lastChild;
theLastChild.style.display='block';
}
);
}
.nav-container{
height: 10px;
background: white;
padding: 30px 0px 40px 0px;
margin-left: 18%;
margin-right: 18%;
}
.nav-body ul{
text-align: right;
}
.nav-body ul li{
display: inline- block;
float: left;
margin-right: 30px;
}
#logo{
margin-right: 0px;
}
.nav-body ul li{
line-height: 0.6;
}
#logo{
margin-top: -10px;
}
#logo-light-blue{
color: #5dc5ef;
font-weight: 900;
}
#logo-dark-blue{
color: #1885c8;
font-weight: 900;
}
.circle {
display: none;
width: 8px;
height: 8px;
background: #5dc5ef;
/* -moz-border-radius: 50px;
-webkit-border-radius: 50px; */
border-radius: 4px;
margin: auto;
margin-top: 7px;
}
<header class="nav-container">
<nav class="nav-body">
<ul>
<li class="nav-link">צור קשר
<div class="circle"></div></li>
<li class="nav-link">המלצות ומאמרים
<div class="circle"></div></li>
<li class="nav-link">שאלות נפוצות
<div class="circle"></div></li>
<li class="nav-link">אודות ד"ר שי מרון אלדר
<div class="circle"></div></li>
<li class="nav-link">אודות ההליכים
<div class="circle"></div></li>
<li class="nav-link">ראשי
<div class="circle"></div></li>
<li id="logo"> <h3> <span id="logo-light-blue"> ד"ר </span><span id="logo-dark-blue"> שי מרון אלדר </span></h3><br>
<h6> פתרונות כירורגיים להשמנת יתר וניתוחים זעיר פולשניים</h6></li>
</ul>
</nav>
</header>
I need to make a blue circle under that category menu, which I pressed. But now blue circle added only to last menu category. Doesn't matter which one was pressed.
I looking for the last child of that menu category which was pressed. But it shows me every time last child of all menu categories.
What is wrong?
>
You have errors in HTML. Span tags need to be closed.
<li id="logo">
<h3>
<span id="logo-light-blue"> ד"ר </span>
<span id="logo-dark-blue"> שי מרון אלדר </span>
</h3>
<br>
<h6> פתרונות כירורגיים להשמנת יתר וניתוחים זעיר פולשניים</h6>
</li>
And Id attributes should be unique to the element, you are repeating the circle as an Id all over the place.
<div id="circle"></div></li>
It this doesn't solve it, try explaining the question better since even in the demo you have put result is all over the place. Are we missing some CSS or a style lib?
EDIT: I think I know what you wanna, is it this? Have a look at fiddle:
fiddle here
Do you need circle removed from other elements once you click your element?
If you need the circle to be only on 1 element, it needs to be removed from others.
Here is a fiddle showing that:
fiddle with only 1 circle
Difference is in:
var NavLinks = document.querySelectorAll('.nav-link');
for (var i = 0; i < NavLinks.length; i++) {
var navLink = NavLinks[i];
navLink.addEventListener('click', function (event) {
var allNavs = document.querySelectorAll('.nav-link div');
for (var it = 0; it < allNavs.length; it++){
console.log(allNavs[it]);
allNavs[it].classList.add('invisible');
allNavs[it].classList.remove('circleVisible');
}
console.log(allNavs);
var targetElement = event.target || event.srcElement;
var circleDiv = targetElement.parentNode.querySelectorAll('div');
console.log(circleDiv[0]);
circleDiv[0].classList.add('circleVisible');
circleDiv[0].classList.remove('invisible');
console.log(circleDiv[0]);
}
);
}
I have left console.logs, so you see how it works, remove them when running the code for real :)
The first big problem I see is you have nested for loops but are using the same iterator variable of i. If you are going to next the loops, you need the inner loop to have a different variable. In situations like this, I will often use ii just because it's easy.
Furthermore, you seem to be doing this in a roundabout way. I'm not entirely sure what you need, but if it is as it appears, then this solution is simpler.
CSS
.circle {
display: none;
... other attributes
}
.active-menu-item > .circle {
display: block;
}
JavaScript
var NavLinks = document.querySelectorAll('.nav-link');
for (var i = 0; i < NavLinks.length; i++) {
var navLink = NavLinks[i];
navLink.addEventListener('click', function () {
for (var ii = 0; ii < NavLinks.length; ii++) {
NavLinks[ii].classList.remove("active-menu-item");
}
navLink.classList.add("active-menu-item");
});
}

opens a box within page when link is clicked

I don't know where to start and what to search. I have two links in my HTML file. I want a box within the page to appear below the link when the link above is clicked and when I clicked the second link, the first box will disappear and the other box below the second link will appear. It is like a sliding box as the link is clicked. What is the code/post for this? Thank you so much!
May be called a content switcher or a tabs widget. Here's a simple way of doing it in CSS.
.box {
display: none;
}
.box:target {
display: block;
}
one two
<div id="one" class="box">box one</div>
<div id="two" class="box">box two</div>
And here's a way to do it in JS
var links = document.getElementsByTagName('a'),
boxes = document.getElementsByClassName('box');
for (var i = 0; i < links.length; i++) {
links[i].addEventListener('click',function(e) {
e.preventDefault();
var url = this.getAttribute('href').replace('#','');
for (var j = 0; j < boxes.length; j++) {
boxes[j].classList.remove('active');
}
document.getElementById(url).classList.add('active');
})
}
.box {
display: none;
}
.active {
display: block;
}
one two
<div id="one" class="box">box one</div>
<div id="two" class="box">box two</div>
I dont understand you but i guess you want some thing like this :
function myFunction() {
var x = document.getElementById('myDIV');
if (x.style.display === 'none') {
x.style.display = 'block';
} else {
x.style.display = 'none';
}
}
#myDIV {
width: 100%;
padding: 50px 0;
text-align: center;
background-color: lightblue;
margin-top:20px;
}
<p>Click the "Try it" button to toggle between hiding and showing the DIV element:</p>
<button onclick="myFunction()">Try it</button>
<div id="myDIV">
This is my DIV element.
</div>

display a div below a selected input field? No JQuery

how to display a div everytime a user focus on a input field. there is already a div and it is hidden. the position of the div will change depending on the position of the selected field and it will be display below
this is my code
formFieldListWrapper.style.top = ((((formSelectedFieldInput.offsetTop > (formWrapper.offsetHeight/2))?((formSelectedFieldInput.offsetTop-(formWrapper.offsetHeight/2))-(formSelectedFieldInput.offsetHeight+formWrapper.offsetHeight*0.02)):(formSelectedFieldInput.offsetTop))/formWrapper.offsetHeight)*100) + "%";
formFieldListWrapper.style.left = ((formSelectedFieldInput.offsetLeft/formWrapper.offsetWidth)*100) + "%";
Why use javascript? This could be chieved by using CSS only
HTML
<div class="holder">
<input type="text" />
<div class="dropdown">
<p>Testing</p>
<p>Css ONLY</p>
<p>Dropdown</p>
</div>
</div>
CSS
.holder {
position: relative;
}
.dropdown {
position: absolute;
border: 1px solid red;
display: none;
}
input:focus + .dropdown {
display: block;
}
UPDATE
little bit misred the question, if You need to position div dynamically like in this fiddle, You cloud use:
HTML
<div class="holder">
<input type="text" />
</div>
<div class="holder" style="margin-top: 30px;">
<input type="text" />
</div>
<div class="dropdown">
<p>Testing</p>
<p>Css ONLY</p>
<p>Dropdown</p>
</div>
CSS
.holder {
position: relative;
}
.dropdown {
position: absolute;
border: 1px solid red;
display: none;
z-index: 1;
background: white;
}
input:focus + .dropdown {
display: block;
}
Javascript to position dropdown div
var inputs = document.querySelectorAll('input');
for (var i = 0; i < inputs.length; i++) {
inputs[i].addEventListener('focus', function(){
this.parentNode.appendChild(document.querySelector('.dropdown'));
});
}
Try the following:
formSelectedFieldInput.addEventListener("focus", setDivToInput, false);
function setDivToInput(e)
{
var inputElement = e.target; //e.target refers to the element that fired the event.
formFieldListWrapper.style.top = inputElement.offsetTop + formFieldListWrapper.offsetHeight + "px";
formFieldListWrapper.style.left= inputElement.offsetLeft + "px";
formFieldListWrapper.style.display = "block";
}
The first line adds a focus event to the input. This sets the div to the input based upon it's position on the page. This is very basic and doesn't behave well when the div runs of the screen. You need to add logic for that.
Now for multiple inputs in a form
var nodes = form.querySelectorAll("input"); //replace with your form element
for (var i = 0; i < nodes.length; ++i)
{
nodes[i].addEventListener("focus", setDivToInput, false);
}
function setDivToInput(e)
{
var node = e.target;
formFieldListWrapper.style.top = node.offsetTop + formFieldListWrapper.offsetHeight + "px";
formFieldListWrapper.style.left= node.offsetLeft + "px";
formFieldListWrapper.style.display = "block";
}
This code sets the focus event to all inputs in the form.

Categories