Please can you tell me how to change this code so that the user can click on the first read me to see just the sugar text and separately click on the second read me to see the toast text.
It is driving me mad - the display texts have different names but using this code, both read me clicks show the toast comment.
I'm a non-techie with no code knowledge so please reply in simple language!
<p><script language="javascript">
function toggle() {
var ele = document.getElementById("sugar");
var text = document.getElementById("displayTextsugar");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "read more";
}
else {
ele.style.display = "block";
text.innerHTML = "hide";
}
}
</script> read sugar more <== click Here</p>
<p> </p>
<div style="display: none" id="sugar">
<h1>Sugar in my tea but none in coffee please</h1>
</div>
<script language="javascript">
function toggle() {
var ele = document.getElementById("toast");
var text = document.getElementById("displayTexttoast");
if(ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "read more";
}
else {
ele.style.display = "block";
text.innerHTML = "hide";
}
}
</script>
<p>read toast more <== click Here</p>
<div style="display: none" id="toast">
<h1>brown toast with marmite please</h1>
</div>
Since your 2 different codes, shared the same name, only the second one is being called (the first one gets overwritten).
It could be easier to use parameters to make this work, i added a sender and a target to your toggle function, that you can then use with sender (the element that is being clicked) and the target (the element that should hide, or show)
The only changes in your toggle method, is that i am using the parameter to get the elements, so you are now using 1 "code" for both clicks ;)
function toggle(sender, target) {
var ele = document.getElementById(target);
var text = sender;
if (ele.style.display == "block") {
ele.style.display = "none";
text.innerHTML = "read more";
} else {
ele.style.display = "block";
text.innerHTML = "hide";
}
}
<p>read sugar more <== click Here</p>
<p> </p>
<div style="display: none" id="sugar">
<h1>Sugar in my tea but none in coffee please</h1>
</div>
<p>read toast more <== click Here</p>
<div style="display: none" id="toast">
<h1>brown toast with marmite please</h1>
</div>
Related
I am trying to have 3 buttons and when the user clicks on one of them it displays the corresponding table and hides the other two.
I have tried using getting element by id and then setting the display to none or block based on what the current state of the table is.
<div onclick="myFunction()" id="u362" class="ax_default">
</div>
<div onclick="myFunction2()" id="u317" class="ax_default">
</div>
<script>
function myFunction() {
var a = document.getElementById("tbl");
var b = document.getElementById("tbl2");
if (a.style.display === "none") {
a.style.display = "block";
b.style.display = "block";
} else {
a.style.display = "none";
b.style.display = "none";
}
}
function myFunction2() {
var a = document.getElementById("tbl");
var b = document.getElementById("tbl2");
if (b.style.display === "none") {
a.style.display = "block";
b.style.display = "block";
} else {
a.style.display = "none";
b.style.display = "none";
}
}
</script>
The actual results are just really weird and have no resemblance to what I am trying to do.
You have not shown all of your code and are not explaining what you are wanting to do. Right now both of your functions are acting the same way, because you are operating on both tables each time.
If I can "guess" as to what you might want, it would be that when you click on button 1, then it will show table 1 and hide table 2. If you click on button 2 then it will show table 2 and hide table 1. If you look at your code below this is not what you are doing. You are showing both tables or hiding both tables in both instances.
To fix this you can do something like this:
<div onclick="myFunction()" id="u362" class="ax_default">
</div>
<div onclick="myFunction2()" id="u317" class="ax_default">
</div>
<script>
var a = document.getElementById("tbl");
var b = document.getElementById("tbl2");
function myFunction() {
a.style.display = "block";
b.style.display = "none";
}
function myFunction2() {
a.style.display = "none";
b.style.display = "block";
}
</script>
Notice you do not need an if/else in each function unless you are wanting the buttons to toggle on and off, in which case you may only need one button.
Here is a snippet of your code cleaned up. As #kojow7 noted above they basically do the same thing just based off 1 table or the other.
Things to note:
1) use slightly more descriptive variable names in your functions
2) create a css class that does your hiding so that you can simply test for that. when possible try to keep your js from handling styling
3) i replaced your if else with ternary if's. but in reality if all you are doing is toggling the class hidden then you could replace the if with a toggle.
4) instead of adding the onclick listener in your html it should be added via your js. try not to muddy your html with js concerns.
document.getElementById('u362').addEventListener('click', function () {
const tbl1 = document.getElementById("tbl1"),
tbl2 = document.getElementById("tbl2");
tbl1.classList.contains('hidden') ?
(tbl1.classList.remove('hidden'), tbl2.classList.remove('hidden')) :
(tbl1.classList.add('hidden'), tbl2.classList.add('hidden'));
});
document.getElementById('u317').addEventListener('click', function () {
const tbl1 = document.getElementById("tbl1"),
tbl2 = document.getElementById("tbl2");
tbl2.classList.contains('hidden') ?
(tbl1.classList.remove('hidden'), tbl2.classList.remove('hidden')) :
(tbl1.classList.add('hidden'), tbl2.classList.add('hidden'));
});
.hidden {
display: none;
}
<div id="u362" class="ax_default">u362</div>
<span id="tbl1" class="hidden">Table 1</span>
<span id="tbl2" class="hidden">Table 2</span>
<div id="u317" class="ax_default">u317</div>
With the information provided in your question, I suppose that your error comes when hiding or showing your tables. I think you have to change your code at those lines:
if (a.style.display === "none") {
a.style.display = "block";
b.style.display = "block";
} else {
a.style.display = "none";
b.style.display = "none";
}
for something like this:
b.style.display = "none";
if (a.style.display === "none") {
a.style.display = "block";
}
The new code will always hide table b when hitting button a. It doesn't matter the display status of table a because it doesn't really matter for hiding the rest of the tables. And only changes the display status of table a in case of being hidden.
You should do these changes also for each function of each button. I've also recommended to refactor all functions into a unique function and using it for all of the buttons you need.
I assume that the tables are invisible only after clicking the button, the appropriate table appears.
For future reference, please describe exactly what you want to use and you can use JsFiddle to show your code. Sometimes it is difficult to deduce from the descriptions what the writer had in mind :)
const buttons = document.querySelectorAll('button');
buttons.forEach(button => {
button.addEventListener('click', e => {
showTable(e.target.dataset.table);
});
});
function showTable(idTable) {
const tables = document.querySelectorAll('table');
tables.forEach(table => {
table.id === idTable ? table.style.display = 'block' : table.style.display = 'none';
});
}
table {
display: none;
}
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/skeleton/2.0.4/skeleton.min.css">
<button id="one" data-table="tb1">One</button>
<button id="two" data-table="tb2">Two</button>
<button id="tree" data-table="tb3">three</button>
<table id="tb1">
<tr>
<td>One</td>
</tr>
</table>
<table id="tb2">
<tr>
<td>Two</td>
</tr>
</table>
<table id="tb3">
<tr>
<td>Three</td>
</tr>
</table>
I had this code, that works ok to show/hide a second element by clicking the first one:
<script>
var acc = document.getElementsByClassName("movs-header");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("active");
var x = this.nextElementSibling;
if (x.style.display === "block") {
x.style.display = "none";
} else {
x.style.display = "block";
}
}
}
</script>
And this is the structure (they are repeating elements in a php system):
<div id="frm_container_[id]" class="movs-box">
<div class="movs-header">
some content here, clickable to show-hide the next sibling div
</div>
<div class="movs-body">
this content will show and hide
</div>
</div>
Now, I need to add this link inside a div with a class="movs-editlink", which has to be outside the movs-box div to refer the id "frm_container", in order to work.
Then the structure will be:
<div id="frm_container_[id]" class="movs-box">
<div class="movs-header">
some content here, clickable to show-hide the next sibling div
</div>
<div class="movs-body">
this content will show and hide
</div>
</div>
<div class="movs-editlink">[editlink label="edit" prefix="frm_container_"]</div> <!-- this div to show and hide along -->
(please don't mind the shortcode, it works fine)
What I need is to show/hide the last div with the same javascript code (when I click the "movs-header" div, but I fail to refer to "this.className", my guess was:
<script>
var acc = document.getElementsByClassName("movs-header");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function(){
this.classList.toggle("active");
var x = this.nextElementSibling;
var xedit = this.getElementsByClassName("movs-editlink").classname;
if (x.style.display === "block") {
x.style.display = "none";
xedit.style.display = "none";
} else {
x.style.display = "block";
xedit.style.display = "block";
}
}
}
</script>
I believe this is not working because the last div is outside the scope of "this", then I think I need to find the NEXT div in the structure with the class "movs-link" to be included in the display toggle, am I right? But I can't find how. Please help.
Based on your markup, rather than getElementsByClassName from this, do it with this.parentNode.nextElementSibling
var xedit = this.parentNode.nextElementSibling;
Or with jquery's nextUntil
var xedit = $(this).parent().nextUntil( "movs-editlink" );
My Goal: to have my div hidden on page load and show/hide the div with a button using only HTML/CSS/JavaScript.
I have set up a button in HTML and JavaScript to show/hide my div which works great when the div is visible on page load and not hidden using CSS. When I hide the div using CSS display: none; the div is hidden on page load but the button has to be clicked twice before the div becomes visible.
HTML:
<button class="btn btn-link" id="btnLink" onclick="hideLink()">Hide
Content</button> <br><br>
<div id="myLink">
<h1>Div content here</h1>
</div>
CSS:
#myLink {display: none;}
JavaScript:
function hideLink() {
var x = document.getElementById('myLink');
var b = document.getElementById('btnLink');
if (x.style.display === 'none') {
x.style.display = 'block';
b.childNodes[0].nodeValue="Hide Content";
} else {
x.style.display = 'none';
b.childNodes[0].nodeValue="Show Content";
}
}
You should check for !== 'block' rather than === 'none'
The value x.style.display is set to blank when we use none in the css as the css selector is what gets the none attribute than the element ( at lease that is what I understand ). So the check === none actually compares it will blank and return false ( x.style.display = '').
Now once we have set the value to block using JS the element's style.display property has a value which we can compare.
function hideLink() {
var x = document.getElementById('myLink');
var b = document.getElementById('btnLink');
if (x.style.display !== 'block') {
x.style.display = 'block';
b.childNodes[0].nodeValue = "Hide Content";
} else {
x.style.display = 'none';
b.childNodes[0].nodeValue = "Show Content";
}
}
#myLink {
display: none;
}
<button class="btn btn-link" id="btnLink" onclick="hideLink()">
Show Content
</button>
<br><br>
<div id="myLink">
<h1>Div content here</h1>
</div>
The first time the button is clicked, the element itself does not specifically have the style for display set. After your first if/then, then it does.
See here:
http://plnkr.co/edit/4peCJS1vhJskexqdLdKL?p=preview
var t = document.getElementById('output').innerText;
document.getElementById('output').innerText = JSON.stringify(x.outerHTML);
corrected it with another if...
function hideLink() {
var x = document.getElementById('myLink');
var b = document.getElementById('btnLink');
if (x.style.display === ''){
x.style.display = 'none';
}
if (x.style.display === 'none') {
x.style.display = 'block';
b.childNodes[0].nodeValue="Hide Sitemap Section";
} else {
x.style.display = 'none';
b.childNodes[0].nodeValue="Show Sitemap Section";
}
}
I am new to all of this so please excuse any misuse of terms.
I have added a toggle to my wordpress site to hide long sections of text and it seems to work just fine.
I wanted to add an arrow that flips depending on whether the section is open or not. My problem is the arrow flips back and forth no matter what section is toggled and I don't know how to fix that.
JS:
function toggle(id) {
var element = document.getElementById(id);
var text = document.getElementById("arrow");
if (element) {
var display = element.style.display;
if (display == "none") {
element.style.display = "block";
text.innerHTML = "▲";
} else {
element.style.display = "none";
text.innerHTML = "▼";
}
}
}
HTML:
<h4>Procedure</h4>
<h4 onclick="toggle('telnetPrint')">Telnet<a id="arrow">▼</a></h4>
<div id="telnetPrint" style="display: none;">
<ol>
<li>fjkldsaj;lkf</li>
</ol>
<h4 onclick="toggle('telnetPrint')">Hide -</h4>
</div>
<p> </p>
<h4 onclick="toggle('linuxPrint')">Linux Computer▼</h4>
<div id="linuxPrint" style="display: none">
<ol>
<li>fjkldsjfklsa</li>
</ol>
<h4 onclick="toggle('linuxPrint')">Hide -</h4>
</div>
If anyone can help, I'd greatly appreciate it.
p.s. no jQuery please
It looks like you are calling the same "arrow". You only have arrow set for Telnet. You can add an arrow as well to linuxPrint. I would ID them as :
<a id="arrowtelnetPrint"></a>
and
<a id="arrowlinuxPrint"></a>
That way you can use the "id" to change the correct one. Here is the jsfiddle:
https://jsfiddle.net/ezdrhLtr/2/
This will have the full code, with minor adjustments, that toggle both arrows.
var text = document.getElementById("arrow");
you are referencing an element with id 'arrow'. Everytime the toggle function is executed, you will flip the element with id 'arrow'. What you can do is pass a boolean value to know if its to be flipped or not
<h4 onclick="toggle('telnetPrint',true)">Telnet<a id="arrow">▼</a></h4>
and in your script
function toggle(id, flipOrNot) {
var element = document.getElementById(id);
var text = document.getElementById("arrow");
if (element) {
var display = element.style.display;
if (display == "none") {
element.style.display = "block";
if(flipOrNot){
text.innerHTML = "▲";
}
} else {
element.style.display = "none";
if(flipOrNot){
text.innerHTML = "▼";
}
}
}
}
for other elements, you can do
<h4 onclick="toggle('linuxPrint',false)">Hide -</h4>
to prevent flip
So I looked at other questions and I found an answer that was chosen on this link:
Toggle (show/hide) element with javascript
This below was the following function that works in the answer to change the display.
function toggle(id) {
var element = document.getElementById(id);
if (element) {
var display = element.style.display;
if (display == "none") {
element.style.display = "block";
} else {
element.style.display = "none";
}
}
}
I tried that in my code, but it's not working. I've attached a link to the JSFiddle at the end or this post.
I have a parent div with the id of #activities. It contains multiple children, but the important ones are the li,p, and div which has an id as #suggestion_input. Below is the HTML.
HTML
<div id="activities" class="info_container">
<h1>Our Activities</h1>
<div class="contain">
<ul>
<li>Activity 1</li>
<li>Activity 2</li>
<li>Activity 3 </li>
<li>Activity 4 </li>
<li>Activity 5</li>
<li>Activity 6 </li>
<li>Activity 7</li>
<li>Your Suggestions</li>
</ul>
<p>
Bacon ipsum dolor sit amet ribeye tenderloin meatball, chuck andouille beef ribs jerky ...
</p>
<div id="suggestion_input">
<label for="name" >Your Name</label>
<input type="text" id="name" name="name">
<label for="email">Email</label>
<input type="email" id="email" name="email">
<label for="suggestions">Suggestions</label>
<textarea id="suggestions" name="suggestions" rows="39"></textarea>
</div>
When the user clicks the last li in the ul called "Your Suggestions", then the p will have display set to none and the #suggestion_input will have display of inline-block. Currently, their css is set to inline-block and none respectively.
CSS
#activities p{
display:inline-block;
width:500px;
vertical-align:top;
margin-top:20px;
margin-left:20px;
background:#FFFDA1;
}
#suggestion_input{
display:none;
margin-left:150px;
vertical-align:top;
margin-top:20px;
text-align:center;
}
And then this is my javascript which I think reflects the answer in the link except that it isn't a function.
Javascript - This code is part of an addEventListener. Event is a "click".
if(e.target.innerText === 'Your Suggestions'){
var para = document.getElementById('activities').querySelector('p');
var display = para.style.display;
/* if you uncomment this, then the following code will work
outside of the if display == 'inline-block' condition
para.style.display = 'none';
suggestion_input.style.display = 'inline-block';
*/
if(display == 'inline-block'){
// This code will not work
para.style.display = 'none';
suggestion_input.style.display = 'inline-block';
console.log('works');
}
}else{
if(display == 'none'){
display = "inline-block";
}
}
}
When I click, nothing happens. Is the error because of the condition in the if statement of "display == 'none'" ?
Here is the JSfiddle: http://jsfiddle.net/a4t7w/1/
There is a couple of error in your js , I listed them in the comment , 4 in totoal
document.getElementById('activities').addEventListener("click",function(e){
// SKIP THIS CODE, THE ERROR LIES BELOW
// 1. put the var outside of the if/else
var para = document.getElementById('activities').querySelector('p');
var display = para.style.display;
// THIS WAS WHERE THE ERROR OCCURS
if(e.target.innerText === 'Your Suggestions'){
if(display = 'inline-block'){ // 2. it should be "=" instead of "=="
para.style.display = 'none';
suggestion_input.style.display = 'inline-block';
console.log('works');
}
}else{
if(display = 'none'){
suggestion_input.style.display = 'none'; // 3. add in suggestion display none
para.style.display = 'inline-block'; // 4. "para.style.display" instead of "display"
}
}
}
});
A working demo : http://jsfiddle.net/a4t7w/7/
So now when you click suggestion , the from show up, than if you click the activity, the paragraph come back in, from disappear
Okay, so to start, part of your problem is with the understanding that para.style.display equals inline-block like is set in your style sheet. Unfortunately in this usage Javascript is accessing your inline styles as defined with the element itself and not what you are defining with external CSS.
So this statement: if(display == 'inline-block') never returns true because display is actually set to "". If you aren't already, get familiar with Firebug for Firefox. It does wonders for helping debug this kind of stuff.
Another thing is here: if(e.target.innerText === 'Your Suggestions'). Instead of innerText you should use innerHTML or textContent. The innerText property is an IE thing.
Now, to solve your problem! I see you are attaching the click event to the <div> element that holds your <ul> element. If you only need this click event you function on your "Suggestions" <li> then I would recommend you isolate that particular element when attaching your listener.
Change your HTML and JS:
<li id="suggestionToggle">Your Suggestions</li>
...
document.getElementById('suggestionToggle').addEventListener("click",function(e) ...
Next you can rewrite your Javascript to test for the presence of "" or inline-block when setting your styles on the <p> element. Here's an updated version of your code:
document.getElementById('activities').addEventListener("click",function(e)
{
var suggestion_input = document.getElementById('suggestion_input');
var para = document.getElementById('activities').querySelector('p');
var light_green = document.getElementById('activities').querySelector('.light_green');
if(light_green){
light_green.style.backgroundColor="red";
light_green.className = "";
e.target.style.backgroundColor = '#0DFFB9';
e.target.className = 'light_green';
} else {
e.target.style.backgroundColor = '#0DFFB9';
e.target.className = 'light_green';
}
if(e.target.innerHTML == 'Your Suggestions') {
var display = para.style.display;
if(display == 'inline-block' || display == "") {
// This code will not work ** It will now! **
para.style.display = 'none';
suggestion_input.style.display = 'inline-block';
} else {
if(display != "inline-block") {
para.style.display = "inline-block";
suggestion_input.style.display = "none";
}
}
} else {
para.style.display = "inline-block";
suggestion_input.style.display = "none";
}
});
JS Fiddle to see the toggle in action is here: http://jsfiddle.net/RyUz5/8/
Hope that helps!
EDIT: Enabled proper toggling that I accidentally stripped out as noted by yancie.
Read this line carefully:
/*
if you uncomment this, then the following code will work
outside of the if display == 'inline-block' condition
para.style.display = 'none';
suggestion_input.style.display = 'inline-block';
*/
now all you have to do is uncomment this line:
para.style.display = 'none';
suggestion_input.style.display = 'inline-block';