Toggle multiple spans - javascript

I need to control hiding/showing certain spans. I found some examples here and the basic code works. Here is my jsfiddle. There are two topics and when the word more is clicked on, sub-topics are shown. The problem is that all of the sub-topics are shown, not just the ones under the topic that was clicked.
I know the problem is with the same class name being used for the two div sections and if I change the class name of one of them and duplicate the jquery it will work as I want. But this code is being created using a loop function in php and there isn't a set number of possible topics. I suppose I could change the php code to create unique class names but I don't know how to add the jquery code so it will check any number of possibilities. How can this be coded?
<script>
$("#kid-1").hide();
$("#kid-2").hide();
$("#kid-3").hide();
$(".more-kids").click(function() {
$("#kid-1").toggle();
$("#kid-2").toggle();
$("#kid-3").toggle();
});
</script>
<div class="information">
<span>Terms</span>
<span class="more-kids">more</span><br />
<span id="kid-1">First Child</span><br />
<span id="kid-2">Second Chlld</span><br />
</div>
<div class="information">
<span>Conditions</span>
<span class="more-kids">more</span><br /><br />
<span id="kid-3">Third Child</span><br />
</div>

If you are making id's that are numbers, that indicates you should probably be using a class instead. What you could instead do is change your id to a class being "kid". Then toggle the items by using $(this).nextAll(".kid").toggle():
$(".kid").hide();
$(".more-kids").click(function() {
$(this).nextAll(".kid").toggle();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="information">
<span>Terms</span>
<span class="more-kids">more</span><br />
<span class="kid">First Child</span><br />
<span class="kid">Second Chlld</span><br />
</div>
<div class="information">
<span>Conditions</span>
<span class="more-kids">more</span><br /><br />
<span class="kid">Third Child</span><br />
</div>

Related

Changing display from block to none for multiple textareas

I'm currently trying to figure out how to make a text area disappear while another one will appear instead.
I have no knowledge of javascript and I have just started learning the basics of HTML and CSS, is there a chance anyone from the forum can help me out or maybe guide me to the correct path.
I'm attaching the part of the code, to make it more clear.
When you click on "2.svg" it should change the "textarea.one's and three's" "display: block;" into "display: none;"
When you click on "3.svg" it should change the "textarea.two's and one's" "display: block;" into "display: none;"
When you click on "1.svg" it should change the "textarea.two's and three's" "display: block;" into "display: none;"
I hope this explanation is clear enough, I'm also not sure if I'm allowed to ask to provide full code on this forum without preparing anything on my own.
Thank you in advance to whoever will read this!
<div>
<img id="header1" src="/1.svg" alt="Open Menu" class="menu">
<img id="header1" src="/2.svg" alt="Open Menu" class="menu">
<img id="header1" src="/3.svg" alt="Open Menu" class="menu">
</div>
<div class="textniz">
<textarea class="one" id="myInput" name="myInput" readonly>
Line one
Line two
Line three</textarea>
</div>
<div class="textniz">
<textarea class="two" id="myInput" name="myInput" readonly>
Line four
Line five
Line six</textarea>
</div>
<div class="textniz">
<textarea class="three" id="myInput" name="myInput" readonly>
Line seven
Line eight
Line nine</textarea>
</div>
Read this: https://www.w3schools.com/jsref/prop_style_display.asp
In order to change an element's display property, you can access it like this:
document.querySelector("myelement").style.display = "theValueIWant";
Mind the different selectors
Now, what you want is when we click 2.svg to change textarea one and three's diplay property from block to none. First select these using document.querySelector("textarea.one") and then change the value: document.querySelector("textarea.one").style.display = "none";
Now, to call this javascript you need an event. You can use the onClick one. Simply
<img id="header1" onClick="document.querySelector('textarea.one').style.display = 'none';" src="/1.svg" alt="Open Menu" class="menu">
would change the display property of the textarea.one element on click.
Method I In order to call multiple elements, what I suggest is adding one more class to the two elements that you are going to hide, and the simply use the above code with changing the class. E.g., to textarea one and three add class hideOne and then hide the element with document.querySelector("hideOne").style.display = "none";
Method II Another way you can accomplish this, is by creating a function that would hide the two components. Create a script tag and then use the above selector to hide the two elements:
<script>
function hide1(){
document.querySelector('textarea.one').style.display = "none"
document.querySelector('textarea.three').style.display = "none"
}
</script>
Then call the function by inserting into the element to be clicked(your svg): onClick="hide1()"
That's it!
The following is a very short way of achieving the same without jQuery.
It is not as easy to read as the jQuery based solution but contains certain elements that might be interesting to you too:
I used a "delegated event attachment" which means I attached the click event handler to the parent element (the first div in the document) of the three <img> elements. Doing it this way keeps the document "fast" and makes it easily extendable by further elements.
I identify the clicked image by its id attribute: only if the clicked element has the tagName==="DIV" and its id starts with "header", I will take the remaining (id-string - 1) as the index to look-up the class name c in the cls array.
In the txtas.forEach() loop I will then make the <textarea> containing c in its classList visible, while all others will be hidden.
const cls=["one","two","three"],
txtas=document.getElementsByName("myInput");
document.querySelector("div").onclick=ev=>{ let el=ev.target;
if(el.tagName==="IMG"&&el.id.substr(0,6)==="header"){
let c=cls[el.id.substr(6)-1];
txtas.forEach(t=>t.style.display=t.classList.contains(c)?"":"none");
}
}
<div>
<img id="header1" src="/1.svg" alt="first" class="menu">
<img id="header2" src="/2.svg" alt="second" class="menu">
<img id="header3" src="/3.svg" alt="third" class="menu">
</div>
<div class="textniz">
<textarea class="one" name="myInput" readonly>
Line one
Line two
Line three</textarea>
</div>
<div class="textniz">
<textarea class="two" name="myInput" readonly>
Line four
Line five
Line six</textarea>
</div>
<div class="textniz">
<textarea class="three" name="myInput" readonly>
Line seven
Line eight
Line nine</textarea>
</div>
I removed the id attributes from your <textarea> elements as they would have been dupes. The script works very well without them.
Impossible with just CSS but so easy with JQuery (which I think would be easier fo you to start as the semantic is much more read friendly for begginers than pure javascript)
like this:
$("#header1").click(function(){
$(".two").hide();
$(".three").hide();
$(".one").show();
});
$("#header2").click(function(){
$(".one").hide();
$(".three").hide();
$(".two").show();
});
$("#header3").click(function(){
$(".one").hide();
$(".two").hide();
$(".three").show();
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<div>
<img id="header1" src="/1.svg" alt="Open Menu" class="menu">
<img id="header2" src="/2.svg" alt="Open Menu" class="menu">
<img id="header3" src="/3.svg" alt="Open Menu" class="menu">
</div>
<div class="textniz">
<textarea class="one" id="myInput" name="myInput" readonly>
Line one
Line two
Line three</textarea>
</div>
<div class="textniz">
<textarea class="two" id="myInput" name="myInput" readonly>
Line four
Line five
Line six</textarea>
</div>
<div class="textniz">
<textarea class="three" id="myInput" name="myInput" readonly>
Line seven
Line eight
Line nine</textarea>
</div>
So as per your question, if it is just a quick switch and you want only one view to be active, it's better and easy to use jQuery because it is very direct, #Alvaro has already shared the quick code snippet. It's very easy to play around with jQuery.
Disclaimer: It makes your life so easy that if in case you try to learn a full seasoned framework, then there will be a long workaround. But get started with jQuery. You'll find it very interactive.
Happy Coding :)

How to get ID, Name and Class of Extreme DIV from button click using JQuery?

How to get ID of extreme parent div?
<div class="panel" id="Kudapanel"> //Extreme Div
<div class="Kudapanel1" id="Kudapanel1">
</div>
<div>
<div>
<input type="button" id="yo"> //In much nestings
</div>
</div>
</div>
Take two use cases:
if panel classname is there in extreme div, then how to get ID of div?
if panel classname is not there, then how to get ID of parent div?
I tried:
$("#yo").click(function(){
alert($(this).closest('div').attr('id'));
});
Please do not use parent().parent().parent(), as extreme div location could be different at multiple places
Try using the class selector:
$("#yo").click(function(){
alert($(this).closest('div.panel').attr('id'));
});
If you do not have the class we need to see the parent html where this will be located in order to give you a solution.
UPDATE
A solution if the class is not defined is to use another tag, instead of div use section for the upper parent tag.
<section id="Kudapanel"> //Extreme Div
<div class="Kudapanel1" id="Kudapanel1">
</div>
<div>
<div>
<input type="button" id="yo"> //In much nestings
</div>
</div>
</section>
$("#yo").click(function(){
alert($(this).closest('section').attr('id'));
});
If you can count on the level of nesting, then you can just go up the parent chain until you get to it
$('#yo').on('click', function(){
alert($(this).parents().eq(2).prop('id'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="panel" id="Kudapanel"> //Extreme Div
<div class="Kudapanel1" id="Kudapanel1">
</div>
<div>
<div>
<input type="button" id="yo"> //In much nestings
</div>
</div>
</div>
Otherwise you should go with #Mivaweb's answer

Knockout js some parts does not render

I have a very weird knockout js problem. What happens is that only the first tag in each div is rendered to the DOM, the others just ... don't. The werdest part is this: it does not produce any errors and the rest of the dom renders correctly, secondly it happens most but not all the time? Any guesses?
The template that is being rendered is this:
<div class="row">
<div>
<span data-bind="text: $data.topRows()[0].text() + $data.topRows()[1].text()" />
<input data-bind="value: $data.topRows()[0].inputText" /> <!-- this fails to go into the dom sometimes and every row past the first span and inside this div -->
</div>
<div>
<span data-bind="text: $data.topRows()[1].text()" /> <!-- this is renderdd -->
<input data-bind="text: $data.topRows()[1].inputText" /> <!-- this is not -->
</div>
</div>
I know this is not much to go on but well, I am speechless. RequireJs is used to require all the files.
You have various problems in your proposed snippet:
span elements don't work too well when self-closing, use <span data-bind="..."></span> instead;
you don't close the first comment correctly
as #ilya mentioned you probably want the value binding for inputs
you have a typo for the second input, it starts with <inputdata-bind... (missing a space there
If I fix those four problems your code will work fine.
You should use value binding instead of text for <input>
<span data-bind="text: $data.topRows()[0].text() + $data.topRows()[1].text()" />
<input data-bind="value: $data.topRows()[0].inputText" />
and
<span data-bind="text: $data.topRows()[1].text()" />
<input data-bind="value: $data.topRows()[1].inputText" />
JSFiddle DEMO

Javascript on Multiple DIVs

I am using a Wordpress Theme (Incipiens) that has a show/hide Javascript to show a map on the contact page http://demo.themedev.me/wordpress_themes/incipiens/contact-us/
I want to use this function on a page multiple times to show/hide galleries.
<div class="map">
<div class="map_top">
<hr class="toolbox toolbox1">
</div>
<hr class="vertical_sep0">
<a class="show_map" href="javascript:void(0)"></a>
<div class="map_container"><div class="thismap"><iframe>........</iframe></div>
</div>
I have this working but the call to the js opens all divs. I therefore put a unique div id round each gallery and slightly changed the javscript...
<div class="map">
<div class="map_top">
<hr class="toolbox toolbox1">
</div>
<hr class="vertical_sep0">
<div id="silestone">
<div class="map_container">
[show_gallery width="124" height="124" galleryid="527"][/show_gallery]
</div>
</div>
</div>
It works but very oddly, sometimes the right one opens, sometimes the wrong one...not sure what i'm doing wrong, should I just have one javascript call that contains the ID's to all divs? If so how do I do this?
Since you have not shown the actual script you use for toggling, I assume you mean something like this (taken from the page) -
function (){
$(this).toggleClass('hide_map');
$('.map_container').slideToggle(400);
}
I would change that to -
function unhide(id){
$(this).toggleClass('hide_map');
$('#' + id).find('.map_container').slideToggle(400);
}
Does that work?

Removing Breaks Before H1

I have a page that is like this:
<div id="contBody">
<br />
<br />
<!-- Maybe more, it's a variable number of <br /> that can appear -->
<h1 id="header">Test</h1>
</div>
Since the number of <br /> before the <h1> varies I and I want to remove them programmatically, how I can do it using jQuery?
If you want to remove all of them before the h1 elements, do this:
$('br + h1').prevAll('br').remove();
Using the next-adjacent-selector[docs], this will find all <h1> elements that are preceded by at least once <br> element.
Then it uses the prevAll()[docs] method to select the previous <br> elements, and the remove()[docs] method to remove them.
You can find them all with .prevAll() and .remove() them, like this:
$("#header").prevAll("br").remove();

Categories

Resources