Is it possible to toggle different divs by clicking on different elements using the same function? - javascript

Say I have 50 div, like this:
<div class="btn1"></div> //Toggles the first container to appear
<div class="btn2"></div> //Toggles the second container to appear
<div class="btn3"></div> //Toggles the third container to appear
And another 50 div that contain information, like this:
<div class="container-1"><h1>This is the first container</h1></div>
<div class="container-2"><h1>This is the second container</h1></div>
<div class="container-3"><h1>This is the third container</h1></div>
Is it possible to make the corresponding div toggle when each button is clicked with just one function? I have read a little about delegation and operating on parents/siblings but it only seems to work on multiple buttons opening the same container, rather than each button opening each container.
Somehow I don't think writing a function for every div is the way to go.

yes it is possible. Basically you need to add a reference to clicked object so click event will know what to show/hide
$(function() {
$('.btn').on('click', function(e) {
var $dataTarget = $($(this).data('target'));
$dataTarget.show().siblings('.container').hide();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn btn1" data-target=".container-1"></div> //Toggles the first container to appear
<div class="btn btn2" data-target=".container-2"></div> //Toggles the second container to appear
<div class="btn btn3" data-target=".container-3"></div> //Toggles the third container to appear
<div class="container container-1">
<h1>This is the first container</h1>
</div>
<div class="container container-2">
<h1>This is the second container</h1>
</div>
<div class="container container-3">
<h1>This is the third container</h1>
</div>
This will show the container targeted, then will hide other containers.

Use starts with selector ^ Document here
Use data-* to store corresponding div on button.
Select the data-* then use as selector to show
$('div[class^=container]').hide();
$('div[class^=btn]').click(function() {
$('div[class^=container]').hide();
var thisclass = $(this).attr("data-class")
$('.' + thisclass).show();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn1" data-class="container-1">1</div>
<div class="btn2" data-class="container-2">2</div>
<div class="btn3" data-class="container-3">3</div>
<div class="container-1">
<h1>This is the first container</h1>
</div>
<div class="container-2">
<h1>This is the second container</h1>
</div>
<div class="container-3">
<h1>This is the third container</h1>
</div>

You can use index and eq to do this
$("[class*='btn']").click(function(){
$("[class*='container-']").eq($(this).index()-1).toggle();
})
[class*="btn"]{
width:150px;
height:20px;
border:2px solid #000;
display:inline-block;
cursor:pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<div class="btn1"></div>
<div class="btn2"></div>
<div class="btn3"></div>
<div class="container-1">
<h1>This is the first container</h1>
</div>
<div class="container-2">
<h1>This is the second container</h1>
</div>
<div class="container-3">
<h1>This is the third container</h1>
</div>

you can use something like this
$(document).ready(function() {
$("div[class^='btn']").each(function() {
$(this).click(function() {
var str = $(this)[0].className;
$(".container-" + str.substring(3, str.length)).toggle();
});
});
});
Find all the class which starts with btn and apply a click event to it..
and based on the number hide the corresponding container class.
Here is the full code:
$(document).ready(function() {
$("div[class^='btn']").each(function() {
$(this).click(function() {
var str = $(this)[0].className;
$(".container-" + str.substring(3, str.length)).toggle();
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="btn1">aaaa</div> //Toggles the first container to appear
<div class="btn2">bbbb</div> //Toggles the second container to appear
<div class="btn3">cccc</div> //Toggles the third container to appear
<div class="container-1">
<h1>This is the first container</h1>
</div>
<div class="container-2">
<h1>This is the second container</h1>
</div>
<div class="container-3">
<h1>This is the third container</h1>
</div>
(Source: fiddle https://jsfiddle.net/fxabnk4o/17/)

Related

How to get number of div left after deleting?

In my HTML there are eight div. I was able to get the number of the div using jQuery and insert it into the .num div element.
However when I delete one of the div by clicking the delete button, the number of divs in the span retrieved through jQuery won't update to the current number of divs remaining. It will still show 8.
How can I get the current number of div elements left in the DOM immediately after clicking the button?
setTimeout(() => {
if ($(".delete div").length > 0) {
$(".num span").html($(".delete div").length);
}
}, 100);
$("button").click(function() {
$(".delete div:last-child").remove();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
```
<div class="delete">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
<div class="div5">5</div>
<div class="div6">6</div>
<div class="div7">7</div>
<div class="div8">8</div>
</div>
<div class="num">Number of div: <span>0</span></div><br>
<button>delete</button>
The problem is because you're using setTimeout(), which only runs once after the specified delay.
For the pattern you're using to work you need to use setInterval() instead, which will run repeatedly at the set delay:
setInterval(() => {
if ($(".delete div").length > 0) {
$(".num span").html($(".delete div").length);
}
}, 100);
$("button").click(function() {
$(".delete div:last-child").remove();
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="delete">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
<div class="div5">5</div>
<div class="div6">6</div>
<div class="div7">7</div>
<div class="div8">8</div>
</div>
<div class="num">Number of div: <span>0</span></div><br>
<button>delete</button>
However, using a timer for this is not ideal. As the number of div elements is only affected when the button is clicked, just update the .num span element in that event handler:
var $span = $(".num span").html($(".delete div").length);
$("button").click(function() {
$(".delete div:last-child").remove();
$span.html($(".delete div").length);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="delete">
<div class="div1">1</div>
<div class="div2">2</div>
<div class="div3">3</div>
<div class="div4">4</div>
<div class="div5">5</div>
<div class="div6">6</div>
<div class="div7">7</div>
<div class="div8">8</div>
</div>
<div class="num">Number of div: <span>0</span></div><br>
<button>delete</button>

why does my jquery function fadeOut work but slice doesn't work?

I need to make a button that views three consequent posts
when I click "view all" the three "div"s should show up
I need to make the three 'div's show up if I click the view all button
so I am using jquery here
$('.posts .repeat-grid').slice(0, 3).show();
$('#view-all').on('click', function() {
$('.posts .repeat-grid:hidden').slice(0, 1).slideDown();
if ($('.posts .repeat-grid:hidden').length === 0) {
$('#view-all').fadeOut();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="posts">
<div class="repeat-grid">1</div>
<div class="repeat-grid">2</div>
<div class="repeat-grid">3</div>
</div>
<div id="view-all">View All</div>
any idea why it is not working?
You Can Try this if that's what you mean
$('#view-all').on('click', function() {
$('.posts').slideToggle();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="posts">
<div class="repeat-grid">1</div>
<div class="repeat-grid">2</div>
<div class="repeat-grid">3</div>
</div>
<div id="view-all">View All</div>

How to rearrange divs for single page application

I'm building a single-page web app. In this one file, I want a specific div to be shown on startup. Perhaps the user will then press a button, and a new div will replace it.
Right now, I'm using js to hide one div and show another in this case. The problem is, the new div appears further down the page (as it is written in the html file after the first div).
How can I, using javascript, simply replace one div with another as the user navigates back and forth between the divs? Is this possible and recommended?
/* JS
When #firstButton is pressed, replace div #first with div #second
When #secondButton is pressed, replace the div #second with div #first
*/
#second {
visibility: hidden;
}
<div id="first">
<h1>First Page</h1>
<button id="firstButton">Go to second page</button>
</div>
<div id="second">
<h1>Second Page</h1>
<button id="secondButton">Go to first page</button>
</div>
Using visibility: hidden is causing your elements to still take up space, which is why your "pages" don't appear to change places.
Switch to display: none, which can be easily toggled with jQuery's .show() and .hide() like so:
$("#firstButton").on("click", function() {
$("#first").hide();
$("#second").show();
});
$("#secondButton").on("click", function() {
$("#first").show();
$("#second").hide();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="first">
<h1>First Page</h1>
<button id="firstButton">Go to second page</button>
</div>
<div id="second" style="display: none;">
<h1>Second Page</h1>
<button id="secondButton">Go to first page</button>
</div>
If you don't want to use jQuery:
document.getElementById("firstButton").addEventListener("click", () => {
document.getElementById("first").style.display="none";
document.getElementById("second").style.display="block";
}, false);
document.getElementById("secondButton").addEventListener("click", () => {
document.getElementById("first").style.display="block";
document.getElementById("second").style.display="none";
}, false);
<div id="first">
<h1>First Page</h1>
<button id="firstButton">Go to second page</button>
</div>
<div id="second" style="display:none">
<h1>Second Page</h1>
<button id="secondButton">Go to first page</button>
</div>

How do I hide a section when I show a different section?

Basically I want one section to be shown at first as the home page. When I click on a link, I want that section to be shown, but everything else hidden, and so on. Every time I click a link, I only want the clicked on link's section to be shown.
I am close, but stuck. Here is my HTML:
About Me
Contact
<div class="container-fluid">
<div class="container about showing">
<h2>About Me</h2>
</div>
</div>
<div class="container-fluid">
<div class="container about showing">
<h2>Contact</h2>
</div>
</div>
And here is my script:
$(document).ready(function() {
$('.about').hide();
$('.contact').hide();
$('.showing').show();
$('#contact').on('click', function(e) {
e.preventDefault();
$('div').removeClass('showing');
$('.contact').addClass('showing');
if ($('div').hasClass('showing')) {
$('div').show();
} else {
$('div').hide();
}
});
});
So it shows the 'About Me' section right away and everything else is hidden. When I click the 'Contact' link it removes the 'showing' class from all my 'div's and adds the 'showing' class to my contact section. I then check to see if the 'div' has the 'showing' class, if it does I have it show the 'div' otherwise I want it to hide it.
However, when I click on the Contact link, it does show the Contact section, but it does not hide the About Me section. I know this is a long post, I am just trying to make sure I explain everything correctly. Any help is greatly appreciated!
I would strongly suggest you use data fields and common classes to make it generic.
var $pages = $('.container');
$('.menu').on('click', function(e){
//remove showing from all containers
$pages.removeClass('showing');
//put it on the container with the matching class of the data target
$pages.filter('.'+ $(e.target).data('target')).addClass('showing');
});
.container {
display: none;
}
.container.showing {
display: unset;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
About Me
Contact
Other
<div class="container-fluid">
<div class="container home showing">
<h2>Home</h2>
</div>
</div>
<div class="container-fluid">
<div class="container about">
<h2>About Me</h2>
</div>
</div>
<div class="container-fluid">
<div class="container contact">
<h2>Contact</h2>
</div>
</div>
<div class="container-fluid">
<div class="container other">
<h2>Other</h2>
</div>
</div>
Here's a few things you can optimize:
$(document).ready(function() {
$('.about, .contact').hide(); //put both of them in single selector
$('.showing').show(); //this shows the only element that has "showing
$('#contact, #about').on('click', function(e) {
e.preventDefault();
var self = $(this); //reference to the object being clicked
var target = $("." + self.attr('id'));
//removes "showing" class from all others and hides them
$(".container").not(target).removeClass("showing").hide();
//adds "showing" class to the new current item
target.addClass("showing").show();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
About Me
Contact
<div class="container-fluid">
<div class="container about showing">
<h2>About Me</h2>
</div>
</div>
<div class="container-fluid">
<div class="container contact"> <!--you don't want that "showing" class here!-->
<h2>Contact</h2>
</div>
</div>

Javascript click specific to ID

I have a div setup like so:
<div class="content">
<button class="show-comments" id="content1"></button>
</div>
<div class="comments-wrapper" id="comment1"></div>
<div class="content">
<button class="show-comments" id="content2"></button>
</div>
<div class="comments-wrapper" id="comment2"></div>
I have the following code:
$('.show-comments').click(function(e){
e.preventDefault();
$('.comments-wrapper').slideToggle('slow');
});
As you would assume, the code works but on a class basis. I'd like for it to open up only the .comments-wrapper of its associated id (i.e. open slideToggle comments2 if content 2 button is clicked and so on and so on).
How would I do this?
$('.show-comments').click(function(e){
e.preventDefault();
$(this).closest(".content").next('.comments-wrapper').slideToggle('slow');
});
Note that this is dependent on the .content element being immediately followed by the .comments-wrapper.
If you have access to modify the html itself, I would suggest adding a wrapper element and then doing the following to avoid the reliance on the exact order of elements:
<div class="wrapper">
<div class="content">
<button class="show-comments" id="content1"></button>
</div>
<div class="comments-wrapper" id="comment1"></div>
</div>
<div class="wrapper">
<div class="content">
<button class="show-comments" id="content2"></button>
</div>
<div class="comments-wrapper" id="comment2"></div>
</div>
$(this).closest(".wrapper").find('.comments-wrapper').slideToggle('slow');
This way, if you add an element between the .content and the .comments-wrapper it does not break the code.
You can do this:
$(this).parent("div").next('.comments-wrapper').slideToggle('slow');
This will find the related div of class .comments-wrapper and slide toggle.
And a fiddle: http://jsfiddle.net/xCJQB/
$('.show-comments').click(function (e) {
e.preventDefault();
var num = this.id.match(/\d+$/)[0];
$("#comment" + num).slideToggle('slow');
});
Demo ---> http://jsfiddle.net/7pkyk/1/
Use this context
$(this).closest('.comments').next('.comments-wrapper').slideToggle('slow');
If it is not the immediate element then you might try this as well
$(this).closest('.comments')
.nextAll('.comments-wrapper').first().slideToggle('slow');
you can add a common class to associate a button with a div.
html:
<div class="content">
<button class="show-comments group1" id="content1"></button>
</div>
<div class="comments-wrapper group1" id="comment1">1</div>
<div class="content">
<button class="show-comments group2" id="content2"></button>
</div>
<div class="comments-wrapper group2" id="comment2">2</div>
javascript:
$('.show-comments').click(function(e){
var associate = $(this).attr('class').match(/group\d+/).pop();
var selector = '.comments-wrapper.' + associate;
e.preventDefault();
$(selector).slideToggle('slow');
});
http://jsfiddle.net/uMNfJ/

Categories

Resources