I'm trying to implement simple hide/show functionality using jQuery. I have two groups of boxes: A and B. I want to be able to click one button to see just the boxes from group A, and a different button to show just group B. This should not depend on what's happened on the page previously, or the order of button presses.
Based on the official basic code sample for the jQuery UI hide() function, I'm using a strategy where a button click has two effects: first, hide all the boxes from both groups, and second, reveal the boxes from the group I want to see. There's also a button to show all boxes, which basically functions as a reset.
Sometimes this works, sometimes it doesn't (MVCE snippet below). When I start from a fresh page load or a reset, I can click the button to show group A, and it's fine. When I click on the button to show group B, though, the group A buttons stay on the screen. Or, from a fresh page/reset, I can click on the group B button and see just boxes from group B, then the group A button and see just boxes from group A, but then I can't get back to just group B.
A bit of investigation with the console and additional groups has revealed that this has something to do with DOM order. I can always select any given group that I want, to start with, but things get messed up if I then try to show a group that appears earlier in the DOM.
What's causing the current behavior, and how can I fix it?
$(function() {
$("#toggleAll").on("click", function() {
$('.box').removeAttr("style").hide().fadeIn();
});
$("#toggleA").on("click", function() {
$('.box').hide('clip', {}, 1000);
$('.groupA').removeAttr("style").hide().fadeIn();
});
$("#toggleB").on("click", function() {
$('.box').hide('clip', {}, 1000);
$('.groupB').removeAttr("style").hide().fadeIn();
});
});
.box {
border: 1px solid black;
}
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" integrity="sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=" crossorigin="anonymous"></script>
</head>
<body>
<p>Show boxes of type:</p>
<button id="toggleAll">Show all</button>
<button id="toggleA">Show group A</button>
<button id="toggleB">Show group B</button>
<hr />
<div id="a1" class="box groupA">
<h4>Title</h4>
<p>Text for box A1</p>
</div>
<div id="a2" class="box groupA">
<h4>Title</h4>
<p>Text for box A2</p>
</div>
<div id="b1" class="box groupB">
<h4>Title</h4>
<p>Text for box B1</p>
</div>
<div id="b2" class="box groupB">
<h4>Title</h4>
<p>Text for box B2</p>
</div>
</body>
</html>
Just try it without all your additional options and use the simple hide() and show(), or in your case the fadeIn()
$(function() {
$("#toggleAll").on("click", function() {
$('.box').fadeIn();
});
$("#toggleA").on("click", function() {
$('.box').hide();
$('.groupA').fadeIn();
});
$("#toggleB").on("click", function() {
$('.box').hide();
$('.groupB').fadeIn();
});
});
.box {
border: 1px solid black;
}
<html>
<head>
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js" integrity="sha256-T0Vest3yCU7pafRw9r+settMBX6JkKN06dqBnpQ8d30=" crossorigin="anonymous"></script>
</head>
<body>
<p>Show boxes of type:</p>
<button id="toggleAll">Show all</button>
<button id="toggleA">Show group A</button>
<button id="toggleB">Show group B</button>
<hr />
<div id="a1" class="box groupA">
<h4>Title</h4>
<p>Text for box A1</p>
</div>
<div id="a2" class="box groupA">
<h4>Title</h4>
<p>Text for box A2</p>
</div>
<div id="b1" class="box groupB">
<h4>Title</h4>
<p>Text for box B1</p>
</div>
<div id="b2" class="box groupB">
<h4>Title</h4>
<p>Text for box B2</p>
</div>
</body>
</html>
Related
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>
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>
I want to write a code that expands and collapses a div with a paragraph, once you click the header text above it.
<div class="container">
<h3><span class="toggler">Text that toggles</span></h3>
<div class="wrapper">
<p>Random text</p>
</div>
</div>
<div class="container">
<h3><span class="toggler2">Text that toggles</span></h3>
<div class="wrapper2">
<p>Random text</p>
</div>
</div>
I am aware that I could write a function like this which would toggle between display: block and display: none.
I could just repeat the same function for different divs with different classes and it would work, but if I have a lot of them I would end up repeating the same function multiple times and I feel like there has to be a much cleaner way to do this.
$(document).ready(function() {
$(".toggler").on("click", function() {
$(".wrapper").toggleClass("active");
});
});
You don't need write single line of code if you use jquery & bootstrap.
Solution 1:
Add reference bnelow:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js"></script>
your html:
<div class="container">
<h3><span class="toggler" data-toggle="collapse" data-target="#col1">Text that toggles</span></h3>
<div class="wrapper" id="col1">
<p>Random text</p>
</div>
</div>
<div class="container">
<h3><span class="toggler2" data-toggle="collapse" data-target="#col2">Text that toggles</span></h3>
<div class="wrapper2" id="col2">
<p>Random text</p>
</div>
</div>
Solution 2:
Either you can write simple line code
$(document).ready(function() {
$("h3").on("click", function() {
$(this).next().toggleClass("active");
});
});
we can select header with header Tag. After that, we can add toogleClass to just next element that is "DIV".
so, when click header, toggleClass will be added to next element that is DIV
You dont need to repeat it, give both a single class like "toggle-enabled" then instead of using toggler and toggler2 as two function you can put toggle-enabled as one selector and both will run the same function on click.
If you want to only toggle the one selected then use "this" keyword to get current and hide and show that or slide it whatever you want to do but dont need to repeat the code.
Here is your example code working as expected:
$(document).ready(function() {
$(".toggle-enabled").on("click", function() {
var nextdiv = $(this).parent().siblings("div");
nextdiv.is(":visible")?nextdiv.hide():nextdiv.show();
});
});
.togglethis{color:red;}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container">
<h3><span class="toggler toggle-enabled">Text A that toggles</span></h3>
<div class="wrapper togglethis">
<p>Random text</p>
</div>
</div>
<div class="container">
<h3><span class="toggler2 toggle-enabled">Text B that toggles</span></h3>
<div class="wrapper2 togglethis">
<p>I have left your toggler2 class in there and you can add more classes to separate it</p>
</div>
</div>
This code should work for your html:
$(document).ready(function () {
$('[class^="toggler"]').on('click', function () {
$(this).closest('.container').children('[class^="wrapper"]').toggle();
});
});
The code looks for any element on your html whose class name starts with toggle. It then attaches an on-click handler function. That function then looks for the affected element's closest ancestor with class name of container. Then from that ancestor/parent, it selects children with class name starting with wrapper. It then toggles the visibility of those children (or child)
You could give your togglers class names of toggleN (where N is any valid class name character) or simply toggle (same class name for all). Similarity, you could name the classes for your wrappers as wrapperN or simply wrapper.
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/)
I have a div with two divs inside that I want div A to show, with the other hidden. by default I want div A to show
<div id="0">
<div id="A">this is A</div>
<div id="B">this is B</div>
</div>
<div id="1">
<button1>this is 1</button>
<button2>this is 2</button>
</div>
Separate to this is the buttons to action it.
Here is where I got with the javascript:
$(document).ready(function() {
$('.toggle').hide();
$('a.togglelink').click(function() {
$('.toggle').hide();
$(this).parent().next('.toggle').toggle();
return false;
});
});
EXAMPLE
HTML
<div>
<div id="divA" class="toggle">this is A</div>
<div id="divB" class="toggle">this is B</div>
</div>
<div>
<button value="divA">this is 1</button>
<button value="divB">this is 2</button>
</div>
JavaScript
showHideDivs("divA");
$("button").on("click", function(){
showHideDivs(this.value)
});
function showHideDivs(id){
$(".toggle").hide();
$("#" + id).show();
}
Edit: #ShowcaseImagery - I realized that this question was asked specifically for bootstrap and that my solution is more of a JS/jQuery implementation. If you need similar functionality and you're using bootstrap you should look into the collapse accordions. The collapse documentation should outline how to do this correctly.
div0 and div1 is not valid XHTML. I'm guessing that's where your problem is. Instead use the id tag like so:
<div id="div0">YOUR STUFF HERE</div>
<div id="div1">MORE STUFF HERE</div>