For loop loses variable value after first loop [duplicate] - javascript

This question already has answers here:
How to add two strings as if they were numbers? [duplicate]
(20 answers)
Closed 5 years ago.
Apologies if my question title is not accurate, I couldn't think how to phrase it.
var options = [2,3,4]
// select drop down
var select = document.getElementById("itemSet");
for (var i = 0; i < options.length; i++) {
var opt = options[i];
var el = document.createElement("option");
el.text = opt;
el.value = opt;
select.add(el);
}
// define arrays
var arrActivity = ["alien monster", "man in business suit levitating", "fencer", "horse racing", "skier", "snowboarder", "golfer", "surfer", "rowboat", "swimmer"];
var arrFood = ["grapes", "melon", "watermelon", "tangerine", "lemon", "banana", "pineapple", "red apple", "green apple", "pear"];
var arrObjects = ["skull and crossbones", "love letter", "bomb", "hole", "shopping bags", "prayer beads", "gem stone", "hocho", "amphora", "world map"];
var arrLetters = ["letter a", "letter b", "letter c", "letter d", "letter e", "letter f", "letter g", "letter h", "letter i", "letter j"];
// format the array data for output into the textarea
function boom() {
var e = document.getElementById("itemSet");
var myCols = e.options[e.selectedIndex].value;
console.log(myCols);
var arrNew = [];
if (document.getElementById("radioActivity").checked) {
y = arrActivity;
} else if (document.getElementById("radioFood").checked) {
y = arrFood;
} else if (document.getElementById("radioObjects").checked) {
y = arrObjects;
} else if (document.getElementById("radioLetters").checked) {
y = arrLetters;
}
for (var i = 0; i < y.length; i += myCols) {
arrNew.push(
y.slice(i, i + myCols)
);
}
// set the textarea output
op = JSON.stringify(arrNew, null, 4);
document.getElementById('output').value = op;
}
<form onSubmit="return false;">
<label class="radio-inline">
<input type="radio" name="myArray" id="radioActivity" value="valActivity"> Activity
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioFood" value="arrFood"> Food
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioObjects" value="arrObjects"> Objects
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioLetters" value="arrLetters"> Letters
</label>
<select class="form-control" id="itemSet" name="itemSet"></select>
<button onClick="boom();"> Check Radio </button>
<textarea id="output" class="form-control" style="width:95%; height:500px; margin-top:20px;"></textarea>
</form>
When I click the "Check Radio" button, I want to reformat the arrays into chunks using this for loop:
for (var i = 0; i < y.length; i+=myCols) {
arrNew.push(
y.slice(i, i+myCols)
);
}
If I submit the form with a select value of e.g. 2 then the array is reformatted as:
[
[
"alien monster",
"man in business suit levitating"
],
[
"fencer",
"horse racing",
"skier",
"snowboarder",
"golfer",
"surfer",
"rowboat",
"swimmer"
]
]
Instead of in chunks of 2:
[
[
"alien monster",
"man in business suit levitating"
],
[
"fencer",
"horse racing"
],
[
"skier",
"snowboarder"
],
[
"golfer",
"surfer"
],
[
"rowboat",
"swimmer"
]
]
This CodePen demonstrates the issue: https://codepen.io/paperknees/pen/boXjXW
I can't work out what I'm doing wrong.

myCols is a string, therefore
y = 0;
myCols = "2"
//first iteration
y += myCols // "2"
//second iteration:
y += myCols // "22"
To solve this, add an unary plus operator:
var myCols = +e.options[e.selectedIndex].value;

You'll get it here -
while (y.length > 0)
arrNew.push(y.splice(0, myCols))
console.log(arrNew);
That's it!

Related

Arrays keys with a radio button

