How to show and hide div elements using vanilla js - javascript

Below is code where i tried to show and hide div elements using pure js. Since when i click button it take three click to hide the div elemnts and after that it run smoothly. I was trying to find how to show elemnts in first click.
var count = 0;
function showMee() {
var buttonHome = document.querySelector("#showMe");
count += 1;
buttonHome.addEventListener("click", function() {
if (count == 1) {
document.querySelector('#linkMeOne').style.display = 'none';
document.querySelector('#linkMeTwo').style.display = 'none';
} else if (count == 2) {
document.querySelector('#linkMeOne').style.display = 'block';
document.querySelector('#linkMeTwo').style.display = 'block';
count = 0;
}
});
}
#linkMeOne {
display: block;
}
#linkMeTwo {
display: block;
}
<div id="linkMeOne">
Hiding me As first time....
</div>
<div id="linkMeTwo">
Hiding me as well as...
</div>
<input type="button" value="Check Me" id="showMe" onclick="showMee()" />

Just toggle hidden.
If you want them to start out hidden, add the hidden attribute to the divs
const div1 = document.getElementById("linkMeOne");
const div2 = document.getElementById("linkMeTwo")
document.querySelector("#showMe").addEventListener("click",function() {
div1.hidden = !div1.hidden;
div2.hidden = !div2.hidden;
})
<div id="linkMeOne">
Hiding me As first time....
</div>
<div id="linkMeTwo">
Hiding me as well as...
</div>
<input type="button" value="Check Me" id="showMe" />

Just remove the addEventlistener and the code will start working.
var count = 0;
function showMee() {
var buttonHome = document.querySelector("#showMe");
count += 1;
//buttonHome.addEventListener("click", function() {
if (count == 1) {
document.querySelector('#linkMeOne').style.display = 'none';
document.querySelector('#linkMeTwo').style.display = 'none';
} else if (count == 2) {
document.querySelector('#linkMeOne').style.display = 'block';
document.querySelector('#linkMeTwo').style.display = 'block';
count = 0;
}
//});
}
#linkMeOne {
display: block;
}
#linkMeTwo {
display: block;
}
<div id="linkMeOne">
Hiding me As first time....
</div>
<div id="linkMeTwo">
Hiding me as well as...
</div>
<input type="button" value="Check Me" id="showMe" onclick="showMee()" />
Instead of using a variable, use a class to set the display to none.
function showMee() {
document.querySelector('#linkMeOne').classList.toggle('hidden');
document.querySelector('#linkMeTwo').classList.toggle('hidden')
}
#linkMeOne {
display: block;
}
#linkMeTwo {
display: block;
}
.hidden {
display: none !important;
}
<div id="linkMeOne">
Hiding me As first time....
</div>
<div id="linkMeTwo">
Hiding me as well as...
</div>
<input type="button" value="Check Me" id="showMe" onclick="showMee()" />

While there are many correct answers, all of them lack simplicity.
The easiest of all solution is to add an eventListener to the button and toggle a class to all elements with a certain class. That way you don't have to list every single element:
document.querySelector('#showMe').addEventListener('click', function() {
document.querySelectorAll('.linkMe').forEach(el =>
el.classList.toggle('d-block')
);
})
.linkMe {
display: none;
}
.d-block {
display: block;
}
<div class="linkMe">
Hiding me As first time....
</div>
<div class="linkMe">
Hiding me as well as...
</div>
<input type="button" value="Check Me" id="showMe" />

You could just toggle using a data attribute and some CSS. Here is a verbose version of that:
document.querySelector("#showMe")
.addEventListener("click", (event) => {
const t = event.target;
const showem = t.dataset.show;
document.querySelectorAll('.can-toggle').forEach((element) => {
element.dataset.show = showem;
});
t.dataset.show = showem == "show" ? "hide" : "show";
});
.can-toggle[data-show="hide"] {
display: none;
}
<div class="can-toggle">
Hiding me As first time....
</div>
<div class="can-toggle">
Hiding me as well as...
</div>
<input type="button" value="Check Me" id="showMe" data-show="hide" />
OR even independently with an initial state:
document.querySelector("#showMe")
.addEventListener("click", (event) => {
document.querySelectorAll('.can-toggle').forEach((element) => {
element.dataset.show = element.dataset.show == "hide" ? "show" : "hide";
});
});
.can-toggle[data-show="hide"] {
display: none;
}
<div class="can-toggle" data-show="hide">
Hiding me As first time....
</div>
<div class="can-toggle">
Hiding me as well as...
</div>
<div class="can-toggle" data-show="Ishow">
What am I?
</div>
<input type="button" value="Check Me" id="showMe" data-show="hide" />

