Hiding text after clicking on something different - javascript

My goal here is to have the riddles in my page to be shown one at a time. My instructor has shown us a way using JavaScript variables. in my HTML I have two riddles shown as an example:
<h5>Question 1</h5>
<p onClick="revealAnswer('answer1','When it is turned into the teacher', 0)">When is homework not homework?</p><br/>
<span id="answer1" class="answers"></span><br/>
<hr>
<h5>Question 2</h5>
<p onClick="revealAnswer('answer2','An Umbrella', 1)">What goes up when rain comes down?</p><br/>
<span id="answer2" class="answers"></span><br/>
<hr>
in an external JavaScript, I have this code to expose the answers:
var isVisible = new Array();
isVisible[0] = false;
isVisible[1] = false;
function revealAnswer(answerId, answer, indexNum){
if(isVisible[indexNum]==false){
document.getElementById(answerId).innerHTML = answer;
isVisible[indexNum]=true;
console.log(answerId);
}
else{
document.getElementById(answerId).innerHTML = "";
isVisible[indexNum]=false;
}
My goal is when you click on "question 1", it shows you the answer, but when you click on "question 2" the answer to "question 1" goes away, and shows you the answer to "question 2". I am entirely new to JavaScript, but my best guess is to either add a new function, add an additional "if" or "else" to the existing "revealAnswer" function. What are your best recommendations?

var isVisible = new Array();
isVisible[0] = false;
isVisible[1] = false;
function revealAnswer(answerId, answer, indexNum){
if(isVisible[indexNum]==false){
var spanAnswer = document.querySelectorAll(".answers");
for(i=0;i < spanAnswer.length ; i++){
spanAnswer[i].innerHTML = '';
isVisible[i] = false;
}
document.getElementById(answerId).innerHTML = answer;
isVisible[indexNum]=true;
console.log(answerId);
}
else{
document.getElementById(answerId).innerHTML = "";
isVisible[indexNum]=false;
}
}
<h5>Question 1</h5>
<p onClick="revealAnswer('answer1','When it is turned into the teacher', 0)">When is homework not homework?</p><br/>
<span id="answer1" class="answers"></span><br/>
<hr>
<h5>Question 2</h5>
<p onClick="revealAnswer('answer2','An Umbrella', 1)">What goes up when rain comes down?</p><br/>
<span id="answer2" class="answers"></span><br/>
<hr>
Here you go
document.querySelectorAll will not work in IE
here is the traditional code which will work in IE as well
function revealAnswer(answerId, answer, indexNum){
if(isVisible[indexNum]==false){
var spanAnswer = document.getElementsByTagName("span");
for(i=0;i < spanAnswer.length ; i++){
if(spanAnswer[i].id == "answer"+(i+1)){
spanAnswer[i].innerHTML = '';
}
}
document.getElementById(answerId).innerHTML = answer;
isVisible[indexNum]=true;
console.log(answerId);
}
else{
document.getElementById(answerId).innerHTML = "";
isVisible[indexNum]=false;
}
}

Jquery would make your life much easier. Go take a look at this : http://www.w3schools.com/JQuery/jquery_hide_show.asp
To hide or show elements using Jquery you only have to do is give an id to your HTML elements as follows : <button id="hide">ButtonHide</button>
And then call an event on that button in JQuery :
$(document).ready(function(){
$("#hide").click(function(){
$("#hide").hide();
});
});
The #is a direct reference to the ID in your html making it easy to access it from your jquery.
If you wanted to hide the answer using jquery all you would have to do is :
Give and ID to it:
<p id="Question1Answer">blablabla</p>
<p id="Question2">blablabla</p>
Set an event on question 2
$(document).ready(function(){
$("#Question2").click(function(){
$("#Question1Answer").hide();
});
});
To make it clearer how to inlcude this into your code go check the link I posted at the top of the answer
Go check on the following link how to include Jquery : http://www.w3schools.com/jquery/jquery_get_started.asp

Here's a different approach. It toggles the visibility of the current answer, and then it hides all the other answers.
This simplifies the HTML, because you don't need any IDs. nextElementSibling grabs the answer that goes with the clicked question.
It also simplifies the JavaScript, because you don't need a global array to hold the visibility of each answer.
function revealAnswer(p) {
var ans= p.nextElementSibling,
all= document.querySelectorAll('.answers');
ans.classList.toggle('visible');
for(var i = 0 ; i < all.length ; i++) {
if(all[i] !== ans) all[i].classList.remove('visible');
}
}
.answers {
display: none;
}
.visible {
display: block;
}
<h5>Question 1</h5>
<p onClick="revealAnswer(this)">When is homework not homework?</p>
<p class="answers">When it is turned into the teacher</p>
<hr>
<h5>Question 2</h5>
<p onClick="revealAnswer(this)">What goes up when rain comes down?</p>
<p class="answers">An Umbrella</p>
<hr>

I know two ways to do this. One would be to put invisible radiobuttons on the page and to write the questions in their labels, but that's quite a peculiar hack. Let's do something simpler.
Instead of storing the state of all answers, you could just store which one is visible. Then, when you click on a question, the currently visible answer is hidden and the new answer is shown.
var visibleAnswer = null;
function revealAnswer(answerId, answer){
var answerElement = document.getElementById(answerId);
if(visibleAnswer) {
visibleAnswer.innerHTML = "";
}
if(!visibleAnswer || visibleAnswer.id !== answerElement.id) {
answerElement.innerHTML = answer;
visibleAnswer = answerElement;
} else {
answerElement.innerHTML = "";
visibleAnswer = null;
}
}
<h5>Question 1</h5>
<p onClick="revealAnswer('answer1','When it is turned into the teacher')">When is homework not homework?</p><br/>
<span id="answer1" class="answers"></span><br/>
<hr>
<h5>Question 2</h5>
<p onClick="revealAnswer('answer2','An Umbrella')">What goes up when rain comes down?</p><br/>
<span id="answer2" class="answers"></span><br/>
<hr>

Related

How to get the value of a specific element in a div when clicked?

I'm making a search engine program. People can ask questions and it will be listed in a different div. People can then click a question listed to answer it, and the answer (and that particular question) will be listed in another div.
But my code only shows the last question entered in the answer list. So if there are 3 questions and a user answered the first one, the expected output is:
Question 1?
Ans: Answer 1
But the actual output is:
Question 3?
Ans: Answer 1
function separate()
{
var question = document.createElement("p");
question.innerHTML = document.getElementById("qInput").value;
document.getElementById("stackDisplay").appendChild(question);
question.addEventListener("click", answerBox);
}
function answerBox(ques)
{
document.getElementById("answerBox").style.display = "block";
}
var i =1;
function collectAns() {
if(event.key === 'Enter') {
var quest = document.getElementById("qInput").value;
var ans = document.getElementById("ansSpace").value;
document.getElementById("ansDisplay").innerHTML += i+") "+quest+"<br> Ans: "+ans+"<br><br>";
document.getElementById("answerBox").style.display = "none";
i+=1;
}
}
<div class="search">
<input type="text" placeholder="Search.." name="search" id="qInput">
<button type="submit" onclick="separate()">
<i class="fa fa-search"></i>
</button>
</div>
<div class="stack">
<span id="stackDisplay">
<center><b><u> LIST OF QUESTIONS</u></b></center>
<button id="close" onmouseover="clo()"> × </button>
</span>
<button onmouseover="list()"> ☰ </button>
</div>
<div class="ans">
<span id="ansDisplay">
<center><b><u> LIST OF ANSWERS</u></b></center>
<button id="closeans" onmouseover="closeans()"> × </button>
</span>
<button onmouseover="listans()">
<i class="fa fa-commenting-o"></i>
</button>
</div>
<div id="answerBox">
<center><b> Write your answer:</b></center>
<button id="closeans" onmouseover="closeansbox()"> × </button>
<textarea id="ansSpace" placeholder="Your answer here..." onkeydown="collectAns()"></textarea>
</div>
I know it's because of var quest = document.getElementById("qInput").value; so it only takes the last question, but I don't know what to write instead of this.
I tried adding question.addEventListener("click", function(){collectAns(ques)}); in the separate() but it prints undefined instead of the question.
I tried adding var q = document.getElementById("stackDisplay").children; in the collectAns() but I don't know which question they'll click so I can't give the index, so I wrote q[this] when printing, and it still gives undefined.
What should I do to make it show the question? (without jquery or php if possible, just html, css, javascript)
I removed unnecessary stuff to answer the question.
The idea is to call collectAns with the question as argument. To do that you can use the bind method.
As you are adding eventListners, you will need to remove old ones to prevent them to be executed too. The difficulty to remove old ones is that you don't know their name, they are anonymous because of the use of bind. You could store them in an array but it is simplier to clone the node, which do not clone the eventlistners attached to it.
function separate() {
var question = document.createElement("li");
question.innerHTML = document.getElementById("qInput").value;
document.getElementById("stackDisplay").appendChild(question);
question.addEventListener("click", answerBox);
}
function answerBox() {
const answerbox = document.getElementById("answerBox");
const question = this.innerText;
answerbox.querySelector('.ques').innerText = question;
// find textarea, clone it and remove it
// this is to remove any eventListener from it.
const textarea = answerbox.querySelector('textarea');
const new_textarea = textarea.cloneNode();
textarea.remove();
// add new eventListner with question as parameter
new_textarea.addEventListener('keydown', collectAns.bind(null, this.innerText));
answerbox.appendChild(new_textarea);
// display answer box
answerbox.style.display = "block";
}
var i = 1;
function collectAns(ques) {
if (event.key === 'Enter') {
var ans = document.getElementById("ansSpace").value;
document.getElementById("ansDisplay").innerHTML += i + ") " + ques + "<br> Ans: " + ans + "<br><br>";
document.getElementById("answerBox").style.display = "none";
i += 1;
}
}
<div class="search">
<input type="text" placeholder="Question.." name="search" id="qInput">
<button type="submit" onclick="separate()">
add
</button>
</div>
<h4>LIST OF QUESTIONS:</h4>
<ul id="stackDisplay"></ul>
<h4>LIST OF ANSWERS</h4>
<ul id="ansDisplay"></ul>
<div id="answerBox">
<div>Write your answer to question "<span class="ques"></span>":</div>
<textarea id="ansSpace" placeholder="Your answer here..."></textarea>
</div>

How do I change the text displayed on a website?

What I want to do is change one word of text on my webpage to run through a list of words.
ie:
<p>My favorite hobby is <u>fishing</u>!</p>
Where "fishing" would change after about 2 secs to the next word of a list of hobbies.
The closest example I've found is this
<div id="welcome">
<h3>Welcome, welcome, welcome!</h3>
<h3>Hang around a bit (for a surprise).</h3>
</div>
function ChangeIt() {
var newcontent = '
<h1>Click here ' +
'for a web page with more of the same.</h1>';
WriteContentIntoID("welcome",newcontent);
}
setTimeout("ChangeIt()",20000);
But I can't get it to work either.
Here's something simple using setInterval():
<p>My favorite hobby is <span id="ch">fishing</span>!</p>
<script>
var activities = ['eating', 'burping','coding'];
var i=0;
setInterval(function(){
document.getElementById("ch").innerHTML = activities[i];
if (i < activities.length-1) {
i++;
} else {
i=0;
}
}, 1000);
</script>
FIDDLE Demo
EDIT: changed to make it loop forever.
Use this:
<p>My favorite hobby is <u>fishing</u>!</p>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript">
function getnewword(){
return "me";// fix this section with getting new word!
}
function ChangeIt() {
$("p u").html(getnewword());
setTimeout("ChangeIt()",2000);
}
setTimeout("ChangeIt()",2000);
<script>
Programming is cool. You should try with some beginner JavaScript tutorials like http://www.w3schools.com/js/.
You must encapsulate your script with script tag and you must use selectors (like document.getElementById).
This is the full code:
<div id="welcome">
<h3>Welcome, welcome, welcome!</h3>
<h3 id="hobby">Hang around a bit (for a surprise).</h3>
</div>
<script>
// we start with 0
var currentHobby = 0;
function ChangeIt() {
// hobbies array
var hobbies = ["fishing", "eating", "drinking", "programming"];
// we save the current hobby in hobbyString and increment the currentHobby number
var hobbyString = hobbies[currentHobby];
currentHobby++;
// if the currentHobby number is too big, we start with 0 again
if(currentHobby >= hobbies.length) {
currentHobby = 0;
}
document.getElementById("hobby").innerHTML = "My favourite hobby is " + hobbyString;
}
setInterval("ChangeIt()",2000);
</script>
HTML PART
I am going to <span id="changingtext">InitialWord</span>
Javascript Part - You Need JQuery and call the following on onLoad
var texts = ["France", "Italy", "Ireland", "Wales"];
var count = 0;
function updateval() {
$("#changingtext").text(texts[count]);
count < 4 ? count++ : count = 0;
}
setInterval(updateval, 2000);
Working JS Fiddle Link Click Here
Click on the Javascript setting button on JsFiddle to check the settings put in use.

How to remove a div element at a specific index using pure javascript

I dynamically create a form. There is an add line button that adds a new line that includes a delete line button.
I originally wrote this in angular, and I was able to pass "$index" into the function to remove the specific line.
I am now rewriting my code in pure js, and my question is: How can I go about implementing this same functionality?
The example for deleting elements by index as per your requirement can be found in this jsfiddle : https://jsfiddle.net/ChaitanyaMunipalle/9z73rfjx/2/. I assume you will take care of adding lines & delete buttons dynamically. It contains only deletion.
As you have not given any code, I assumed the html would look like the below one:
<div id="lines">
<div class="line-item">
<input type="text" name="line-value"/> <button class="delete-line">Delete</button>
</div>
<div class="line-item">
<input type="text" name="line-value"/> <button class="delete-line">Delete</button>
</div>
<div class="line-item">
<input type="text" name="line-value"/> <button class="delete-line">Delete</button>
</div>
</div>
You have to add event listeners to delete buttons. And you have to use closure to save the index of the button clicked.
var deleteItem = function(index) {
var divElements = document.getElementsByClassName("line-item");
for (var i = 0; i < divElements.length; i++) {
if (i == index) {
divElements[i].parentNode.removeChild(divElements[i]);
break;
}
}
};
var deleteButtons = document.getElementsByClassName("delete-line");
for (var i = 0; i < deleteButtons.length; i++) {
(function(index){
deleteButtons[i].addEventListener('click', function() {
deleteItem(index);
}, false);
})(i);
}
I don't quite understand your setup, but removing a div is just
parentNode.removeChild(yourDiv)
If you only have the parentNode but know the index of the div you want to delete, then
parentNode.removeChild(parentNode.children[i])
`<div id="div1">
<p id="p1">This is a paragraph.</p>
<p id="p2">This is another paragraph.</p>
</div>
<script>
var parent = document.getElementById("div1");
var child = document.getElementById("p1");
parent.removeChild(child);
</script>`
This a example in jsfiddle:
https://jsfiddle.net/AlfonsoRamirez9/ttj1sLo5/
I hope help you :)