I'm trying to access my random array keys with a radio button on each of them
I want to place the radio button only on the array
of the allQuestions[index].anwsers keys and it has 3 indexes keys.
I'm couldn't make it and this my work so far.
const allQuestions = [{
question: "Which of them is from compton",
anwsers: ["Nas", "Tupac", "Omarion", "Kendick"],
correctAnswer: "Kendrick"
},
{
question: "founder of HipHop",
anwsers: ["Tupac", "Eazy E", "Kendick", "Bambata"],
correctAnswer: "Bambata"
},
{
question: "Who won BET Hip Hop Album 2018",
anwsers: ["Kendrick", "Bruno", "Jay Z", "Drake"],
correctAnswer: "Kendrick",
},
{
question: "Best Female HipHop Art 2018",
anwsers: ["Azelia", "Nicki", "Cardi_b", "Mama Rap"],
correctAnswer: "Nicki"
}
]
function render() {
var index, unique;
var print = '<ul>';
for (i = 0; i < allQuestions.length; i++) {
index = Math.floor(Math.random() * allQuestions.length);
}
var showQuiz = document.getElementById('showQuiz');
var showAnswers = document.getElementById('showAnswers');
showQuiz.style.color = 'red';
showQuiz.innerHTML = allQuestions[index].question;
showAnswers.innerHTML = allQuestions[index].anwsers;
// I'm tryin to ue sthe unshift method here but it' not workin
showAnswers.unshift('<input type="radio" value="allQuestions.anwsers[]');
}
<div id="question" style="text-align: center"> Quiz</div>
<button type="button" onclick="render()">Next Quiz</button>
<div id="showQuiz"></div>
<div id="showAnswers"></div>
Appears we are trying to use the Array function unshift() on a DOM element. What i believe you are trying to do is create a list of radio buttons for each answer in your allQuestions.answers[], this can be done with a for loop, or a map like so:
Edit to add answersAsHtml and join(" ") this improves readability and joins each array element with a space instead of the default comma.
const allQuestions = [{
question: "Which of them is from compton",
anwsers: ["Nas", "Tupac", "Omarion", "Kendick"],
correctAnswer: "Kendrick"
},
{
question: "founder of HipHop",
anwsers: ["Tupac", "Eazy E", "Kendick", "Bambata"],
correctAnswer: "Bambata"
},
{
question: "Who won BET Hip Hop Album 2018",
anwsers: ["Kendrick", "Bruno", "Jay Z", "Drake"],
correctAnswer: "Kendrick",
},
{
question: "Best Female HipHop Art 2018",
anwsers: ["Azelia", "Nicki", "Cardi_b", "Mama Rap"],
correctAnswer: "Nicki"
}
]
function render() {
var index, unique;
var print = '<ul>';
for (i = 0; i < allQuestions.length; i++) {
index = Math.floor(Math.random() * allQuestions.length);
}
var showQuiz = document.getElementById('showQuiz');
var showAnswers = document.getElementById('showAnswers');
var answersAsHtml = allQuestions[index].anwsers.map(ans => `<input type="radio" value="${ans}">${ans}</input>`).join(" ");
showQuiz.style.color = 'red';
showQuiz.innerHTML = allQuestions[index].question;
showAnswers.innerHTML = answersAsHtml;
}
<div id="question" style="text-align: center"> Quiz</div>
<button type="button" onclick="render()">Next Quiz</button>
<div id="showQuiz"></div>
<div id="showAnswers"></div>
You are trying to write into an html element, that's not an array. You are probably looking for something more like this.
showAnswers.innerHTML = allQuestions[index].anwsers.map(function (answer){
return '<input type="radio" name="answers" value="' + answer + '"/>' + answer
})

Filtering output of json with multiple if statements

