How To Hide And Display Multiple Divs using JavaScript - javascript

How would I go about hiding and showing multiple divs using JavaScript? I don't want to use JQuery. I can make it work for hiding and showing one div but not multiple divs. The problem originates because I'm using PHP to display multiple records. These records are included in divs which have the same ID.
document.getElementById( 'history-slider' ).addEventListener( 'click', function() {
document.getElementById('edit-slider').style.display = 'block';
document.getElementById('history-slider').style.display = 'none';
}, false );
document.getElementById( 'edit-slider' ).addEventListener( 'click', function() {
document.getElementById('history-slider').style.display = 'block';
document..getElementById('edit-slider').style.display = 'none';
}, false );
.edit-slider {
display: none;
}
<div class="panel-body panel-strip" id="history-slider">
<h3>Title</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p>
<img src="img/time_icon.png" class="time-icon"> <span class="hour-text">4.00 hrs</span>
</p>
</div>
<hr class="calendar-divider">
<div class="panel-body panel-strip edit-slider">
<div class="row pull-right">
<a href="add.php">
<div class="col-xs-4 delete-panel">
<img src="img/delete_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Delete</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 edit-panel">
<img src="img/edit_icon.png" class="edit-images center-block"><span class="text-center edit-texts edit-text">Edit</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 record-panel">
<img src="img/record_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Record</span>
</div>
</a>
</div>
</div>
HTML;
<div class="panel-body panel-strip" id="history-slider">
<h3>Title</h3>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit.</p>
<p>
<img src="img/time_icon.png" class="time-icon"> <span class="hour-text">4.00 hrs</span>
</p>
</div>
<hr class="calendar-divider">
<div class="panel-body panel-strip edit-slider">
<div class="row pull-right">
<a href="add.php">
<div class="col-xs-4 delete-panel">
<img src="img/delete_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Delete</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 edit-panel">
<img src="img/edit_icon.png" class="edit-images center-block"><span class="text-center edit-texts edit-text">Edit</span>
</div>
</a>
<a href="http://google.com/">
<div class="col-xs-4 record-panel">
<img src="img/record_icon.png" class="edit-images center-block"><span class="text-center edit-texts">Record</span>
</div>
</a>
</div>
</div>
JavaScript;
document.getElementById( 'history-slider' ).addEventListener( 'click', function() {
document.getElementById('edit-slider').style.display = 'block';
document.getElementById('history-slider').style.display = 'none';
}, false );
document.getElementById( 'edit-slider' ).addEventListener( 'click', function() {
document.getElementById('history-slider').style.display = 'block';
document..getElementById('edit-slider').style.display = 'none';
}, false );
I have also set in the CSS to hide the "edit-slider" div on page load.
.edit-slider {
display: none;
}
The HTML is echoed out in a loop for every record in the database. Information is also added in replace of the placeholder text.
How should I best go about making it so that if a div if clicked it is hidden and the corresponding div is shown in it's place?
I was thinking about doing something about individually giving the divs separate ID's in PHP and than passing those ID's to JavaScript and creating some sort of a loop? My knowledge of JavaScript isn't massive so I don't really know how easy or difficult this method would be. Or is there a much easier method?
This is my first stack overflow post,so sorry if I'm doing anything wrong or missed something.

If you use classes instead of IDs you can use document.QuerySelectorAll() to get all the divs with that class and then show or hide as necessary.
Something like below would hide all divs with an edit-slider class and reveal (assuming they were already hidden) all divs with a history-slider class.
(function() {
var editSliders = document.querySelectorAll('div.edit-slider');
for(var i=0;i<editSliders.length;i++){
editSliders[i].style.display = 'none';
}
var historySliders = document.querySelectorAll('div.history-slider');
for(var i=0;i<historySliders.length;i++){
historySliders[i].style.display = 'block';
}
})();

First, consider using class instead of id to set multiple elements with the same attribute and value. Then, use the following script:
<script type="text/javascript">
document.querySelectorAll('div.history-slider').forEach(item => {
item.addEventListener("click", myFunction);
});
function myFunction() {
this.hide;
}
</script>

Related

First accordion active

