Collapsible not expanding - javascript

I have a button containing a div with contents. When clicking the div, I want the collapsed content to expand. Upon hovering above the div, it changes color and the pointer changes, just as I like. However, upon clicking nothing happens: the collapsed content does not expand. What is wrong with my code?
var coll = document.getElementsByClassName("contents");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var collapse = this.nextElementSibling;
if (collapse.style.display === "block") {
collapse.style.display = "none";
} else {
collapse.style.display = "block";
}
});
}
<div class="results">
<button type="button" class="contents">
<div class="info">
...
</div>
</button>
<div class="collapse">
<p>Text only shown when expanding</p>
</div>
</div>

Okay...It worked when I put the script tag at the end instead of in the head section!

It is better for you to use jQuery as a client-side framework for better performance, cross-browser and fewer lines of code.
You can use $('.collapse').slideToggle() function for your project. Documentation

Related

Toggle re-hides all divs; need parent div to remain visible

Apologies in advance, I'm not terribly familiar with Javascript, but I do understand what this code is doing and why it is causing me this problem. I'm just not sure how to go about solving it AT all.
On my webpage I have an open/close dialogue toggle which is the parent div, the dialogue box is hidden upon the page loading. Within this dialogue box are more hidden divs for the dialogue options. Problem is, when one of the dialogue options is clicked, the script hides the entire dialogue box, preventing any of the dialogue options from being seen, because it can only show one div at a time, regardless of its parent or child status. When a div is clicked, all other divs are re-hidden.
I need the parent div to remain visible until the dialogue box toggle is clicked again. The individual choices DO need to hide/unhide when another choice is clicked.
Not sure if I should include any CSS here, it's just styling the dialogue box and its buttons within.
<div id="dialogue" style="display:none;">
<div class="room">
Room description here. What do you do?
<div class="buttons">
Pet the cat.
<br>
<div id="cat" style="display:none;">aw yeah kitty time</div>
Turn on the radio.
<br>
<div id="radio" style="display:none;">
<br>
audio file and tracklist here
</div>
</div>
</div>
</div>
<span class="toggle">
[Open/close dialogue.]
</span>
<script type="text/javascript">
var divs = ["cat", "radio", "dialogue"];
var visibleDivId = null;
function divVisibility(divId) {
if(visibleDivId === divId) {
visibleDivId = null;
} else {
visibleDivId = divId;
}
hideNonVisibleDivs();
}
function hideNonVisibleDivs() {
var i, divId, div;
for(i = 0; i < divs.length; i++) {
divId = divs[i];
div = document.getElementById(divId);
if(visibleDivId === divId) {
div.style.display = "block";
} else {
div.style.display = "none";
}
}
}
</script>
I probably need a third function here because currently all the toggles are grouped together, hence why they're interacting like this, but I don't have the first clue how to accomplish this. I have been looking and haven't found anything that seems to match my needs.
Made a few corrections to your HTML so the href does not refresh the page on click. Also added in a few attributes (aria-controls) to track which div the button controls. I added comments to the JavaScript. There are plenty of Aria attributes they typically help with accessibility but they are super useful for keeping track of things in HTML and passing information to JavaScript.
//create a function to handle the click that takes in the event as a argument
function handleClick(event) {
//find out which div the button controls
const ariaControls = event.currentTarget.getAttribute("aria-controls"),
//select the controlled div
controlledAria = document.getElementById(ariaControls);
// if the controlled div is cat
if (ariaControls === "cat") {
// hide the radio div
document.getElementById("radio").classList.add("hide");
// if the controlled div is radio
} else if (ariaControls === "radio") {
// hide the car div
document.getElementById("cat").classList.add("hide");
}
//toggle the hide div on the controlled div
controlledAria.classList.toggle("hide");
}
//select all the buttons
const buttons = document.querySelectorAll("button");
//for each button add an event listener when the button is clicked run the handle click function
buttons.forEach(button => button.addEventListener("click", handleClick))
.hide {
display: none;
}
<div id="dialogue" class="hide">
<div class="room">
Room description here. What do you do?
<div class="buttons">
<button aria-controls="cat">Pet the cat.</button><br>
<div id="cat" class="hide">aw yeah kitty time</div>
<button aria-controls="radio">Turn on the radio.</button><br>
<div id="radio" class="hide">audio file and tracklist here
</div>
</div>
</div>
</div>
<span class="toggle"><button aria-controls="dialogue">[Open/close dialogue.]</button></span>

