javascript hide/show example - close divs - javascript

In this javascript hide/show example, how can I close all other divs when a div is selected?
<script TYPE="text/JavaScript">
function show_hide(id, show)
{
if (el = document.getElementById(id))
{
if (null==show) show = el.style.display=='none';
el.style.display = (show ? '' : 'none');
}
}
</script>
& don't tell me to use jQuery, becuase it won't run in some mobile environments that we use.

I'd do it like this
var alldivs = document.getElementsByTagName("DIV");
for (var i=0;i<alldivs.length;i++){
var odiv = alldivs[i];
//we only need "other" divs, not the one we're working on
if ( (odiv.id) && (odiv.id!=id)) {
odiv.style.display="none";
}
}
(+ thanks for not asking for a jQuery solution:)

Related

Multiple Functions with one Code

so I'm using this code, to slideToggle a box on my webpage.
// OPEN CERTAIN BOX
$(function() {
var sliding = false;
var mq = window.matchMedia( "(min-width: 700px)" );
if (mq.matches) {
var time = 500;
} else {
var time = 0;
}
var id = ('1');
var div = ('#toggle-content-' + id);
var img = ('#toggle-img-' + id);
var toggler = ('toggler-' + id);
$(div).hide()
$(toggler).click(function() {
if (sliding == false) {
sliding = true;
// Open / Close
$( div ).slideToggle(time,"swing");
// ...
As you can see, I'm using the var id, to use the toggle function for a certain box, which has its own css and html code.
I have 7 more boxes. Until now, i copied the code 7 times and changed the id at each copy from 2 - 8. Is there a way to make it with one code?
I tried a for loop, that goes from 1 - 8 but this obviously didnt work.
Has someone an idea? Or do I have to make that 8 copies and changed the id.
Edit:
My approach with the for-loop:
$(function() {
var sliding = false;
var mq = window.matchMedia( "(min-width: 700px)" );
if (mq.matches) {
var time = 500;
} else {
var time = 0;
}
for(i = 1; i <= 8; i++){
var id = (i.toString());
var div = ('#toggle-content-'+id);
var img = ('#toggle-img-'+id);
var toggler = ('toggler-'+id);
$( div ).hide()
$( toggler ).click(function(){
if (sliding == false){
sliding = true;
// Open / Close
$( div ).slideToggle(time,"swing");
...
And this is my html code for one box:
<tr><td cellspacing="0" cellpadding="0" height="50px" class="upper">
<toggler-1><area-head-text><img id="toggle-img-1" src="images/box_opener.png"/>Starterpaket</area-head-text></toggler-1>
</td></tr>
<tr><td>
<div id="toggle-content-1">
<area-head-text>
<img class="text-image" src="images/arrow.png"/>3 individuelle Entwürfe<br>
<img class="text-image" src="images/arrow.png"/>3 Korrekturzeichnungen<br>
<img class="text-image" src="images/arrow.png"/>Internationale Nutzungsrechte<br>
<img class="text-image" src="images/arrow.png"/>400€<br><br>
</area-head-text>
</div>
</td></tr>
I'm not sure why you put "Obviously" a loop doesn't work, because that's pretty much exactly what you should do. Something like this:
for(var i = 1; i <= 8; i++)
{
var div = $('#toggle-content-' + i);
var img = $('#toggle-img-' + i);
var toggler = $('toggler-' + i);
$(div).hide()
$(toggler).click(function() {
if (sliding == false) {
sliding = true;
// Open / Close
$( div ).slideToggle(time,"swing");
// ...
}
This is 2 options.
(and my preference) -
Instead of using an ID to add the click event onto each individual toggle button, use the same class on each, and add the click event on that class. When the user clicks a toggle button traverse the DOM from the clicked toggle button to perform your toggle on the relevant <div>.
This would look something like:
$(function() {
$('.toggleBtn').click(function() {
var sliding = $(this).data('sliding'); //use data attr to store sliding status
if (sliding == false) {
$(this).data('sliding') = true;
}else {
return; //don't toggle we're sliding
}
// navigate to element and toggle
$(this).parent('.someParentElement').children('.theDiv').slideToggle(time,"swing");
//clear sliding status
$(this).data('sliding', false);
}
}
The reason this is my preference, is because although it's faster to target an ID for a click event than a class for a single event, using 7 click events on 7 different IDS in my opinion (I don't know for sure) is less efficient than using a single click event on 1 class. That's my perceived purpose of using events on classes rather than IDS.
Also this way, when you want to add another box in, or remove a box, you don't need to modify any Javascript, the only thing you would need to maintain this code for is if you decide to change the structure of the HTML, and therefore the navigation of the DOM to perform your toggle.
using your method:
var ids = ["id1","id2","id3"];
for(var id in ids) {
var $div = $('#toggle-content-' + id);
var $img = $('#toggle-img-' + id);
var $toggler = $('toggler-' + id);
$div.hide()
$toggler.click(function() {
if (sliding == false) {
sliding = true;
// Open / Close
$div.slideToggle(time,"swing");
// ...
}

tags underneath headings disappear when clicked again w/ javascript no idea why

I have pasted the javascript below but also a link to my codepen so you can see exactly what I am talking about.
I would like the heading to be clicked and expose the text below. On another click I would like for the text to go back to hidden. Multiple headings can be opened at the same time. What is happening with my current setup is you can click once to show, click again to hide and then when you click again to show nothing shows, if you keep clicking the text and headings below are eaten/dissapear. I would prefer to do this without jquery. thanks for any help.
http://codepen.io/jrutishauser/pen/YPrrNa
var clickToShow = function () {
if (this.nextElementSibling.className === 'open'){
this.nextElementSibling.remove('open');
} else if (this.nextElementSibling.className != 'open') {
this.nextElementSibling.className = 'open';
}
};
var articleHeadings = document.getElementsByTagName('h3');
for (var index = 0; index < articleHeadings.length; index++){
articleHeadings[index].onclick = clickToShow;
}
var subArticleHeadings = document.getElementsByTagName('h4');
for (var index2 = 0; index2 < subArticleHeadings.length; index2++){
subArticleHeadings[index2].onclick = clickToShow;
}
Change this.nextElementSibling.remove('open') to this.nextElementSibling.className = ''. I believe remove() method removes the element, not the class.
You can do it like this also. This is the correct way of doing it.
var clickToShow = function () {
element=this.nextElementSibling;
if (element.className === 'open'){
element.className=element.className.replace('open','');
} else if (element.className != 'open') {
element.className = 'open';
}
};

'href' Not Showing Output on Click

Im trying to have a href link expand/display extra text when clicked however when I click it nothing happens.
When I run the html code I can click on the link but it does not show the text for some reason.
Any idea why?
Heres the code:
<html>
click to expand
<div id="divID" style="display: none;">this is expanded</div>
</html>
I'm trying to keep the code as short as possible as the above code will have to be repeated hundreds of times for each link.
Assuming you're using jQuery, you are using the CSS selector incorrectly. Your line should be this:
click to expand
The # in #divID represents any element with an id of divID, whereas just using divID will search for divID tags (something like <divID></divID>)
See here for more documentation on the ID Selector and here's a list of all the CSS selectors you can use, including the Element Selector for you to understand why your previous code didn't work.
You can also combine CSS selectors to narrow your selection in the future, although it's not much necessary with an ID selector:
click to expand
And if you absolutely insist on not using jQuery:
click to expand
or breaking it out into its own function:
<script>
function toggleElementById(id) {
if (document.getElementById(id).style.display == 'none') {
document.getElementById(id).style.display = 'block';
} else {
document.getElementById(id).style.display = 'none';
}
}
</script>
click to expand
Add this to your page:
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
Then:
$('#divID').toggle();
I see you're using jQuery, right? So I wrote your answer in jQuery..
$('.toggle').click(function () {
var selected = $(this).attr('href');
$('.expandable'+selected).toggle();
});
Check out the jsfiddle
If you're not using jQuery than here is the javascript version (html changed).
var expandable = document.getElementsByClassName("expandable");
for (i = 0; i < expandable.length; ++i) {
expandable[i].setAttribute('style','display: none;');
}
var toggle = document.getElementsByClassName("toggle");
for (i = 0; i < toggle.length; ++i) {
toggle[i].setAttribute('onclick','toggler(this)');
}
function toggler(obj) {
var id = obj.dataset.toggle,
el = document.getElementById(id);
el.style.display = (el.style.display != 'none' ? 'none' : '');
}
Check out the jsfiddle

How to reduce 180 lines of code down to 20 in Javascript?

I have a lot of click handler functions which are almost (textually and functionally) identical. I've got a menu with maybe 10 items in it; when I click on an item, the click handler simply makes one div visible, and the other 9 div's hidden. Maintaining this is difficult, and I just know there's got to be a smart and/or incomprehensible way to reduce code bloat here. Any ideas how? jQuery is Ok. The code at the moment is:
// repeat this function 10 times, once for each menu item
$(function() {
$('#menuItem0').click(function(e) {
// set 9 divs hidden, 1 visble
setItem1DivVisible(false);
// ...repeat for 2 through 9, and then
setItem0DivVisible(true);
});
});
// repeat this function 10 times, once for each div
function setItem0DivVisible(on) {
var ele = document.getElementById("Item0Div");
ele.style.display = on? "block" : "none";
}
Create 10 div with a class for marking
<div id="id1" class="Testing">....</div>
<div id="id2" class="Testing">....</div>
<div id="id3" class="Testing">....</div>
and apply the code
$('.Testing').each(function() {
$(this).click(function() {
$('.Testing').css('display', 'none');
$(this).css('display', 'block');
}
}
$(document).ready(function (){
$("div").click(function(){
// I am using background-color here, because if I use display:none; I won't
// be able to show the effect; they will all disappear
$(this).css("background-color","red");
$(this).siblings().css("background-color", "none");
});
});
Use .siblings() and it makes everything easy. Use it for your menu items with appropriate IDs. This works without any for loops or extra classes/markup in your code. And will work even if you add more divs.
Demo
Fiddle - http://jsfiddle.net/9XSJW/1/
It's hard to know without an example of the html. Assuming that there is no way to traverse from the menuItem to ItemDiv - you could use .index and .eq to match up the elements based on the order they match with the selector.
var $menuItems = $("#menuItem0, #menuItem1, #menuItem2, ...");
var $divs = $("#Item0Div, #Item1Div, #Item2Div, ...");
$menuItems.click(function(){
var idx = $(this).index();
// hide all the divs
$divs.hide()
// show the one matching the index
.eq(idx).show();
})
Try
function addClick(i) {
$('#menuItem'+i).click(function(e) {
// set nine divs hidden, 1 visble
for( var j = 0; j < 10; ++j ) {
var ele = document.getElementById("Item"+j+"Div");
ele.style.display = (i == j ? "block" : "none");
}
});
}
// One click function for all menuItem/n/ elements
$('[id^="menuItem"]').on('click', function() {
var id = this.id; // Get the ID of the clicked element
$('[id^="Item"][id$="Div"]').hide(); // Hide all Item/n/Div elements
$('#Item' + id + 'Div').show(); // Show Item/n/Div related to clicked element
});
Obviously this would be much more logical if you were using classes instead:
<elem class="menuItem" data-rel="ItemDiv-1">...</elem>
...
<elem class="ItemDiv" id="ItemDiv-1">...</elem>
$('.menuItem').on('click', function() {
var rel = $(this).data('rel'); // Get related ItemDiv ID
$('.ItemDiv').hide(); // Hide all ItemDiv elements
$('#' + rel).show(); // Show ItemDiv related to clicked element
});
Save the relevant Id's in an array - ["Item0Div", "Item1Div", ...]
Create a generic setItemDivVisible method:
function setItemDivVisible(visible, id) {
var ele = document.getElementById(id);
ele.style.display = visible ? "block" : "none";
}
And set your click handler method to be:
function(e) {
var arrayLength = myStringArray.length;
for (var i = 0; i < idsArray.length; i++) {
setItemDivVisible(idsArray[i] === this.id, idsArray[i]);
}
}
I think this will do the trick

Toggle multiple divs on and off (almost working)

I have this:
function toggleCharts() {
var x, divArray = ["item_4746983", "item_4491867"];
for (x in divArray) {
if (x) {
document.getElementById(divArray[x]).style.display = 'block';
}
}
<button onClick="toggleCharts();">Charts</button>
and this:
#item_4746983 {
display:none;
}
#item_4491867 {
display:none;
}
item_4746983 & item_4491867 are thumbnails that I want to show or hide when you click on charts
The code works and they display when I click the button but I can't figure out the code to hide them by clicking on it again.
Instead of styling by id, style by class:
.hiddenThumbnail {
display:none;
}
Then apply and remove the hiddenThumbnail class to and from the two items. This makes your css code smaller, and makes everything generally more maintainable. See this excellent answer for a guide on how to modify the classes.
Alternatively, use a library like YUI to do it (I'm sure jquery has similar functions also).
Check if the div is shown already and change the display. The following code should work.
var div = document.getElementById(divArray[x])
var shown = div.style.display;
if ("block" == shown) {
div.style.display = none;
} else {
div.style.display = block;
}
Here is a link that shows various ways of doing what you want:
http://www.dustindiaz.com/seven-togglers/
Check the demo.
function toggleCharts() {
var divArray = ["item_4746983", "item_4491867"], i, ele;
for (i=0; i < divArray.length; i++) {
ele = document.getElementById(divArray[i]);
ele.style.display = ele.style.display === 'block' ? 'none' : 'block';
}
}

Categories

Resources