Related

Toggle show/hide functions between multiple divs

I have a page on my site which has 3 separate 'hidden' divs. Each with it's own 'show/hide' button.
Currently... each div and button set functions independently.
Therefore... if all divs are shown (open) at the same time, they stack according to their respective order.
Instead of that, I would rather restrict the function a bit, so that only div can be shown (open) at a time.
Example: If Div 1 is shown, and the user then clicks the Div 2 (or Dive 3) button, Div 1 (or which ever div is open at the time, will close.
I am not sure how to adjust my code to make that all work together. I have tried a few ideas, but they were all duds. So I posted a generic 'independent' version below.
function show_Div_1() {
var div1 = document.getElementById("Div_1");
if (div1.style.display === "none") {
div1.style.display = "block";
} else {
div1.style.display = "none";
}
}
function show_Div_2() {
var div2 = document.getElementById("Div_2");
if (div2.style.display === "none") {
div2.style.display = "block";
} else {
div2.style.display = "none";
}
}
function show_Div_3() {
var div3 = document.getElementById("Div_3");
if (div3.style.display === "none") {
div3.style.display = "block";
} else {
div3.style.display = "none";
}
}
.div {
width: 270px;
height: 30px;
padding-left: 10px;
}
<button type="button" onclick="show_Div_1()">Div 1 - Red</button>
<button type="button" onclick="show_Div_2()" style="margin-left: 4px">Div 2 - Blue</button>
<button type="button" onclick="show_Div_3()" style="margin-left: 4px">Div 3 - Green</button>
<div id="Div_1" class="div" style="background-color:red; display: none;"></div>
<div id="Div_2" class="div" style="background-color:blue; display: none;"></div>
<div id="Div_3" class="div" style="background-color:green; display: none;"></div>
I would suggest using data attributes for a toggle. Why? you can use CSS for them and you can use more than just a toggle - multiple "values".
Here in this example I do your "click" but also added a double click on the button for a third value. Try some clicks and double clicks!
A bit of overkill perhaps but more than just "toggle" for example you could use this to show "states" of things like a stoplight or any number of things.
Use the grid display and move them by just adding a data attribute value and double click it to get it to go (using css) to some grid-area:, things like that.
const hideValues = {
hide: "hidden",
show: "showme",
double: "dblclick"
};
function dblClickHander(event) {
const targetSelecor = event.target.dataset.target;
const target = document.querySelector(targetSelecor);
const action = target.dataset.hideme == hideValues.double ? hideValues.hide : hideValues.double;
const toggleTargets = document.querySelectorAll('.toggle-target');
toggleTargets.forEach(el => {
el.dataset.hideme = hideValues.hide;
});
target.dataset.hideme = action;
}
function toggleEventHandler(event) {
const targetSelecor = event.target.dataset.target;
const target = document.querySelector(targetSelecor);
const showHide = target.dataset.hideme == hideValues.hide ? hideValues.show : hideValues.hide;
const toggleTargets = document.querySelectorAll('.toggle-target');
toggleTargets.forEach(el => {
el.dataset.hideme = hideValues.hide;
});
target.dataset.hideme = showHide;
}
/* set up event handlers on the buttons */
const options = {
capture: true
};
/* we do this first to prevent the click from happening */
const toggleButtons = document.querySelectorAll('.toggle-button');
toggleButtons.forEach(el => {
el.addEventListener('dblclick', dblClickHander, options);
});
toggleButtons.forEach(el => {
el.addEventListener('click', toggleEventHandler, options)
});
.toggle-target {
width: 270px;
height: 30px;
padding-left: 10px;
}
.toggle-target[data-hideme="hidden"] {
display: none;
}
.toggle-target[data-hideme="showme"] {
display: block;
}
.toggle-target[data-hideme="dblclick"] {
display: block;
border: solid 2px green;
padding: 1rem;
opacity: 0.50;
}
.red-block {
background-color: red;
}
.blue-block {
background-color: blue;
}
.green-block {
background-color: green;
}
<button type="button" class="toggle-button" data-target=".red-block">Div 1 - Red</button>
<button type="button" class="toggle-button" data-target=".blue-block">Div 2 - Blue</button>
<button type="button" class="toggle-button" data-target=".green-block">Div 3 - Green</button>
<div class="toggle-target red-block" data-hideme="hidden">red</div>
<div class="toggle-target blue-block" data-hideme="hidden">blue</div>
<div class="toggle-target green-block" data-hideme="hidden">green</div>
This can be done in many ways. I think the best approach in your case could be
BUTTONS
<button type="button" onclick="show_div('Div_1')">Div 1 - Red</button>
<button type="button" onclick="show_div('Div_2')" style="margin-left: 4px">Div 2 - Blue</button>
<button type="button" onclick="show_div('Div_3')" style="margin-left: 4px">Div 3 - Green</button>
SCRIPT
function show_div(div_id) {
var thisDiv = document.querySelector('#'+div_id);
var thisState = thisDiv.style.display;
// close all in any cases
document.querySelectorAll('.div').forEach(function(el) {
el.style.display = "none";
});
// open this div only if it was closed
if (thisState == "none" ){
thisDiv.style.display = "block";
}
}

Show a hidden div while making another hidden

I am looking for a way to toggle through three stacked div's where a button press will trigger an onclick function to make that specific div visible and hiding the others. I have included a jsfiddle below with the code I currently have any help on this would be amazing!
function togglediv(id1, id2, id3) {
var idOne = document.getElementById(id1);
var idTwo = document.getElementById(id2);
var idThree = document.getElementById(id3);
idOne.style.display = idOne.style.display == "block" ? "none" : "block";
idTwo.style.display = idTwo.style.display == "none";
idThree.style.display = idThree.style.display == "none";
}
<div class="table-responsive">
<button type="button" class="btn btn-primary" onclick="togglediv('inner-dung', 'inner-boss', 'inner-item')">
Dungeon
</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-boss', 'inner-dung', 'inner-item')">
Boss
</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-item', 'inner-dung', 'inner-boss')">
Item
</button>
</div>
<div id="search-dung">
<div id="inner-dung">
DUNGEON
</div>
<div id="inner-boss">
BOSS
</div>
<div id="inner-item">
ITEM
</div>
</div>
JSFiddle
You can pass the ID you want to show to the function, use a CSS class to toggle display: none/block, toggle that class on the element you click on and hide the rest by removing the class.
.table-responsive {
margin: 0px auto;
width: 90%;
}
#search-dung {
margin: 0px auto;
width: 90%;
height: 50%;
background-color: white;
border: 1px solid red;
}
#inner-dung,
#inner-item,
#inner-boss {
position: absolute;
margin: 0px auto;
width: 90%;
height: 50%;
background-color: white;
border: 1px solid red;
display: none;
}
#inner-dung.show,
#inner-item.show,
#inner-boss.show {
display: block;
}
<div class="table-responsive">
<button type="button" onclick="togglediv('inner-dung')">
Dungeon
</button>
<button type="button" onclick="togglediv('inner-boss')">
Boss
</button>
<button type="button" onclick="togglediv('inner-item')">
Item
</button>
</div>
<div id="search-dung">
<div id="inner-dung">
DUNGEON
</div>
<div id="inner-boss">
BOSS
</div>
<div id="inner-item">
ITEM
</div>
</div>
<script>
var els = document.getElementById('search-dung').getElementsByTagName('div');
function togglediv(id) {
var el = document.getElementById(id);
for (var i = 0; i < els.length; i++) {
var cur = els[i];
if (cur.id == id) {
cur.classList.toggle('show')
} else {
cur.classList.remove('show');
}
}
}
</script>
function togglediv(id1, id2, id3) {
var idOne = document.getElementById(id1);
var idTwo = document.getElementById(id2);
var idThree = document.getElementById(id3);
idOne.style.display = "block";
idTwo.style.display = "none";
idThree.style.display = "none";
}
https://codepen.io/anon/pen/NjOpJw
a couple of of problems there.
use onClick rather than onclick
idOne.style.display = idOne.style.display == "block" ? "none" : "block"; will return a boolean so you should change it for this
idOne.style.display = "block";
set your javascript to load in the body.
here's a working version
https://jsfiddle.net/83qwrk70/1/
You can use a switch case, passing only the element you want to show in toggle div
//index.html
<button type="button" class="btn btn-primary" onclick="togglediv('inner-dung')">
Dungeon
</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-boss')">
Boss</button>
<button type="button" class="btn btn-primary" onclick="togglediv('inner-item')">
Item </button>
//index.js
function show(el) {
el.style.display = 'block';
}
function hide(el) {
el.style.display = 'none';
}
function togglediv(selected) {
var idOne = document.getElementById('inner-dung');
var idTwo = document.getElementById('inner-boss');
var idThree = document.getElementById('inner-item');
switch(selected) {
case 'inner-dung': {
show(idOne);
hide(idTwo);
hide(idThree);
break;
}
case 'inner-boss': {
hide(idOne);
show(idTwo);
hide(idThree);
break;
}
case 'inner-item': {
hide(idOne);
hide(idTwo);
show(idThree);
break;
}
}
}
Here is another option that is scaleable:
var active = "inner-dung",
inactive = ["inner-boss", "inner-item"];
var toggleDiv = function (id) {
active = inactive.splice(inactive.indexOf(id), 1, active);
document.getElementById(active).style.display = "block"; // or use style sheet
for (var i = 0; i < inactive.length; i++) {
document.getElementById(inactive[i]).style.display = "none"; // or use style sheet
}
}
If there is no default active item, you can put "inner-dung" in the array as well. If you do that, the "inactive" array will receive "undefined" the first time, but it will not get in the way of the purpose.
You don't have to use a for-loop of course, but if you have more items you would.
"Teach your children well"
Apply a rule to the parent to influence the children.
document.querySelector( "form" ).addEventListener( "click", function( evt ) {
var n = evt.target.name;
if ( n ) {
document.querySelector( "#foobarbaz" ).setAttribute( "class", n );
}
}, false );
#foo,
#bar,
#baz {
display: none;
}
#foobarbaz.foo #foo,
#foobarbaz.bar #bar,
#foobarbaz.baz #baz {
display: block;
}
<div id="foobarbaz" class="foo">
<div id="foo">Foo!</div>
<div id="bar">Bar?</div>
<div id="baz">Baz.</div>
</div>
<form>
<input type="button" value="Foo" name="foo">
<input type="button" value="Bar" name="bar">
<input type="button" value="Baz" name="baz">
</form>