External javascript for collapsible menu not running on website

So basically, I've got some javascript that I (literally) ripped directly from w3.
It's meant to be a clickable menu that opens up and displays check boxes, however, it's not actually opening when I load the webpage. It works perfectly fine within their own editor, and oxygen isn't spitting any errors out at me, so I'm at a bit of a loss.
Below is a snippet of my HTML.
<body>
<h1>Title</h1>
<button type="button" class="collapsible">Content Header</button>
<div class="content">
<label class="container">Content<input type="checkbox" checked="checked" />
<span class="checkmark"></span><br />
</label>
</div>
</body>
and here's the javascript for the collapsible menu (that isn't working)
var coll = document.getElementsByClassName("collapsible");
var i;
for (i = 0; i < coll.length; i++) {
coll[i].addEventListener("click", function() {
this.classList.toggle("active");
var content = this.nextElementSibling;
if (content.style.display === "block") {
content.style.display = "none";
} else {
content.style.display = "block";
}
});
}
Placed the at the bottom of the document within the tags, it started magically working. Thanks #aerial301
I don't see a problem in your javascript code either.
Have you tried to wrap your code in the document.onload(function) event?
Example:
<script>
document.onload(() => {
// your javascript code here.
})
</script>

simplifying a javascript click count menu controlling 3 individual dropdowns