I have this html accordion code:
<div class="accordion_container">
<div class="container">
<div class="accordion">
<button class="header">
Úvod
<i class="icon"></i>
</button>
<div class="body">
Lorem Ipsum
</div>
</div>
<div class="accordion">
<button class="header">
Závěr
<i class="icon"></i>
</button>
<div class="body">
Lorem Ipsum
</div>
</div>
</div>
and this script:
<script>
let accordion_btns = document.querySelectorAll('.accordion_container .accordion .header'),
accordion_bodys = document.querySelectorAll('.accordion_container .accordion .body');
if(accordion_btns && accordion_bodys)
{
accordion_btns = Array.isArray(accordion_btns) ? accordion_btns : Object.values(accordion_btns);
accordion_btns.forEach(accordion_btn=>{
accordion_btn.addEventListener('click', function(){
process_accordion(this);
});
});
function process_accordion(x) {
set_height_0();
let next_sibling = x.nextElementSibling;
if(next_sibling.offsetHeight>0)
{
next_sibling.style.height = '0px';
x.closest('.accordion').classList.remove('active');
} else {
next_sibling.style.height = next_sibling.scrollHeight+30+'px';
x.closest('.accordion').classList.add('active');
}
}
function set_height_0() {
accordion_bodys = Array.isArray(accordion_bodys) ? accordion_bodys : Object.values(accordion_bodys);
accordion_bodys.forEach(accordion_body=>{
accordion_body.style.height = '0px';
accordion_body.closest('.accordion').classList.remove('active');
});
}
}
</script>
I was trying from all my strengh and using all my beginner brain power, but I can't figure out, how to modify this code so the first accordion is active when I load the page. I tried adding the active class to into the html but the only part of the accordion is open when i load the page.
The best way to do this is using the details / summary, where you do not need to use javascript. See MDN documentation here.
You can then assign an attribute open="true" to the that you want
<div class="accordion_container">
<div class="container">
<details class="accordion" open="true">
<summary class="header">
Úvod
<i class="icon"></i>
</summary>
<div class="body">
Lorem Ipsum
</div>
</details
</div>
<div class="container">
<details class="accordion">
<summary class="header">
Závěr
<i class="icon"></i>
</summary>
<div class="body">
Lorem Ipsum
</div>
</details
</div>
</div>

Trying to figure out how to close old content when switching tabs

I have a very basic tab setup on my website and I managed to show the content I need when I press a tab. However, that content stays visible when I click another tab.
I also tried to write a function to remove all the clicked-on tab content before showing me the next one but the problem is it gives me an addEventListener error and it's been driving me crazy for the last couple of days.
const tabs = function(panelClass, numClass, techNum) {
document.getElementById(panelClass).addEventListener("click", () => {
removeStuff();
document.querySelector('.slide').style.display = "flex"
document.querySelector(numClass).style.display = "flex"
document.querySelector(techNum).style.display = "block"
});
};
function removeStuff(parameter) {
document.querySelector(parameter).addEventListener("click", () => {
document.querySelector('.slide').style.display = "none"
document.querySelector('.content-slide').style.display = "none"
document.querySelector('.picture').style.display = "none"
});
}
removeStuff('tab1');
removeStuff('tab2');
tabs('tab1', '.two', ".p2");
tabs('tab2', '.one', ".p1");
<img class='picture p2' src="./picture.jpg" height=140px;alt="">
<img class='picture p1 ' src="./picture.jpg" height=140px;alt="">
<div class="slide">
<!-- Slide 1 -->
<div class="content-slide active one">
<h3>Some text</h3>
<p>Lorem ipsum dolor sit.</p>
</div>
<!-- Slide2 -->
<div class="content-slide two">
<h3>Some Text</h3>
<p>Lorem ipsum dolor </p>
</div>
</div>
The easiest and better approach would be to check that document.getElementById(someID) is not null before adding an event listener to it:
Demo code:
const tabs = function(panelClass, numClass, techNum) {
var panel = document.getElementById(panelClass);
if(panel){
panel.addEventListener("click", () => {
removeStuff();
document.querySelector('.slide').style.display = "flex"
document.querySelector(numClass).style.display = "flex"
document.querySelector(techNum).style.display = "block"
});
}
};
function removeStuff(parameter) {
var tab = document.querySelector(parameter);
if(tab){
tab.addEventListener("click", () => {
document.querySelector('.slide').style.display = "none"
document.querySelector('.content-slide').style.display = "none"
document.querySelector('.picture').style.display = "none"
});
}
}
removeStuff('tab1');
removeStuff('tab2');
tabs('tab1', '.two', ".p2");
tabs('tab2', '.one', ".p1");
<img class='picture p2' src="./picture.jpg" height=140px;alt="">
<img class='picture p1 ' src="./picture.jpg" height=140px;alt="">
<div class="slide">
<!-- Slide 1 -->
<div class="content-slide active one">
<h3>Some text</h3>
<p>Lorem ipsum dolor sit.</p>
</div>
</div>
<!-- Slide2 -->
<div class="content-slide two">
<h3>Some Text</h3>
<p>Lorem ipsum dolor </p>
</div>
</div>
If this an actual copy-and-paste of your code, a couple of things stand out:
You closed your main slide div before "content-slide two". Given the final <div> tag in your markup...that doesn't look like what you meant to do. One way or another, you have an extra div tag.
Your call to removeStuff() in the tabs function does not pass a parameter. That's going to cause some issues with querySelector; you'd be invoking addEventListener on an undefined object in the removeStuff() function.
It's likely that these two things are part of the problems you're experiencing.