javascript expand/collapse text - collapse on default

I'm very inexperienced in javascript but have managed (with the help of google) to put together the following expandable/collapsible link
<script type="text/javascript">
function toggleMe(a) {
var e = document.getElementById(a);
if(!e) return true;
if(e.style.display == "none") {
e.style.display = "block"
}
else {
e.style.display = "none"
}
return true;
}
</script>
<p>
<input onclick="return toggleMe('para1')" style="font-size:18px; color:#008080;" type="text" value="LINK TO EXPAND" />
</p>
<p id="para1">
<strong><em>text text text text</em></strong>
</p>
The only problem with it is that it is expanded by default and I wanted it collapsed by default. Can anyone help with this? Thank you!
Also, if anyone knows how to get +/- signs next to the link that change depending on whether it is expanded or collapsed, that would be great.
<script type="text/javascript">
function toggleMe(a) {
var e = document.getElementById(a);
var toggleIcon = document.getElementById('toggle-icon');
if(!e) return true;
if(e.style.display == "none") {
e.style.display = "block";
toggleIcon.innerHTML = '-';
}
else {
e.style.display = "none";
toggleIcon.innerHTML = '+';
}
return true;
}
</script>
<p>
<input onclick="return toggleMe('para1')" style="font-size:18px; color:#008080;" type="text" value="LINK TO EXPAND" />
<span id="toggle-icon">+</span>
</p>
<p id="para1" style="display: none;">
<strong><em>text text text text</em></strong>
</p>
You can try putting in style statement the display option like below:
<p id="para1" style="display:none"><strong><em>text text text text</em></strong></p>
That can default collapse when you open your html, hope it help you...
Options 1:
Add this to your css to hide it by default:
#para1 {
display: none;
}
Options 2:
Move your script down, and call it initially toggleMe('para1'); so you will hide it first.
<p>
<input onclick="return toggleMe('para1')" style="font-size:18px; color:#008080;" type="text" value="LINK TO EXPAND" />
</p>
<p id="para1">
<strong><em>text text text text</em></strong>
</p>
<script type="text/javascript">
function toggleMe(a) {
var e = document.getElementById(a);
if(!e) return true;
if(e.style.display == "none") {
e.style.display = "block"
}
else {
e.style.display = "none"
}
return true;
}
toggleMe('para1');
</script>
Daniel has the correct answer to your question. This is a bit more than you asked for, but I think you will have a better time if you manipulate classes instead of element styles properties. Just makes it a bit more flexible.
In the example below I wrapped your code in a common element and then changed that element's class to achieve your desired effect. That let me easily add in your plus and minus too.
It's a little raw but you can see where this can take you. Hope it helps.
https://jsfiddle.net/6xoe1b94/
function toggleMe(a) {
var e = document.getElementById('wrapper');
if(! e.classList.contains('active')) {
e.classList.add('active');
}
else {
e.classList.remove('active');
}
}
#para1{
display:none;
}
.active #para1{
display:block;
}
#plus{
display:inline-block;
}
#minus{
display:none;
}
.active #plus{
display:none;
}
.active #minus{
display:inline-block;
}
<div id='wrapper'>
<p>
<input onclick="return toggleMe('para1')" style="font-size:18px; color:#008080;" type="text" value="LINK TO EXPAND" /><span id='plus'>+</span><span id='minus'>-</span>
</p>
<p id="para1">
<strong><em>text text text text</em></strong>
</p>
</div>
I added a solution that removes the javascript and css from your html. I also changed your expand/collapse element to a div instead of input. I've added a span element within the div that changes it's text content (either + or -) based on whether #para1 is displayed or not. Also, in css I added display: none; to #para1 (this initially hides the element), cursor: pointer; (shows it is clickable when the user hovers over it) user-select: none; (stop div from highlighting when user clicks on it).
// store elements
var expandEl = document.getElementById("expand");
var plusMinusEl = document.getElementById("plusMinus");
var para1El = document.getElementById("para1");
// toggle function: pass element as argument
function toggleMe(el) {
// check if element is hidden
if(el.offsetParent === null) {
plusMinusEl.textContent = "-";
el.style.display = "block"
}
else {
plusMinusEl.textContent = "+";
el.style.display = "none"
}
}
// click function for expand div
expandEl.addEventListener("click", function() {toggleMe(para1El)});
#expand {
font-size:18px;
color:#008080;
cursor: pointer;
user-select: none; /* stop div from highlighting */
}
#para1 {
display: none;
}
<div id="expand">
LINK TO EXPAND <span id="plusMinus">+</span>
</div>
<p id="para1"><strong><em>text text text text</em></strong></p>