I've got 3 individual slide down menu's at the top of my page.
Page Menu
Account dropdown
Cart Dropdown
I've created individual open and close functions for each one
function menu_open(){
document.getElementById("myNav_overlay").style.height = "100%";
document.getElementById("myNav").style.height = "100%";
$('.menu-link').text("menu_open");
}
function menu_close() {
document.getElementById("myNav_overlay").style.height = "0%";
document.getElementById("myNav").style.height = "0%";
$('.menu-link').text("menu");
}
function account_open(){
document.getElementById("myAccount_overlay").style.height = "100%";
document.getElementById("myAccount").style.height = "100%";
$('.account-link').text("person");
}
function account_close() {
document.getElementById("myAccount_overlay").style.height = "0%";
document.getElementById("myAccount").style.height = "0%";
$('.account-link').text("person");
}
function cart_open(){
document.getElementById("myCart_overlay").style.height = "100%";
document.getElementById("myCart").style.height = "100%";
$('.cart-link').text("shopping_cart");
}
function cart_close() {
document.getElementById("myCart_overlay").style.height = "0%";
document.getElementById("myCart").style.height = "0%";
$('.cart-link').text("shopping_cart");
}
and then 3 individual click count functions to determine if the menu needs to open or close.
$(function() {
var menuclickCount = 0;
var accountclickCount = 0;
var cartclickCount = 0;
$('.menu-link').click(function () {
if(menuclickCount%2==0){
//do when open
menu_open();
account_close();
cart_close();
}else{
//do when closed
menu_close();
}
clickCount++;
});
$('.account-link').click(function () {
if(accountclickCount%2==0){
//do when open
account_open();
menu_close();
cart_close();
}else{
//do when closed
account_close();
}
accountclickCount++;
});
$('.cart-link').click(function () {
if(cartclickCount%2==0){
//do when open
cart_open();
menu_close();
account_close();
}else{
//do when closed
cart_close();
}
cartclickCount++;
});
});
This seems rather large compared to what it has to be and seems like there may be a better/simpler way of doing it. But honestly not sure how this would typically be done.
Is it better to leave a setup like this as is where each one is controlled individually and manually closes the other? OR, is it better to combine these into a more robust, smaller function that still controls them as needed?
If it is better to combine into a simpler function, how would this be done to where it still opens and closes each dropdown section?
I took 1 working function and duplicated it to make this work as is. So now I'm curious to see how this compares to what is considered industry standard and practical.
The HTML is simple....
Menu content
<div id="myNav_overlay" class="overlay_background"></div>
<div id="myNav" class="nav-overlay">
<div class="overlay-content">
MENU
</div>
</div>
Account content
<div id="myAccount_overlay" class="overlay_background"></div>
<div id="myAccount" class="account-overlay">
<div class="overlay-content">
ACCOUNT
</div>
</div>
Cart content
<div id="myCart_overlay" class="overlay_background"></div>
<div id="myCart" class="cart-overlay">
<div class="overlay-content">
CART
</div>
</div>
Without getting into styling the example too much, using the wonder of jQuery, you can do this:
(1) On click, select all menu containers (class .ddown in my example)
(2) return all menu containers to their default height of zero (by removing the .showMenu class with its new height)
(3) for the clicked container only, apply a style that increases container height.
$('.ddown').click(function(){
$('.ddown').removeClass('showMenu');
$(this).addClass('showMenu');
});
.container{height:100px;}
.ddown{display:inline-block;width:100px;border:1px solid #ccc;overflow:hidden;}
.mnuTitle{height:20px;}
.mnuContent{height:0;background:white;}
.showMenu{height:100px;background:palegreen;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<div class="container">
<div id="myNav" class="ddown">
<div class="mnuTitle">Menu</div>
<div class="mnuContent">
MENU CONTENT
</div>
</div>
<div id="myAccount" class="ddown">
<div class="mnuTitle">Account</div>
<div class="mnuContent">
ACCOUNT CONTENT
</div>
</div>
<div id="myCart" class="ddown">
<div class="mnuTitle">Cart</div>
<div class="mnuContent">
CART CONTENT
</div>
</div>
</div><!-- .container -->

Javascript show/hide, show first div on page load

Can you help me to make the first div show on page load?
function showStuff(element) {
var tabContents = document.getElementsByClassName('tabContent');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].style.display = 'none';
}
var tabContentIdToShow = element.id.replace(/(\d)/g, '-$1');
document.getElementById(tabContentIdToShow).style.display = 'block';
}
.tabContent {
display:none;
}
<div tabindex="1" class="tabs"><div id="tabs1" onclick="showStuff(this)">CARATTERISTICHE</div><div class="triangle-down-tab"></div></div>
<div id="tabs2" onclick="showStuff(this)">DESTINATARI</div><div class="triangle-down-tab"></div></div>
<div tabindex="3" class="tabs"><div id="tabs3" onclick="showStuff(this)"><i class="fa fa-calendar" style="color:#000000;"></i> CALENDARIO</div><div class="triangle-down-tab"></div></div>
<a name="contenuto"><hr></a>
<div id="tabs-1" class="tabContent">
<p>tab 1</p>
</div>
<div id="tabs-2" class="tabContent">
<p>tab 2 tab 2 </p>
</div>
<div id="tabs-3" class="tabContent">
<p>tab 3 tab 3 tab 3</p>
</div>
This is my actual code. jsFiddle
Thanks!
You could try running a function when the document is ready.
$(document).ready(function () {
showTab("tabs-1");
function showTab(divId) {
//Get the element
var divElement= document.getElementbyId(divId);
//Set the css property "display" from "none" to be "block";
divElement..style.display = "block";
}
}):
The function should run once the page has fully loaded.
Let me know how it goes.
I sure can. When you do this kind of stuff best use css. That way when the dom loads the css will kick in and your desired effect will show.
Further more its easier to understand and easier to code up.
.tabContent {
display:none;
}
.tabContent.active {
display:block;
}
Then in the HTML
<div id="tabs-1" class="tabContent active">
So when the page loads tab one is active
Then in your JS
function showStuff(element) {
var tabContents = document.getElementsByClassName('tabContent');
for (var i = 0; i < tabContents.length; i++) {
tabContents[i].className="tabContent";
}
var tabContentIdToShow = element.id.replace(/(\d)/g, '-$1');
document.getElementById(tabContentIdToShow).className="tabContent active";
}
Updated fiddle!
https://jsfiddle.net/rb5c5095/3/
We could improve things since we know all the tabs will be made invisible at boot up and tab 1 will show. So when a tab is clicked we could just search the tab who has .active class and remove it, then apply the .active class to the new tab. This would have the benefit that any extra css you add in your html markup would not be removed by the JS code, but i reckon you can work that out and if you can't get back to me i can show you :-)
Here I am invoking the function (upon page load) that tweaks the css of the desired block;
Same can be achieved by $(document).ready;
I took this approach to avoid jquery;
window.onload = showDivOne();
function showDivOne() {
document.getElementById("tabs-1").style.display = "block";
}