Filter cards in Bootstrap 4 with jQuery

I am attempting to create a page that is populated by many cards, using bootstrap 4's new card component.
I want to create a search bar, that when searched, filters out cards whose titles don't match the search query.
Here is a plunker of what I have in mind. Plunker
I would like the cards to get something like a display: none, or opacity:0 if they don't match.
I currently am attempting to write a function that onChange of the search bar does this. I'll post if I can get it figured out.
I've tried to use the built in snippet feature as well.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.0/jquery.min.js"></script>
<script src="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/js/bootstrap.js"></script>
<link href="https://cdn.rawgit.com/twbs/bootstrap/v4-dev/dist/css/bootstrap.css" rel="stylesheet" />
<div class="container">
<div class="row">
<div class="col-sm-4">
<input type="search" placeholder="Search......" name="search" class="searchbox-input" onkeyup="buttonUp();" required>
</div>
<div class="col-sm-4">
</div>
<div class="col-sm-4">
</div>
</div>
<div class="card-columns">
<div class="card">
<div class="card-block">
<h4 class="card-title">Card title that wraps to a new line</h4>
<p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
</div>
</div>
<div class="card card-block">
<blockquote class="card-blockquote">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer>
<small class="text-muted">
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card">
<div class="card-block">
<h4 class="card-title">Card title</h4>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small>
</p>
</div>
</div>
<div class="card card-block card-inverse card-primary text-xs-center">
<blockquote class="card-blockquote">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat.</p>
<footer>
<small>
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card card-block text-xs-center">
<h4 class="card-title">Card title</h4>
<p class="card-text">This card has supporting text below as a natural lead-in to additional content.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small>
</p>
</div>
<div class="card">
</div>
<div class="card card-block text-xs-right">
<blockquote class="card-blockquote">
<p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Integer posuere erat a ante.</p>
<footer>
<small class="text-muted">
Someone famous in <cite title="Source Title">Source Title</cite>
</small>
</footer>
</blockquote>
</div>
<div class="card card-block">
<h4 class="card-title">Card title</h4>
<p class="card-text">This is a wider card with supporting text below as a natural lead-in to additional content. This card has even longer content than the first to show that equal height action.</p>
<p class="card-text"><small class="text-muted">Last updated 3 mins ago</small>
</p>
</div>
</div>
</div>
Here's a quick example of how you could do it using jQuery's contains selector:
$('.searchbox-input').change( function () {
$('.card').show();
var filter = $(this).val(); // get the value of the input, which we filter on
$('.container').find(".card-title:not(:contains(" + filter + "))").parent().css('display','none');
});
Currently this is set up to happen on change of the search input, you would probably want set up a submit button and have it fire on submit instead.
Bootply Example
Here are a few more modern options that are Bootstrap 4 or Bootstrap 5 friendly...
Bootstrap 5 (using JavaScript)
var buttonUp = () => {
const input = document.querySelector(".searchbox-input");
const cards = document.getElementsByClassName("card");
let filter = input.value
for (let i = 0; i < cards.length; i++) {
let title = cards[i].querySelector(".card-body");
if (title.innerText.indexOf(filter) > -1) {
cards[i].classList.remove("d-none")
} else {
cards[i].classList.add("d-none")
}
}
}
Demo
Bootstrap 4 (using jQuery)
// this overrides `contains` to make it case insenstive
jQuery.expr[':'].contains = function(a, i, m) {
return jQuery(a).text().toUpperCase()
.indexOf(m[3].toUpperCase()) >= 0;
};
var buttonUp = () => {
$('.card').removeClass('d-none');
var filter = $(this).val(); // get the value of the input, which we filter on
$('.card-deck').find('.card .card-body h4:not(:contains("'+filter+'"))').parent().parent().addClass('d-none');
}
Demo
Here is the simple solution.
$(document).ready(function(){
$('.searchbox-input').on("keyup", function() {
var value = $(this).val().toLowerCase();
$(".card").filter(function() {
$(this).toggle($(this).text().toLowerCase().indexOf(value) > -1)
});
});
});
$(document).ready(function() {
$('#searchForm').keyup(function(){
search_text($(this).val());
});
function search_text(value){
$('#search_section .card').each(function(){
var found = 'false';
$(this).each(function(){
if($(this).text().toLowerCase().indexOf(value.toLowerCase()) >= 0)
{
found = 'true';
}
});
if(found == 'true'){
$(this).show()
}
else {
$(this).hide();
}
})
}
});