I have a json that has keys of ver, price and level.
In my html there are 3 radio buttons for ver, and 3 checkboxes for each price and level. I have attached an change event that will only output or filter the sample obj which can be a combination depending on the checkedbox of price and level.
am I filtering my result right?
What I'm expecting to be my output when checked: If I choose ver = 1 ,price = 1, and level = 1 it should output 2 objects.
var obj = {
"sample" :[
{"ver": "1", "price":"1", "level": 1},
{"ver": "0", "price":"2", "level": 2},
{"ver": "1", "price":"1", "level": 1},
{"ver": "1", "price":"3", "level": 3},
{"ver": "1", "price":"1", "level": 1},
{"ver": "0", "price":"2", "level": 1},
{"ver": "1", "price":"3", "level": 3}
]
}
var priceArr = [];
var levelArr= [];
var out;
var price = $("input[name='price']").change(function(){
var checked = $(this).val();
if ($(this).is(':checked')) {
priceArr.push(checked);
return priceArr;
}else {
priceArr.splice($.inArray(checked, priceArr),1);
return priceArr;
}
});
var level = $("input[name='level']").change(function(){
var checked = $(this).val();
if ($(this).is(':checked')){
//convert string val to int
levelArr.push(parseInt(checked));
return levelArr;
}else{
levelArr.splice($.inArray(checked, levelArr),1);
return levelArr;
}
});
$("input[type='radio'][name='ver'], input[name='price'], input[name='level']").change(function(){
var r = $("input[type='radio'][name='ver']:checked").val();
var p = price;
var l = level;
sortResult(r,p,l);
});
function sortResult(r,p,l){
p.sort();
l.sort();
if(r != undefined && p != "" && l != ""){
obj.sample.map(function(i){
if (i.ver == r){
//filter the price in which they belong to
if( i.price == p[0] && i.price == p[1] && i.price == p[2]){
//output price that is filtered
console.log(i.price)
if(i.level == l[1] || i.level || l[2] || i.level == l[2] ){
//output level that is filtered
console.log(i.level)
}
}
}
output = '<div>Ver ' + i.ver +'</div>';
output += '<div>Price' + i.price +'</div>';
output += '<div>Level' + i.level +'</div>';
});//map
}//if
}//sortResult
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
<form >
<div><input type="radio" name="ver" value="0" >All</div>
<div><input type="radio" name="ver" value="1" >ver1</div>
<div><input type="radio" name="ver" value="2" >ver2</div>
</form>
</div>
<div>
<form >
<div><input type="checkbox" name="price" value="1" >Price 1</div>
<div><input type="checkbox" name="price" value="2" >Price 2</div>
<div><input type="checkbox" name="price" value="3" >Price 3</div>
</form>
</div>
<div>
<form >
<div><input type="checkbox" name="level" value="1" >Level 1</div>
<div><input type="checkbox" name="level" value="2" >Level 2</div>
<div><input type="checkbox" name="level" value="3" >Level 3</div>
</form>
</div>
<div class="output"></div>
var obj = {
"sample" :[
{"ver": "1", "price":"1", "level": 1},
{"ver": "0", "price":"2", "level": 2},
{"ver": "1", "price":"1", "level": 1},
{"ver": "1", "price":"3", "level": 3},
{"ver": "1", "price":"1", "level": 1},
{"ver": "0", "price":"2", "level": 1},
{"ver": "1", "price":"3", "level": 3}
]
};
function getCheckedBoxes(chkboxName) {
var checkboxes = document.getElementsByName(chkboxName);
var checkboxesChecked = [];
for (var i=0; i<checkboxes.length; i++) {
if (checkboxes[i].checked) {
checkboxesChecked.push(checkboxes[i].value);
}
}
// Return the array if it is non-empty, or null
return checkboxesChecked.length > 0 ? checkboxesChecked : [];
}
$("input").change(function(){
var r = $("input[type='radio'][name='ver']:checked").val();
var ver = r == 0 ? null : r - 1;
sortResult(ver,getCheckedBoxes("price"),getCheckedBoxes("level"));
});
function sortResult(r,p,l){
obj.sample.map(function(i){
if (p.indexOf(i.price) >= 0 && l.indexOf(i.level+"") >= 0) {
if (r && i.ver == r){
console.log(i);
} else if (!r) {
console.log(i);
}
}
});
}
Truthfully there was a lot of edge cases that your code wasn't handling, p and l were functions instead of arrays. Even those weren't forming correctly.

Javascript - How to compare the element value inside event listener to the the array element?