Hide one div and show another on click

I want to hide a div (switch) and show another div (hiddenonload) when the button is pressed. I've managed to hide the switch div on press but how do I show the hiddenonload div, when the button is pressed?
My code
var button = document.querySelector("button");
var element = document.querySelector(".switch");
button.addEventListener("click", function() {
element.classList.toggle("hide");
});
.switch {
opacity: 1;
}
.switch.hide {
opacity: 0;
}
.hiddenonload {
display: none;
}
<div class="switch">
<button>
<a>Hide me on click</a>
</button>
</div>
<div class ="hiddenonload">
<p>Show me</p>
</div>
Just add another classList.toggle to remove the .hiddenonload class of the element you want to show.
Demo
var button = document.querySelector("button");
var element = document.querySelector(".switch");
var element2 = document.querySelector(".hiddenonload");
button.addEventListener("click", function() {
element.classList.toggle("hide");
element2.classList.toggle("hiddenonload");
});
.switch {
opacity: 1;
}
.switch.hide {
opacity: 0;
}
.hiddenonload {
display: none;
}
<div class="switch">
<button>
<a>Hide me on click</a>
</button>
</div>
<div class ="hiddenonload">
<p>Show me</p>
</div>
Here's a version with a couple of other improvements :
var toggler = document.querySelector(".toggler");
var button = sw.querySelector("button");
var toshow = document.querySelector(".hidden");
button.addEventListener("click", function() {
toggler.classList.toggle("hidden");
toshow.classList.toggle("hidden");
});
.hidden {
display: none;
}
<div class="toggler">
<button>
<a>Hide me on click</a>
</button>
</div>
<div class ="hidden">
<p>Show me</p>
</div>
Try this.
var button = document.querySelector("button");
var element = document.querySelector(".hiddenonload");
button.addEventListener("click", function() {
element.classList.toggle("hiddenonload");
button.style.display = button.style.display == "none" ? "block" : "none";
});
.switch {
opacity: 1;
}
.switch.hide {
opacity: 0;
}
.hiddenonload {
display: none;
}
<div class="switch">
<button>
<a>Hide me on click</a>
</button>
</div>
<div class="hiddenonload">
<p>Show me</p>
</div>