How do I get a div to display a specific image when a user mouses over either of two divs?

I want the div with the class features_3_content_center to display the FH_MainMenu.png image when a user mouses over the div with id FH_Blurb, or display the HDS_MainMenu.png image when a user mouses over the div with id HDS_Blurb.
I've attempted this below by having both images on top of each other in features_3_content_center and having it display the image based on its id. This doesn't seem to work, it just displays the first image (HDS_MainMenu.png) and doesn't change on mouseover. What am I doing wrong?
PicChanger: function() {
$('#FH_Blurb').mouseover(function() {
$('.features_3_content_center').getElementById('#features3_FH_image');
});
$('#HDS_Blurb').mouseover(function() {
$('.features_3_content_center').getElementById('#features3_HDS_image');
});
},
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">
<div class="col-sm-4 col-md-4 ol-lg-4" id="features_3_content_left">
<div class="feature" id="FH_Blurb">
<h4>Fizz+Hummer</h4>
<p>Epsum factorial non deposit quid pro quo hic escorol. Olypian quarrels et gorilla congolium sic ad nauseum.
</p>
</div>
</div>
<div class="col-sm-4 col-md-4 ol-lg-4">
<div class="features_3_content_center">
<img src="images/HDS_MainMenu.png" class="img-responsive" id="features3_HDS_image" alt="img">
<img src="images/FH_MainMenu.png" class="img-responsive" id="features3_FH_image" alt="img">
</div>
</div>
<div class="col-sm-4 col-md-4 ol-lg-4" id="features_3_content_right">
<div class="feature" id="HDS_Blurb">
<div>
<h4 class="we_make_games_HDS_text">Human Delivery Service</h4>
<p>Epsum factorial non deposit quid pro quo hic escorol. Olypian quarrels et gorilla congolium sic ad nauseum.
</p>
</div>
</div>
</div>
</div>
JSFiddle: http://jsfiddle.net/2hL71dsr/
Kind of like this:
$('#features3_FH_image, #features3_HDS_image').hide();
$('#FH_Blurb').hover(function() {
$('#features3_FH_image').toggle();
});
$('#HDS_Blurb').hover(function() {
$('#features3_HDS_image').toggle();
});
See it in action in this demo
You aren't actually doing anything to the images. Here is a simple, straight-forward method of showing the images on mouseover, then hiding them again on mouseout.
var imgContainer = $('.features_3_content_center');
var FH_image = imgContainer.find('#features3_FH_image').hide();
var HDS_image = imgContainer.find('#features3_HDS_image').hide();
$('#FH_Blurb').on('mouseover', function() {
FH_image.show();
});
$('#FH_Blurb').on('mouseout', function() {
FH_image.hide();
});
$('#HDS_Blurb').on('mouseover', function() {
HDS_image.show();
});
$('#HDS_Blurb').on('mouseout', function() {
HDS_image.hide();
});

jQuery how to store elements for append() or clone()