HTML multiple choice quiz

I am working on an HTML quiz recently, which is a page shown before a company page we use in my department. If the user answers correctly, then he can get the link to the page he needs to work.
However, when he answers wrongly, he gets a message and he can answer again, but the "Wrong Answer" that he got previously is still shown. That is what i don't want to happen.
The code of the quiz.js file is shown below. Also i post the HTML code of the answer section.
$(document).ready(function()
{
$("#results").click(function() {
if (!$("input[#name=q1]:checked").val())
{
alert("You're not done yet!");
}
else
{
var cat1name = "1";
var cat11name = "None";
var cat1 = ($("input[#name=q1]:checked").val() != "b"); // correct answer
var cat11 = (!cat1); var categories = [];
if (cat1) { categories.push(cat1name) };
if (cat11) { categories.push(cat11name) };
var catStr = 'You answered the following questions incorrectly: ' + categories.join(', ') + '';
$("#categorylist").text(catStr);
$("#categorylist").show("slow");
if (cat1) { $("#category1").show("slow"); };
if (cat11) { $("#category11").show("slow"); };
{ $("#closing").show("slow"); };
}
});
});
<div id="results">
Answer
</div>
<div id="category1">
<p>
<strong>Wrong answer!</strong>
</p>
</div>
<div id="category11">
<p>You answered correctly!</p>
<p><a href="somelink</a></p>
</div>
</div>
</body>
</html>