Once again, I need your input on the problem that I am having now.
I am creating a MCQ trivia where I encounter a logic problem.
Although for this example, I purposely set the answer are B, C or D, the result div will always show the result is correct – although I only set an event listener on button A but no answer.
Based on my code below, am I comparing the element value with the array answer value the right way?
var exam=[{
"question": "Q1?",
"option": ["A","B","C","D"],
"answer": "B"
},{
"question": "Q2?",
"option": ["A","B","C","D"],
"answer": "C"
},{
"question": "Q3?",
"option": ["A","B","C","D"],
"answer": "D"
},{
"question": "Q4?",
"option": ["A","B","C","D"],
"answer": "B"
},{
"question": "Q5?",
"option": ["A","B","C","D"],
"answer": "C"
}]
//dom selector
var container = document.getElementById('container');
var questionEl = document.getElementById('question');
//for the answer display
var opt1 = document.getElementById('opt1');
var opt2 = document.getElementById('opt2');
var opt3 = document.getElementById('opt3');
var opt4 = document.getElementById('opt4');
//for the input button click
var opta = document.getElementById('opta');
var optb = document.getElementById('optb');
var optc = document.getElementById('optc');
var optd = document.getElementById('optd');
//
var button = document.querySelectorAll('button');
var nextButton = document.getElementById('help1Button');
var resultCont = document.getElementById('result');
//display question and answer
function displayQues() {
//select one question randomly from the quiz array
var i = Math.floor(Math.random() * exam.length);
questionEl.textContent=exam[i].question;
opt1.textContent = exam[i].option[0];
opt2.textContent = exam[i].option[1];
opt3.textContent = exam[i].option[2];
opt4.textContent = exam[i].option[3];
};
//load this when page load
displayQues();
opta.addEventListener("click", function() {
if (opt1.value === exam.answer) {
displayQues();
resultCont.textContent = "Correct!";
} else {
resultCont.textContent = "Incorrect!";
}
});
<div id="container">
<div class="title"> Alan Koh Exam Question</div>
<div id="question"> </div>
<button id="opta"> A: <span id="opt1"></span> </button>
<button id="optb"> B: <span id="opt2"></span> </button>
<button id="optc"> C: <span id="opt3"></span> </button>
<button id="optd"> D: <span id="opt4"></span> </button>
<div id="result"></div>
The problem with your current code is opt1.value === exam.answer. Both these properties are undefined. opt1.value because it's not set (I believe you want opt1.textContent) and exam.answer because exam is an array. You get Correct! always since undefined === undefined is true
Your issue can be solved by returning the current displayed question and using it for comparison.
var exam = [{
"question": "Q1?",
"option": ["A", "B", "C", "D"],
"answer": "B"
}, {
"question": "Q2?",
"option": ["A", "B", "C", "D"],
"answer": "C"
}, {
"question": "Q3?",
"option": ["A", "B", "C", "D"],
"answer": "D"
}, {
"question": "Q4?",
"option": ["A", "B", "C", "D"],
"answer": "B"
}, {
"question": "Q5?",
"option": ["A", "B", "C", "D"],
"answer": "C"
}]
//
//dom selector
var container = document.getElementById('container');
var questionEl = document.getElementById('question');
//for the answer display
var opt1 = document.getElementById('opt1');
var opt2 = document.getElementById('opt2');
var opt3 = document.getElementById('opt3');
var opt4 = document.getElementById('opt4');
//for the input button click
var opta = document.getElementById('opta');
var optb = document.getElementById('optb');
var optc = document.getElementById('optc');
var optd = document.getElementById('optd');
//
var button = document.querySelectorAll('button');
//
var nextButton = document.getElementById('help1Button');
var resultCont = document.getElementById('result');
//display question and answer
function displayQues() {
//select one question randomly from the quiz array
var i = Math.floor(Math.random() * exam.length);
questionEl.textContent = exam[i].question;
opt1.textContent = exam[i].option[0];
opt2.textContent = exam[i].option[1];
opt3.textContent = exam[i].option[2];
opt4.textContent = exam[i].option[3];
return exam[i]; // Return the chosen exam variable
};
//load this when page load
var currentExam = displayQues(); // Store the chosen exam
opta.addEventListener("click", function() {
if (opt1.textContent === currentExam.answer) {
currentExam = displayQues(); // Store the new question
resultCont.textContent = "Correct!";
} else {
resultCont.textContent = "Incorrect!";
}
});
<div id="container">
<div class="title"> Alan Koh Exam Question</div>
<div id="question"> </div>
<button id="opta"> A: <span id="opt1"></span> </button>
<button id="optb"> B: <span id="opt2"></span> </button>
<button id="optc"> C: <span id="opt3"></span> </button>
<button id="optd"> D: <span id="opt4"></span> </button>
<div id="result"></div>
Here is the jsfiddle link with the corrected code.
You have to loop through exam and compare the correct question and answer.

