javascript function loses ability to toggle - javascript

Using this script to open 1 of multiple menus based on the target ID. The class is .dropdownDiv. The script starts by removing the "show" class from any .dropdownDiv's, then allowing the user to toggle the targeted .dropdownDiv.
The issue is, the .remove and .toggle don't appear to work together. They work individually just fine. I can toggle one div show-unshow all day long, but clicking the other buttons will not control it. I can do the reverse and have one button remove the div from another, but then the targeting button will not remove it's own div.
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function(event) {
var divs = document.querySelectorAll('.navButton');
for (var i = 0; i < divs.length; i++) {
divs[i].addEventListener('click', showDropDown);
}
});
function showDropDown() {
//un-show all dropdowns
var containers = document.querySelectorAll('.dropdownDiv');
for (var i = 0; i < containers.length; i++) {
containers[i].classList.remove('show');
}
// show targeted dropdown only
var d = document.getElementById(event.target.dataset.target);
d.classList.toggle("show");
console.log(d);
}
</script>

a trivial way to toggle something, that is using a flag and flip it each time you hit an action, so you can do something like so:
if(a)
{//something to do}
else
{// another action to do}
a = ! a;
so, you can remove the clicked drop down instead of removing all drop down classes.

Related

How to remove CSS classes from the classList of each div element, and assign a desired CSS class to a div element, in an array of div elements?

I have a set of HTML buttons programmed with JavaScript. There's a class assigned to an array of HTML div elements, and the buttons are supposed to change that class.
Here's the code for one of the buttons:
a4.addEventListener('click', function()
{
//makes sure all the other buttons aren't chosen
var button = document.getElementsByClassName('unchosen');
for (var i = 0; i < button.length; i++)
{
button[i].classList.remove('chosen');
}
a4.classList.add('chosen');
//is supposed to assign the new css class to every plate div element and get rid of the undesired classes
const plates = document.querySelectorAll(".assay1Plate", ".assay2Plate", ".assay3Plate", ".assay4Plate");
for (var i = 0; i < 35; i++)
{
if (plates[i].classList.contains == "assay1Plate")
{
plates[i].classList.remove("assay1Plate");
console.log("Removed assay 1 plate class due to assay 4 click");
}
if (plates[i].classList.contains == "assay2Plate")
{
plates[i].classList.remove("assay2Plate");
}
if (plates[i].classList.contains == "assay3Plate")
{
plates[i].classList.remove("assay3Plate");
}
plates[i].classList.add("assay4Plate");
//I was going to use this to remove undesired classes from the div elements... but it doesn't really work
/*
for(var k = 0; k < classes.length; k++)
{
if (plates[i].classList.contains(classes[k]) && classes[k] != "assay4Plate")
{
plates[i].classList.remove(classes[k]);
console.log("Classes removed save 4");
}
}
*/
}
});
Console.log shows that classes are being ADDED to the classList of the elements, but it doesn't seem like they can be removed once they've already been added. Clicking the first button changes their classes, clicking the second changes it again, clicking the third changes it again, and so on.... but then clicking the first or second buttons again does nothing.

javascript collapsible table without jquery

This is a simple question I can't seem to figure out and every google search returns a million ways to do this via jquery, but I'd prefer to use vanilla javascript because I am new to it and want to learn it well before using any libraries. What I am trying to do is have a button collapse part of a table when clicked and then show those hidden parts again when clicked again. Basically just toggling the display of a class of elements.
I have a button that calls the test() function
when clicked nothing on my table changes. Here is my javascript code. I am using collapse[0] because if I understand it correctly collapse is a nodeList and I always close and open all of these together so I only need to check the first element.
function test() {
var collapse = document.getElementsByClassName("catOne");
var i = 0;//Counter for loops
if(collapse[0].style.display === "table-row"){
for(i = 0; i < collapse.length; i += 1){
collapse[i].style.display = "none";
}
}
if(collapse[0].style.display === "none"){
for(i = 0; i < collapse.length; i += 1){
collapse[i].style.display = "table-row";
}
}
}
I've tested the function with this code:
function test() {
var collapse = document.getElementsByClassName("catOne");
var i = 0;//Counter for loops
for (i = 0; i < collapse.length; i += 1) {
collapse[i].style.display = "none";
}
which works fine on collapsing the elements so evidentally the issue is with my if statement, but my IDE, Netbeans, doesn't throw any errors and as far as I can tell it should be working.
Thanks for the help.
Link to html and javascript: https://jsfiddle.net/ozjbekjy/
I suspect there are a few problems working against you.
First, you need to make sure the test() function is defined earlier in the page than it's being used. With jQuery, that means using the $(function(){}) wrapper to apply event handlers on DOM ready. You can approximate the same thing yourself with something like this answer.
Otherwise, simply place the <script> tag somewhere before the table (probably in the <head>), and the onclick will work.
You also are using i += 1 where you could be using i++ - they accomplish the same behavior.
Secondly, instead of manipulating the style attribute, use the classList.toggle() function to simply add and remove a class that has the rule display: none, like so:
CSS
.hide-me {
display: none;
}
JavaScript
function test() {
var collapse = document.getElementsByClassName("catOne");
for (var i = 0; i < collapse.length; i++) {
collapse[i].classList.toggle("hide-me");
}
}
Your JSFiddle, with the suggested updates: https://jsfiddle.net/ozjbekjy/4/

no triggering on click event

This is a simple but intersting issue. Suppose I have two sections of respective class .toggle0 and .toggle1, suppose I want to display .toggle0 and hide .toggle1 when clicking on some tag .footer0, and vice-versa : I want to display .toggle1 and hide .toggle0 when clicking on some tag .footer1. Now this code works correctly
$('.toggle1').hide();
var i=0;
$(".footer"+i+"").click(function(){
$(".toggle"+(i+1) %2+"").hide();
$(".toggle"+i+"").show();
});
var j=1;
$(".footer"+j+"").click(function(){
$(".toggle"+(j+1) %2+"").hide();
$(".toggle"+j+"").show();
});
but this doesn't work in the sense that nothing happens on click event
for(var i=0;i<2;i++){
$(".footer"+i+"").click(function(){
$(".toggle"+(i+1) %2+"").hide();
$(".toggle"+i+"").show();
});
}
if I put this
$('.toggle1').hide();
var i=0;
$(".footer"+i+"").click(function(){
$(".toggle"+(i+1) %2+"").hide();
$(".toggle"+i+"").show();
});
i =1;
$(".footer"+i+"").click(function(){
$(".toggle"+(i+1) %2+"").hide();
$(".toggle"+i+"").show();
});
.toggle1 displays and .toggle0 hides when clicking on some tag .footer1 but .toggle0 does not display and .toggle1 does not hide when clicking on some tag .footer0 . It seems that the second click event takes precedence upon the first
The i within the the click handler isn't evaluated until a click, at which point the value has changed from when the handler was bound. If you want to go this route, you need to create a closure. Here's one method to do so:
for (var i = 0; i < 2; i++) {
$(".footer" + i + "").click(function () {
var idx = i;
return function () {
$(".toggle"+(idx+1) %2+"").hide();
$(".toggle"+idx+"").show();
console.log(idx);
}
}());
}
$('.footer0').click(function(){
$('.toggle0 .toggle1').hide();
$('.toggle0').show();
});
$('.footer1').click(function(){
$('.toggle0 .toggle1').hide();
$('.toggle1').show();
});

JavaScript - Toggle function

Im trying to hide/show a JS function I have defined in a chrome extension.
What I have so far:
The span classes I am trying to hide are label:
dspan.className = "cExtension";
//Create toggle button:
function createToggleButton(){
var toggleButton = document.createElement("button");
toggleButton.innerHTML = "Toggle Overlay";
toggleButton.id = "Toggle"
var header = document.getElementById("header");
header.appendChild(toggleButton);
toggleExtension();
}
// find all spans and toggle display:
function toggleExtension(){
var spans = document.getElementsByTagName('span');
var toggle = function() {
for (var i = 0, l = spans.length; i < l; i++) {
if (spans[i].getAttribute('class') == 'cExtension')
if (spans[i].style.display == 'none') spans[i].style.display = '';
else spans[i].style.display = 'none';
}
}
document.getElementById('Toggle').onclick = toggle;
}
The button shows on the header, however it is unclickable. If I change document.getElementById('Toggle').onclick = toggle; to document.getElementById('Toggle').onclick = alert{"Hello"); the alert is triggered on page load on not onclick. I am trying to get this done in pure JS. Where am I going wrong?
First of all, document.getElementById("Toggle").onclick = alert("Hello"); will set the onclick event to whatever the alert function returns, not the alert function itself. So the alert function happens at page load so it can figure out what to return. So you could do this: document.getElementById("Toggle").onclick = function(){alert("Hello");}; and that might work.
Edit: Scratch everything that was here: I missed that toggle variable set to a function in toggleExtension.
I haven't tested all this so I can't guarantee that it'll all work in your specific case.
if visible is set remove it, otherwise add it
div.classList.toggle("visible");
add/remove visible, depending on test conditional, i less than 10
div.classList.toggle("visible", i < 10 );
Make sure browser support: http://caniuse.com/#feat=classlist
Why not use jQuery?
It will do all hard job for you.
http://api.jquery.com/toggle/
Cheers!

how do i use slidetoggle and allow only one div open at a time?

Code: http://codepen.io/anon/pen/sumIx
$('.module article').hide();
});
$('.module-content, .module-photo').click(function() {
for (var i = 0; i < 5; i++) {
$('.module article').slideUp();
} $(this).parent().children('article').slideToggle('slow');
});
If you click on any of the boxes, the previously active div closes as expected.
When you try to close the same div which is active, it opens right back up. How do I keep everything else the same but correct the behavior so that it doesn't reopen?
Try this:
$('.module-content').click(function() {
var $this = $(this).closest('section').find('article');
$('.module article').not($this).slideUp();
$this.slideToggle('slow');
});
http://codepen.io/anon/pen/DBirp
jQuery iterates element collections naturally so your loops are irrelevant in this case. Here's the commented updated code:
$('.module-content').click(function() {
//stores a reference to the clicked section's article
var article = $(this).parent().children('article');
//hides all other articles
$('.module article').not(article).slideUp();
//toggles the clicked one
article.slideToggle('slow');
});
http://codepen.io/anon/pen/dgJDr

Categories