I made a very simple expand boxes. the Structure is like below
<div class="container">
<div class="item"> </div>
<div class="outside"> </div> <!-- append '.item''s children to '.outside' -->
<div class="item"> </div>
<div class="item"> </div>
</div>
I'd like to achieve is that, if a box is opened, contents can be viewed immediately when you click another box. ( Do not need to slideUp and slideDown again)
The problem I am having is that, If you click the first box box 1, you can see the slider correctly, then you click box 2, the contents can be showed properly as well, and then you click back to box 1, contents won't show. I understand append all .inside children to '.outside' contents can be view only once as append moves elements to .outside, if I use clone(), I can view the contents but will lose a working slider.
so my question is do I need to append .inside children to '.outside' first then move everything back to where is was? if someone could help please? Thanks!
Online Sample http://jsfiddle.net/ny4sx/
Here is my html
<div class="container">
<div class="item">1
<div class="inside">
<ul class="slider">
<li>
<img src="http://lorempixel.com/580/250/nature/1" />
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/2" />
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/3" />
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/4" />
</li>
</ul>
</div>
</div>
<div class="item">2</div>
<div class="item">3</div>
</div>
jQuery
var $outside = $('<div class="outside"></div>');
var $closebutton = $('<div class="close">x</div>');
$outside.append($closebutton);
$('.item').click(function (event) {
event.preventDefault();
var $this = $(this);
$this.toggleClass('active');
if ($this.hasClass('active')) {
$('.active').removeClass('active');
$this.addClass("active");
}
if $this.next().hasClass('outside')) {
console.log('yes');
} else {
console.log('no');
$outside.insertAfter(this).css({
'height': 300
}).slideDown();
}
$('.close').click(function () {
$('.outside').remove();
$('.active').removeClass('active');
});
});
//Slider FROM Here
// settings
var $slider = $('.slider'); // class or id of carousel slider
var $slide = 'li'; // could also use 'img' if you're not using a ul
var $transition_time = 1000; // 1 second
var $time_between_slides = 4000; // 4 seconds
function slides() {
return $slider.find($slide);
}
slides().fadeOut();
// set active classes
slides().first().addClass('active');
slides().first().fadeIn($transition_time);
// auto scroll
$interval = setInterval(
function () {
var $i = $slider.find($slide + '.active').index();
slides().eq($i).removeClass('active');
slides().eq($i).fadeOut($transition_time);
if (slides().length == $i + 1) $i = -1; // loop to start
slides().eq($i + 1).fadeIn($transition_time);
slides().eq($i + 1).addClass('active');
},
$transition_time + $time_between_slides);
could you consider something like this or is it too different from what you expect.
HTML:
<div class="container">
<div class="item" data-content="1">1</div>
<div class="item" data-content="2">2</div>
<div class="item" data-content="3">3</div>
<div class="outside">
<div class="close">x</div>
<div class='content content1'>
<ul class="slider">
<li>
<img src="http://lorempixel.com/580/250/nature/1" />
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/2" />
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/3" />
</li>
<li>
<img src="http://lorempixel.com/580/250/nature/4" />
</li>
</ul>
</div>
<div class='content content2'>
<h1>this is item 2</h1>
</div>
<div class='content content3'>
<h1>this is item 3</h1>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit. Sunt, aliquam, dolorum ipsa perferendis iure quibusdam consequuntur nulla reiciendis velit aut modi reprehenderit. Sit, mollitia, natus odio repellat neque error voluptatem.</p>
</div>
</div>
</div>
JS:
$('.item').click(function(event) {
var $this = $(this);
var contentNumber = $this.data("content");
$('.active').removeClass('active');
$this.addClass("active");
$('.content').hide();
$('.content'+contentNumber).show();
$('.outside').slideDown();
});
$('.close').click(function(){
$('.outside').slideUp();
$('.active').removeClass('active');
});
FIDDLE
I played with it a little here:
http://jsfiddle.net/ny4sx/37/
A summary of my edits:
var savedContent = $('.outside .content').children();
var target = $('.outside').prev().children().first();
console.dir(target);
$('.outside .content').remove();
target.append(savedContent);
Not the cleanest (I was doing a lot of trial and error), but I figured out what the issue was. You were deleting the contents before you saved a reference to it, there fore it was not persisting. I would definitely do it the way that MamaWalkter proposed, though.

Categories

Resources