How to get a specific jquery toggle show / hide div to load visible?

I am using jQuery to hide / show sections of content on a page. On one page, I have two such sections. Right now the page loads with both hidden. I need the page to load with the first div visible and the second one hidden.
Here is my javascript:
function a2012() {
var ele = document.getElementById("toggleArch12");
var text = document.getElementById("displayArch12");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "2012 Newsletter Archive";
}
else {
ele.style.display = "block";
text.innerHTML = "Hide Archive";
}
}
function a2011() {
var ele = document.getElementById("toggleArch11");
var text = document.getElementById("displayArch11");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "2011 Newsletter Archive";
}
else {
ele.style.display = "block";
text.innerHTML = "Hide Archive";
}
}
and the HTML to set up the DIVs and their toggle links:
<a id="displayArch12" href="javascript:a2012();">2012 Newsletter Archive</a>
<div id="toggleArch12" style="display:none">content goes here</div>
<a id="displayArch11" href="javascript:a2011();">2011 Newsletter Archive</a>
<div id="toggleArch11" style="display:none">content goes here</div>
I tried changing style="display:none" for the first div to style="display:visible" and while it does cause the page to load with the contents visible, the toggle link still shows the "click to open" text (in this case "2012 Newsletter Archive").
I need the first div to load visible and the correct toggle text (Hide Archive) to show as well. Any ideas?
If you want to use jQuery (which you are not from the code you've posted), you could write it like this:
$("#displayArch11").click(function(e) {
var $display = $(this)
$display.next().toggle(function() {
$display.html($display.html() == "2011 Newsletter Archive" ? "Hide Archive" : "2011 Newsletter Archive");
});
e.preventDefault();
});
$("#displayArch12").click(function(e) {
var $display = $(this)
$display.next().toggle(function() {
$display.html($display.html() == "2012 Newsletter Archive" ? "Hide Archive" : "2012 Newsletter Archive");
});
e.preventDefault();
});
and the HTML like this
<a id="displayArch12" href="#">2012 Newsletter Archive</a>
<div id="toggleArch12" style="display:none">content goes here</div>
<a id="displayArch11" href="#">2011 Newsletter Archive</a>
<div id="toggleArch11" style="display:none">content goes here</div>
This is easier if you use jQuery, but I think simply setting the correct default html should achieve your goal.
<a id="displayArch12" href="javascript:a2012();">Hide Archive</a>
<div id="toggleArch12" style="display:block">content goes here</div>
Change the inline script:
<div id="toggleArch12" style="display:block">content goes here</div>
First, if you want one of the divs to be visible, just don't specify the display property. They are visible by default. Though the value you are looking for with a div is display:block;
I would use a div instead of a link for your toggling needs.
<div id="displayArch12" class="toggleDiv">
2012 Newsletter Archive
<div id="toggleArch12" style="display:block;">Content Here</div>
</div>
<div id="displayArch11" class="toggleDiv">
2011 Newsletter Archive
<div id="toggleArch11" style="display:none;">Content Here</div>
</div>
Then you need some real jQuery to toggle them properly.
$(function() {
$(".toggleDiv").click(function () {
$("div:first-child", this).toggle();
});
});
That should work for you. And of course don't forget to include the jQuery library itself. The easiest way is to use the Google API link.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>

Categories