Hidden Object But Still Have a Place Reserved

I'm trying to make two forms that aren't displayed at the same time. The first one stays visible when the page opens, but if the user select, the first one should be hidden and the second one might take it's place. So here is my CSS for this:
#switcher {
float: right;
font-size: 12px;
}
#web_upload {
visibility: hidden;
}
#local_upload {
visibility: visible;
}
Here is the HTML:
<form action="img_upload.php" id="local_upload" method="post" enctype="multipart/form-data">
<center>
<input type="file" name="file" id="file" />
<br />
<input type="image" name="submit" src="graphics/upload.png" />
</center>
</form>
<form action="url_upload.php" id="web_upload" method="post" method="post">
<center>
<input type="text" name="url" id="url" />
<br />
<input type="image" name="submit" src="graphics/upload.png" />
</center>
</form>
And here is my Javascript to do it:
function showHide(id, other)
{
if(document.getElementById(id)) {
if(document.getElementById(id).style.visibility != "hidden") {
document.getElementById(other).style.visibility = "hidden";
document.getElementById(id).style.visibility = "visible";
} else {
document.getElementById(id).style.visibility = "hidden";
document.getElementById(other).style.visibility = "visible";
}
}
}
So, I'm having three problems:
The second form has a reserved place on the page and I don't want this empty place
The second form is displaying on that reserved place instead of taking place over the first one
If the user select one of the options and try to select other after nothing happens
How I can solve this problems?
#Nathan Campos: I'd combine display and visibility like so --
CSS:
#web_upload {
display: none;
visibility: hidden;
}
#local_upload {
display: inline;
visibility: visible;
}
JavaScript:
function showHide(id, other)
{
var id1 = document.getElementById(id);
var id2 = document.getElementById(other);
if (id1.style.display == "none") {
id1.style.display = "inline";
id1.style.visibility = "visible";
id2.style.display = "none";
id2.style.visibility = "hidden";
} else if (id1.style.display == "" || id1.style.display == "inline") {
id1.style.display = "none";
id1.style.visibility = "hidden";
id2.style.display = "inline";
id2.style.visibility = "visible";
}
}
display: none/block; Show the form / Totally hide and clear the space
visibility: hidden; Hide the form, but keep the space preserved
The CSS visibility property is not the right choice here.
The 'visibility' property specifies whether the boxes generated by an element are rendered. Invisible boxes still affect layout (set the 'display' property to 'none' to suppress box generation altogether)
Reference: http://www.w3.org/TR/CSS21/visufx.html#visibility
Consider instead the CSS display property - display:none applied to an element will make it appear as if it is not present at all, it will be invisible and will not affect layout.
#switcher {
float: right;
font-size: 12px;
}
#web_upload {
display:none;
}
#local_upload {
display:block;
}
//
function showHide(id, other)
{
switch (document.getElementById(id).style.display) {
case 'block':
document.getElementById(id).style.display = 'none';
document.getElementById(other).style.display = 'block';
case 'none':
document.getElementById(id).style.display = 'block';
document.getElementById(other).style.display = 'none';
}
}

Categories

Resources