Getting the value of "on" for radio buttons

var allQuestions = [{
question1: "What is 1 + 1?",
choices: ["1", "2", "3", 4],
correctAnswer: ["2"]
}, {
question2: "What is 2 + 2?",
choices: ["6", "2", "3", 4, ],
correctAnswer: ["4"]
}, {
question3: "What is 3 + 3?",
choices: ["3", "6", "9", 12],
correctAnswer: ["6"]
}];
var newArray = shuffleArray(allQuestions);
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function appendQuestions(number) {
if (newArray == "undefined" || newArray == "null" || newArray.length == 0) {
document.getElementById("questionForm").innerHTML = "Complete!";
} else {
for (i = 0; i < 4; i++) {
$("#questionForm").append("<input name='question' type='radio'>" +
JSON.stringify(newArray[0].choices[i]) + "</input>")
}
}
}
$(function() {
$("#questionList").empty();
appendQuestions();
newArray.shift();
})
function isCorrectAnswer() {
checkedVal = $("input[type=radio][name=question]:checked").val();
if (checkedVal == newArray[0].correctAnswer) {
alert("Correct!");
} else {
alert("Wrong!");
}
alert(checkedVal);
}
$("#submitButton").click(function() {
isCorrectAnswer();
$("#questionForm").empty();
appendQuestions();
newArray.shift();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
<section id='questions'>
<form id="questionForm">
</form>
<div style='clear:both'></div>
<input id='submitButton' type='button' value='Submit'>
</section>
</div>
First off, sorry for the amount of code pasted. I have no idea if I'm missing some small bug or if I'm just writing the wrong code, so I figured it would be best to post all of it.
I am trying to get the value of a radio button. In the isCorrectAnswer function the first 2 lines are to determine the value of the radio button that is currently checked. The problem is when I alert the value of the radio button, it just says "on". I have searched for the last hour trying to figure out what this means or how to fix it and could not find a thing.
I apologize if this is a stupid question or if it has already been answered.
You have to change this line :
$("#questionForm").append("<input name='question' type='radio'>" +
JSON.stringify(newArray[0].choices[i]) + "</input>");
To :
$("#questionForm").append("<input name='question' type='radio' value='" +
JSON.stringify(newArray[0].correctAnswer[i]) + "' />"+JSON.stringify(newArray[0].choices[i]));
Hope this helps.

Javascript quiz won't recall previous answers

I'm new to programming and Javascript, and as a first project I'm trying to create a small quiz application.
I've included it here on jsfiddle:
http://jsfiddle.net/ben220/L0y43q3d/
I've tried to design the program so that the user is able go back through the quiz and change any of their answers before they click to get their final score at the end. The user checks the radio button next to their chosen answer. When the user clicks 'next' to move on (or 'back' to revisit a previous question) their answer is passed to an array called 'choices', and this array will store all of the user's answers as they go through the quiz.
I've managed to write the program so that previous answers can be saved and recalled but there is one annoying problem. If the user checks a particular radio button more than once in the quiz, the program will only remember the first one. For example: if I am on Question 4 and check the radio button for Answer 2, I might decide to go back to the previous question and change my answer, before moving on. So I go back to Question 3 and change the answer to Answer 2. I have now chosen the same radio button on two consecutive questions. But now when I click 'next' to move onto Question 4 again I find that no radio button is checked, my answer was not saved.
I've really tried to fix this by myself but I do not understand what I've done wrong. If anyone out there could suggest a solution I'd be grateful. If any further clarification is needed let me know. Sorry if my explanation or my code is confusing - I'm still a newbie with Javascript! Many thanks.
<div id="container">
<div id="quizArea">
<h2 id="theQuestion">Question 1</h2>
<fieldset id="myForm">
<label><input type="radio" name="question" value="0" />Answer 1</label><br/>
<label><input type="radio" name="question" value="1" />Answer 2</label><br/>
<label><input type="radio" name="question" value="2" />Answer 3</label><br/>
<label><input type="radio" name="question" value="3" />Answer 4</label><br/>
<label><input type="radio" name="question" value="4" />Answer 5</label><br/>
</fieldset>
<div class="mini_container"><button id="next">Next</button></div>
<button id="getScore">Get Score</button>
<div class="mini_container"><button id="back">Back</button></div>
<p id="submitError">Please choose an answer before proceeding to the next question</p>
<div id="score"></div>
</div>
</div>
Javascript:
var module = (function () {
var theQuestions = [{question: "Question 1", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 2}, {question: "Question 2", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 4}, {question: "Question 3", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 1}, {question: "Question 4", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 1}, {question: "Question 5", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 3}],
score = 0,
title = document.getElementById("theQuestion"),
back = document.getElementById("back"),
next = document.getElementById("next"),
radioButtons = document.getElementById("options"),
options = document.getElementsByTagName("label"),
radios = document.getElementsByTagName("input"),
submitError = document.getElementById("submitError"),
scoreBtn = document.getElementById("getScore"),
scoreBox = document.getElementById("score"),
currentQ = 0;
var choices = [];
function getRadioInfo() {
var decision = null;
for(var i = 0; i < radios.length; i += 1) {
if(radios[i].checked) {
decision = radios[i].value;
}
}
return decision;
}
back.onclick = function() {
var decision = getRadioInfo();
choices[currentQ] = decision;
currentQ -= 1;
if(currentQ === 0) {
back.style.display = "none";
}
if(currentQ < theQuestions.length) {
next.style.display = "block";
scoreBtn.style.display = "none";
}
title.innerHTML = theQuestions[currentQ].question;
var a = 0;
for(var i = 0; i < options.length; i += 1) {
options[i].innerHTML = '<input type="radio" name="question" value="' + a + '" />' + theQuestions[currentQ].choices[a];
a += 1;
}
restorePreviousAnswer();
};
var restorePreviousAnswer = function() {
for(var i = 0; i < choices.length; i += 1) {
if(choices.indexOf(choices[i]) == currentQ) {
var prev = choices[i];
}
}
for(var x = 0; x < radios.length; x += 1) {
if (radios[x].value == prev) {
radios[x].checked = true;
}
}
};
next.onclick = function() {
var decision = getRadioInfo();
if(decision == null) {
submitError.style.display = "block";
return;
} else {
submitError.style.display = "none";
}
choices[currentQ] = decision;
currentQ += 1;
if(currentQ > 0) {
back.style.display = "block";
}
if(currentQ == theQuestions.length - 1) {
next.style.display = "none";
scoreBtn.style.display = "block";
}
title.innerHTML = theQuestions[currentQ].question;
var a = 0;
for(var i = 0; i < options.length; i += 1) {
options[i].innerHTML = '<input type="radio" name="question" value="' + a + '" />' + theQuestions[currentQ].choices[a];
a += 1;
}
restorePreviousAnswer();
};
scoreBtn.onclick = function() {
hideAll();
scoreBox.innerHTML = "You scored " + score + " out of " + theQuestions.length;
};
})();
I cleaned up your restorePreviousAnswer function to just if (choices[currentQ] != null) radios[choices[currentQ]].checked = true. Another part of the problem was that null values were being inserted in your array of answers when you went back before selecting a radio button.
jsFiddle example

Categories

Resources