Looping through array using a button - javascript

Ok, in essence I want to create a short quiz that has a next and previous button. I want to loop through two arrays, questions and choices, and have a score at the end. I have read chapters on the DOM and Events and it is just not clicking apparently.
Really I need a little bit of code that shows a concrete example of how to manipulate the DOM. What I have so far are only the arrays, and a function declaring that x is in fact getting my element by id. haha.
Sorry I don't have more code to give. I tried to attach the id to a paragraph, and then get it by it's id and document.write the array, but that replaces the button. If you run the code below you'll see what I'm saying.
<!DOCTYPE html>
<html>
<head>
<title>Bom</title>
</head>
<body>
<input type="button" value="Iterate" id="myButton" onclick="iter_onclick()">
<p id="qArray">Some Text</p>
<script>
var qArray = ["Who is my dog?", "who is the prez?", "Who is my girlfriend?", "Who am I?"];
var cArray = [["Bill","Billy", "Arnold", "Tyler"],["Oz"," Buffon","Tupac","Amy"],["Tony Blair","Brack Osama","Barack Obama","Little Arlo"],["Emma Stone","Tony the Tiger","","The Smurf Girl"]];
function iter_onclick () {
var x = document.getElementById("qArray");
document.write("Hello World");
}
</script>
</body>
</html>`
Like I said, this is my first attempt at truly manipulating the DOM, and I know what I want to do. I just don't know how to do it. I am understanding all the syntax and events and objects and such. But, I'm not really sure how to apply it. Also, no Jquery. I want to know how to create applications with Javascript and then work my way into Jquery. Thanks people.

This will loop through your questions, hope this helps you to proceed.
var qArray = ["Who is my dog?",
"who is the prez?",
"Who is my girlfriend?",
"Who am I?"];
var cArray = [
["Bill", "Billy", "Arnold", "Tyler"],
["Oz", " Buffon", "Tupac", "Amy"],
["Tony Blair", "Brack Osama", "Barack Obama", "Little Arlo"],
["Emma Stone", "Tony the Tiger", "Amy Dahlquist", "The Smurf Girl"]
];
var index = 0;
function iter_onclick() {
//if this is the last question hide and displays quiz ends
if (index >= qArray.length) {
document.getElementById('qArray').innerHTML = '<div>Quiz End, Thank you</div>'
document.getElementById('myButton').style.visibility = 'hidden ';
return false;
}
var html = ' <div> ' + qArray[index] + ' </div> <div>';
for (var i = 0; i < cArray[index].length; i++) {
html += '<label><input type="radio" name="ans" value="'
+ cArray[index][i] + '"/ > ' + cArray[index][i] + ' </label>';
}
html += '</div > ';
document.getElementById('qArray').innerHTML = html;
index++;
}

Here's a very basic example you can work from. This modifies the existing DOM items. You cannot use document.write() on a document that is already loaded or it will clear everything you have and start over and it's not the most efficient way to put content into the DOM.
This example has a number of fields on the page, it loads a question and then checks the answer when you press the next button.
HTML:
<div id="question"></div>
<input id="answer" type="text"><br><br>
<button id="next">Next</button> <br><br><br>
Number Correct So Far: <span id="numCorrect">0</span>
Javascript (in script tag):
var qArray = ["Who is my dog?", "who is the prez?", "Who is my girlfriend?", "Who am I?"];
var cArray = [["Bill","Billy", "Arnold", "Tyler"],["Oz"," Buffon","Tupac","Amy"],["Tony Blair","Brack Osama","Barack Obama","Little Arlo"],["Emma Stone","Tony the Tiger","Amy Dahlquist","The Smurf Girl"]];
var questionNum = -1;
var numCorrect = 0;
function loadQuestion() {
++questionNum;
if (questionNum >= qArray.length) {
alert("all questions are done");
} else {
document.getElementById("question").innerHTML = qArray[questionNum];
document.getElementById("answer").value = "";
}
}
loadQuestion();
function checkAnswer() {
var answer = document.getElementById("answer").value.toLowerCase();
var allowedAnswers = cArray[questionNum];
for (var i = 0; i < allowedAnswers.length; i++) {
if (allowedAnswers[i].toLowerCase() == answer) {
return true;
}
}
return false;
}
document.getElementById("next").addEventListener("click", function(e) {
if (checkAnswer()) {
++numCorrect;
document.getElementById("numCorrect").innerHTML = numCorrect;
loadQuestion();
} else {
alert("Answer is not correct");
}
});
Working demo: http://jsfiddle.net/jfriend00/gX2Rm/

Related

How can I print the contents of all fields on submission in this JS quiz?

I've made a JS/HTML quiz, and I want all the words entered in the text fields to be displayed at the bottom of the page on submission.
The error is in the showResults function, which isn't working the way I intend it to. I'm a beginner at using the querySelector but what I want to do is use the variable answerContainers to store only the .answers part of quizContainer, and then the toSearch variable to store only the values of submitted answers from answerContainers. Finally, I want to print the contents of toSearch to the screen in string form.
Here's my code:
var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');
var myQuestions = ["1. What is your dream destination?",
"2. If you could have one wish right now, what would it be?",
"3. What are your career goals?",
"4. Name an artist whose music you enjoy.",
"5. What are your hobbies?",
"6. Name a few public figures you admire.",
"7. Who is your favourite actor?",
"8. Which family member do you love the most?",
"9. If you could have any animal as your pet, what would it be?",
"10. Name a movie you’ve been planning to watch but haven’t yet had the time.",
"11. What kind of weather do you like the most?",
"12. Name a book or movie that you’ve always loved."];
function showQuestions(myQuestions, quizContainer){
var output = [];
for(var j = 0; j <= 11; j++)
{
var answer = '<label>'
+ '<input type="text" name=""+j+"" id=""+j+"">'
+ '</label>';
output.push(
'<div class="question">' + myQuestions[j] +'</div>'
+ '<div class="answers">' + answer + '</div>'
);
}
quizContainer.innerHTML = output.join("");
}
function showResults(questions, quizContainer, resultsContainer){
var answerContainers = quizContainer.querySelectorAll('.answers');
var toSearch = [];
for(var i=0; i <= 11; i++){
toSearch.push(answerContainers[i].querySelector('input[name=""+i+""]')).value;
}
resultsContainer.innerHTML = toSearch.toString();
}
<!DOCTYPE html>
<html>
<head>
<h2>Interests Questionnaire</h2>
<h4>Answer in 1-5 words each.</h4>
<br>
<link rel="stylesheet" href="test.css">
</head>
<body>
<div id="quiz"></div>
<div id="results"></div>
<script src = "test.js"></script>
<script> showQuestions(myQuestions, quizContainer); </script>
<input type="button" value = "Submit" id = "submit" onclick = "showResults(myQuestions, quizContainer, resultsContainer)">
</body>
</html>
In its current form, the code gives the error "JavaScript error: TypeError: quizContainer is null on line 52". What am I doing wrong and how can I fix it?
There were a few errors in your code - a misplaced parens, that sort of thing. I found/fixed the ones that were preventing success and got the answers to display in a string. You should be able to take it from here.
List of errors:
(1) toSearch.append() is not correct - use toSearch.push()
(2) You cannot have name or id attributes that begin with a number.
(3) This line was incorrect in a few places:
toSearch.append(answerContainers[i].querySelector('input[name=""+i+""]')).value;
should be:
toSearch.push(answerContainers[i].querySelector('input[name="a'+i+'"]').value);
var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');
var myQuestions = ["1. What is your dream destination?",
"2. If you could have one wish right now, what would it be?",
"12. Name a book or movie that you’ve always loved."];
function showQuestions(myQuestions, quizContainer){
var output = [];
for(let j=0; j <= myQuestions.length-1; j++){
var answer = `
<label>
<input type="text" name="a${j}" id="a${j}">
</label>`;
output.push(
`<div class="question">${myQuestions[j]}</div>
<div class="answers">${answer}</div>`
);
}
quizContainer.innerHTML = output.join("");
}
function showResults(myQuestions, quizContainer, resultsContainer){
var answerContainers = quizContainer.querySelectorAll('.answers');
// console.log(answerContainers);
var toSearch = [];
for(var i=0; i <= myQuestions.length-1; i++){
//console.log(answerContainers[i].querySelector('input[name="a'+i+'"]').value);
toSearch.push(answerContainers[i].querySelector('input[name="a'+i+'"]').value);
var x = 0;
}
resultsContainer.innerHTML = JSON.stringify(toSearch);
//userAnswer = (answerContainers[i].querySelector('input[name=question'+i+']:checked')||{}).value;
}
showQuestions(myQuestions, quizContainer);
<h2>Interests Questionnaire</h2>
<h4>Answer in 1-5 words each.</h4>
<br>
<div id="quiz"></div>
<div id="results"></div>
<input type="button" value = "Submit" id = "submit" onclick = "showResults(myQuestions, quizContainer, resultsContainer)">
There are a few problems here:
You have h2, br tags in the <head> of your page. Don't do that. Those kind of tags belong in the <body> tag of the page.
That error is telling you that quizContainer is null - if you look at the line of your code that is declaring quiz container, it is attempting to grab an element by ID - specifically 'quiz'. It can't find it. Possibly because you don't have a <body> tag.
Also - in your showResults function, you have a loop. Outside of that loop, is this line:
userAnswer =(answerContainers[i].querySelector('input[name=question'+i+']:checked')||{}).value;
You are trying to access the answerContainers array with the variable i outside of the loop where i is defined.

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.

jQuery to take value from input and check if it's right. If so, it should post how many are correct

I am trying to take the value of an input and check if the answer is right I don't want it to just say that it's correct, I want it to look through and post how many are correct with numbers, and how many are incorrect. I had problems with posting the code below so here is JSFiddle: http://jsfiddle.net/BBaughn/4rww1mhy/
This one has the better jQuery in it. This one has the worse one: http://jsfiddle.net/BBaughn/cqsah8aw/
(and because it tells me I can't post because jsfiddle.net needs to be accompanied by code, here is 2 questions of my HTML)
<p>Who is the best programmer that you know? (type only the first name)</p>
<input type="textbox" id="best-programmer" placeholder="(e.g. Jonathan)"><br><br>
<!--Answer: BRENDON-->
<p>What element starts with the letter "K"</p>
<input type="textbox" id="element" placeholder="(Hint: periodic table)">
<br>
<br>
<!--Answer: POTASSIUM-->
Change
var answers = [progam = 'BRENDON',
element = 'KRYPTON',
planet = 'PLUTO',
island = "GREENLAND",
prague = "CZECH REPUBLIC"
];
var total = 0;
for (var i=0; i < answers.length; i++) {
total += answers[i];
var post = '<div class="posting-score">Score: '+ answers[i] +'</div>';
$(post).appendTo('.scores');
}
to
var answers = [program, 'BRENDON',
element, 'KRYPTON',
planet, 'PLUTO',
island, "GREENLAND",
prague, "CZECH REPUBLIC"
];
var total = 0;
for (var i = 0; i < answers.length-1; i+=2) {
total += (answers[i] == answers[i+1]);
}
var post = '<div class="posting-score">Score: '+ total +'</div>';
$(post).appendTo('.scores');
Fiddle: http://jsfiddle.net/Drakes/cqsah8aw/1/
You have to set a section in your html code and use the syntax: $(#"id of element").val(); thats how you get the value of an input or any other element.

How to reset a page, and how to score a win in hangman

So I have my hangman page essentially working, but Im looking to tweak it.
Firstly, my failed guesses are adding up correctly, and the alert pops up when you reach 6 failed try's. The problem im having at the moment is I cant figure out how to reset the page. I've tried some renditions of "$(':reset');" but none have worked for me so far. Currently after the alert pops up you click ok, and then can continue guessing, which is obviously not working as intended.
Secondly, I don't know how to recognize a win in code form. When you play the game, you can guess all the correct letters, but upon guessing the final letter, nothing actually happens. I need to find a way for it to recognize that all letters have been identified.
Thank you ahead of time!
JSfiddle - http://jsfiddle.net/9mxxwu0o/
Html -
<body>
<form id="form" name="form" method="post" action="">
<input type="button" id="but" value="Start"/>
<div id="hangman-jquery">
<div id="word"></div>
<div id="alpha"></div>
</div>
</form>
<div id="win">
</div>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="hangman.js"></script>
</body>
JS -
function hangman(word) {
var trys = 0;
var guess = 0;
var alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
$.each(alpha.split(''), function(i, val) {
$('#alpha').append($('<span class="guess">' + val + '</span>'));
});
$.each(word.split(''), function(i, val) {
$('#word').append($('<span class="letter" letter="' + val + '">-</span>'));
});
$('.guess').click(function() {
var count = $('#word [letter=' + $(this).text() + ']').each(function() {
$(this).text($(this).attr('letter'));
}).length;
$(this).removeClass('guess').css('color', (count > 0 ? 'green' : 'red')).unbind('click');
if (count > 0) {
$('#win').text("Correct Guess");
} else if (count <= 0) {
trys++;
$('#win').text("You have tried to guess the word and failed " + trys + " times");
}
if (trys == 6) {
alert("You have guessed six times, you lose");
trys = 0;
$("#win").text("");
$(this).val('');
}
});
}
$(document).ready(function() {
$('#but').click(function() {
var options = new Array("DOG", "CAT", "BAT", "HORSE", "TIGER", "LION", "BEAR", "LIGER", "DOOM", "SPIDER", "TREES", "LAPTOP");
var random = 1 + Math.floor(Math.random() * 12);
hangman(options[random]);
});
});
This is where functions come in handy: reusable blocks of code.
Fixed fiddle: http://jsfiddle.net/2azzvscs/
(Scroll down and "Run Snippet" to try it out right inside of stack overflow)
In this case you should move code for starting the game to a separate function (I called it newGame() in example below) that can be called when you need to start a new game after a win or loss.
Also made it detect win condition and ask user to play again.
I also recommend using html() instead of append(); I converted your code to use an array of strings that gets joined into a single DOM fragment that will replace the previous content. Usually, appending to DOM reflows the document, and so you want to do this as little as possible in a loop. (doing it this way also allows your game state to start over without reloading the page from server, which is totally unnecessary in this case).
function hangman(word) {
var trys = 0;
var guess = 0;
var alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
var strBuilder = [];
$.each(alpha.split(''), function (i, val) {
strBuilder[strBuilder.length] = '<span class="guess">' + val + '</span>';
});
$('#alpha').html(strBuilder.join(''));
strBuilder = [];
$.each(word.split(''), function (i, val) {
strBuilder[strBuilder.length] = '<span class="letter" letter="' + val + '">-</span>';
});
$('#word').html(strBuilder.join(''));
$('.guess').click(function () {
var count = $('#word [letter=' + $(this).text() + ']').each(function () {
$(this).text($(this).attr('letter'));
}).length;
$(this).removeClass('guess').css('color', (count > 0 ? 'green' : 'red')).unbind('click');
if (count > 0) {
$('#win').text("Correct Guess");
} else if (count <= 0) {
trys++;
$('#win').text("You have tried to guess the word and failed " + trys + " times");
}
if ($("#word").text() === word) {
if (window.confirm("You win! Play again?")) {
newGame();
$("#win").text("");
}
}
if (trys == 6) {
alert("You have guessed six times, you lose");
$("#win").text("");
newGame(); // begin new game
}
});
}
function newGame() {
$("#win").text("");
var options = new Array("DOG", "CAT", "BAT", "HORSE", "TIGER", "LION", "BEAR", "LIGER", "DOOM", "SPIDER", "TREES", "LAPTOP");
var random = 1 + Math.floor(Math.random() * 12);
hangman(options[random]);
}
$(document).ready(function () {
$('#but').click(newGame);
});
.guess
{
font-family: "Segoe UI", Arial, Sans-serif;
font-size: 14px;
padding: 5px;
}
.guess:hover
{
background-color: #eee;
cursor: pointer;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<body>
<form id="form" name="form" method="post" action="">
<input type="button" id="but" value="Start" />
<div id="hangman-jquery">
<div id="word"></div>
<div id="alpha"></div>
</div>
</form>
<div id="win"></div>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script src="hangman.js"></script>
</body>
Just add this after your loose message:
$("#word, #alpha").html("");
Like this:
if (trys == 6) {
alert("You have guessed six times, you lose");
$("#word, #alpha").html(""); // This
trys = 0;
$("#win").text("");
$(this).val('');
}
Here is WORKING code:
http://jsfiddle.net/9mxxwu0o/3/
I just added couple easy things to it, no tinkering or making it run bit faster, if you want that, then nothingisnecessary provided you an great answer.
Perhaps you could simply reload the page to reset the game?
location.reload();

How do I fill a UL with array items using jQuery?

Trying to use jQuery to place array values into a ul of radio buttons.
HTML
<div class="quizWindow">
<h1>The Bridge Of Death</h1>
<div id="question"></div>
<form>
<ul id = "choices">
</ul>
</form>
<div id = "quizMessage"></div>
<div id = "result"></div>
<div id = "nextButton"><span>Start Quiz</span></div>
<br>
</div>
JS
var allQuestions = [{question: "What, is your name?", choices: ["Sir Lancelot the brave", "Sir Galahad the brave", "Sir not appearing in this film"], correctAnswer: 1}, {question: "What, is your quest?", choices: ["To seek the holy grail", "To dream the impossible dream", "To get back on the horse"], correctAnswer: 1 }, {question: "What is the airspeed velocity of an unladen swallow?", choices: ["16mph", "I don't know that!", "What do you mean; an african or a european swallow?"], correctAnswer: 3}];
$(document).ready(function () {
//Start Quiz, show first set of questions
$('#nextButton').click(function () {
$('#question').text(allQuestions[0].question);
for (var i = 0; i <= allQuestions.length; i++) {
$.each(allQuestions, function(i, question) {
var $ul = $('<ul/>'); //make a new ul for this question
//iterate through each choice for this question
$.each(question.choices, function (i, choices) {
//add the choice to the ul
$ul.append('<li><label><input type="radio" name="question' + i + '" value="' + choices + '"> ' + choices + '</label></li>');
});
//add the new ul to the form
$('.choices').append($ul);
});
}
});
});
I've got the question showing up in the HTML, but none of the choices below it. I think this is a problem of my HTML formatting in the jQuery but I'm not seeing it.
You can easily use $.each to iterate through objects and arrays. Please note I've changed the name for each input to be 'question'+question number. This is because you obviously can't have multiple questions that all have the same name.
//iterate through each question
$.each(allQuestions, function(i, question){
var $ul = $('<ul/>'); //make a new ul for this question
//iterate through each choice for this question
$.each(question.choices, function(ii, choice){
//add the choice to the ul
$ul.append('<li><label><input type="radio" name="question'+i+'" value="'+choice+'"> '+choice+'</label></li>');
});
//add the new ul to the form
$('.choices').append($ul)
});
Yes you will need to loop. Try something like this.
var $ul = $('ul.yourUl');
for(var i = 0; i < allQuestions.length; i++) {
var $li = $("<li></li>"); //Do whatever is needed to make this li
$ul.append($li);
}

Categories

Resources