Loop for in a .mousemove function

My problem is here :
$(document).mousemove(function(e){
for(i = 1; i < 7; i++){
var tt = document.getElementById("tooltip"+i);
document.getElementById("help"+i).onmousemove=function(event){
if(tooltip == 1){
$(tt).css({left:e.pageX+5, top:e.pageY+5});
tt.style.visibility= "visible";
}
}
document.getElementById("help"+i).onmouseout=function(event){
tt.style.visibility= "hidden";
}
}
});
With this code, the <div id="tooltip"+i> is showing right next to the mouse, but it's always the last "tooltip"+i, in this case tooltip6 which is showing.
I managed that to work by simply removing the loop for, and writing 6 times that next, each with a different i :
$(document).mousemove(function(e){
var i = 1;
var tt = document.getElementById("tooltip"+i);
document.getElementById(i).onmousemove=function(){
if(tooltip == 1){
$(tt).css({left:e.pageX+5, top:e.pageY+5});
tt.style.visibility= "visible";
}
}
document.getElementById(i).onmouseout=function(){
tt.style.visibility= "hidden";
}
});
In this case, it does what i want. It shows the tooltip1, when the mouse is over the <div id=help1>, and (e.g.) tooltip4 over the <div id=help4> if i use var i = 4.
I can obviously just write more and more like that as i add more tooltips, but i really don't understand why the adding of the loop is not working here.
My HTML code with the tooltips :
<span id=tooltip1>Health points of the rock. Each time it gets to 0, you get some stone</span>
<span id=tooltip2>Deeper you go, harder it is.</span>
<span id=tooltip3>Power of the Pickaxe.</span>
<span id=tooltip4>Go To the Village.</span>
<span id=tooltip5>Go To the Blacksmith.</span>
<span id=tooltip6>You can sell stone in the village.</span>
And HTML code with some of the help :
<div class=liststat id=help1>HP : <span id=hp>0</span></div>
<br>
<br>
<div class=liststat id=help2>Deep Level : <span id=lvlrock>0</span>m</div>
<br>
<br>
<div class=liststat id=help3>Pick Power : <span id=pickpower>0</span></div>
<br>
<br>
<div class=liststat id=help6>Stone : <span id=nstone>0</span></div>
Okay, so after reading the comment, i edited my code to make it simpler, and not adding any other listener, to not crash the script :
$(document).mousemove(function(e){
if(tooltip == 1){
var i = e.target.id;
var tt = document.getElementById("tooltip"+i);
tt.style.visibility = "visible";
$(tt).css({left:e.pageX+5, top:e.pageY+5});
document.getElementById(i).onmouseout=function(){
tt.style.visibility= "hidden";
}
}
});

Categories

Resources