Quiz in Javascript with Arrays? - javascript

So, I'm trying to create a quiz in Javascript, by using number ids of the text inputs in HTML, then running a for loop and if to compare the input to the answer in an answers array.
In Html:
<form>
China<input type="text" id="0"><br>
France<input type="text" id="1"><br>
Japan<input type="text" id="2"><br>
<input type="button" id="submitt" value="submit">
</form>
In Javascript:
var answers = ["Beijing", "Paris", "Tokyo",];
$("#submitt").click(function() {
var totalYes=0;
function checkAnswers() {
for(var i=0; i<answers.length; i++) {
var userAnswer = document.getElementById(i);
if(userAnswer.value===answers[i]) {
totalYes++;
}
}
}
alert(totalYes);
checkAnswers();
});
But the code doesn't add 1 to the variable totalYes (questions correct). I've tried totalYes+=1 and totalYes + 1 as well. The alert of totalYes shows up as 0 everytime.
But I know that's the only part not working because when I change totalYes to correct and incorrect alerts, it works:
var answers = ["Beijing", "Paris", "Tokyo",];
$("#submitt").click(function() {
var totalYes=0;
function checkAnswers() {
for(var i=0; i<answers.length; i++) {
var userAnswer = document.getElementById(i);
if(userAnswer.value===answers[i]) {
alert("Correct!");
} else {
alert("Incorrect!");
}
}
}
alert(totalYes);
checkAnswers();
});
Please help?

jsFiddle Demo
NOTE: Because totalYes is a global variable you'll want to reset it to 0 after you show how many the user got right
JS
var answers = ["Beijing", "Paris", "Tokyo", ];
var totalYes = 0;
$("#submitt").click(function (e) {
checkAnswers();
alert(totalYes);
e.preventDefault();
});
function checkAnswers() {
for (var i = 0; i < answers.length; i++) {
var userAnswer = document.getElementById(i);
if (userAnswer.value === answers[i]) {
totalYes++;
}
}
}
Side Note: This would be the easy test to cheat on...simply view source and you can see the JavaScript answers. Perhaps you should toLower() the text and then md5 or sha1 the answers. Then simply do the same when checking them
jsFiddle Demo
var answers = ["feecd450f4886bbed257e222fcf7609cbdd57a64", "3c4bd4d0d0d1e076ce617723edd6a73afc9126ab", "0f1aae8b8398c20f81e1c36e349a7880c9234c63", ];
var totalYes = 0;
$("#submitt").click(function (e) {
checkAnswers();
alert(totalYes);
e.preventDefault();
totalYes = 0;
});
function checkAnswers() {
for (var i = 0; i < answers.length; i++) {
var userAnswer = document.getElementById(i);
if (Sha1.hash(userAnswer.value.toLowerCase()) === answers[i]) {
totalYes++;
}
}
}
Note: You will see some sha1 code this code was taken from http://www.movable-type.co.uk/scripts/sha1.html#code
This will make it impossible without a rainbow table to simply view source to get the answer, I hope this is helpful in some small way
Extra note: Because you are using a for loop for each question, any answer can be put into any textbox. Example: Paris can be put in the textbox next to China and you'll still get 1 right.

The order of calling functions is not correct. You are first alerting your variable and then start counting correct answers. Change to:
$("#submitt").click(function() {
var totalYes=0;
function checkAnswers() {
for(var i=0; i<answers.length; i++) {
var userAnswer = document.getElementById(i);
if(userAnswer.value===answers[i]) {
totalYes++;
}
}
}
checkAnswers(); // check answers at the first place
alert(totalYes);
});

Related

Deselect a radio button in qualtrics

Is there a way to use the qualtrics javascript api (or, if not, a workaround) to programatically clear all entries made to radio buttons on a page?
My usage case is in a matrix table question that "pipes" (actually uses embedded data) values from the previous question to puts calculated numbers into the statements. However, if the respondent navigates back then when the return to the following question the numbers have changed but the responses have remained. As such, if it is the second time a respondent is viewing a page constructed like this, I want to clear all their previous answers.
I want to make sure that qualtrics' data is updated properly.
My survey is currently using the JFE engine if that makes a difference.
Qualtrics.SurveyEngine.addOnload(function() {
var QID = this.questionId;
var that = this;
var counts = [];
var radioButtonsClean = [];
var radioButtons = $(QID).getElementsByTagName('input');
var radioIndex = [];
for(var i=0; i<radioButtons.length; i++) {
if(radioButtons[i].type == 'radio') {
radioButtonsClean.push(radioButtons[i]);
radioIndex.push(radioButtons[i].id);
}
}
// Set counts for each displayed radio button to 0
for(var i=0; i<radioButtonsClean.length; i++) {
counts[i] = 0;
}
this.questionclick = function(event,element){
if (element.type == 'radio') {
var thisId = element.id;
var spotCheck = radioIndex.indexOf(thisId);
var count = counts[spotCheck];
if (count == 0) {
for(var i=0; i<counts.length; i++) {
counts[i] = 0;
}
counts[spotCheck] = 1;
}
else {
this.setChoiceValue(element.id.split('~')[2], element.id.split('~')[3], false);
counts[spotCheck] = 0;
}
}
}
});

How to know that user clicks on the same element?

I am making a quiz. It has two questions with four answers each.
I want to hide the submit button until user answers all question.
My code:
var answered = 0;
function checkAllAns(){
++answered;
if (answered >= 10)
{
document.getElementById("stop-btn").style.display = "inline-block";
document.getElementById("stop-btn").style.opacity = "1";
}
}
It works only when user answers one time each question, but what if user makes a mistake? Say user answers the same question for 10 times, the submit button appear although all question haven't been answered yet.
I replace it with this:
function checkAllAns(index){
var checkedIndex = [];
if ( ansAll[index] == false){
ansAll[index] = true;
}
for (i = 0; i < ansAll.length; ++i) {
if (ansAll[i] == true){
var checked = 0;
for (j = 0; j < checkedIndex.length; ++j){
if ( checkedIndex[j] == ansAll[i] ){
checked = 1;
}
else{
checkedIndex.push( ansAll[i] );
}
}
if (checked == 0){
++answered;
}
}
}
if (answered >= 10){
document.getElementById("stop-btn").style.display = "inline-block";
document.getElementById("stop-btn").style.opacity = "1";
}
}
It does not work (if it is working I won't answer it here...)
What is wrong with my code? If you've find another way to accomplish this, you can suggest me.
Thanks,
My complete code is here: http://codepen.io/anon/pen/EjYWWx
It seems like you have the right idea, but you're working too hard, you can just use one array and iterate through that (unless you're worried about a timing attack) like so:
function checkAllAns(index)
{
ansAll[index] = true;
for (i = 0; i < ansAll.length; ++i)
{
if (ansAll[i] != true)
{
break;
}
if (i == ansAll.length-1)
{
document.getElementById("stop-btn").style.display = "inline-block";
document.getElementById("stop-btn").style.opacity = "1";
}
}
}
Here's a JSFiddle for you: http://jsfiddle.net/soyn0xag/6/
Instead of using complex nesting of iterations and loops, use JQuery.
This checks whether the key has left the text area (aka complete)
$("input[type='text'], textarea").on("keyup", function(){
if($(this).val() != "" && $("textarea").val() != "" && $("input[name='category']").is(":checked") == true){
$("input[type='submit']").removeAttr("disabled");
}
});
This check whether the check box has been selected or changed.
$("input[name='category']").on("change", function(){
if($(this).val() != "" && $("textarea").val() != "" && $("input[name='category']").is(":checked") == true){
$("input[type='submit']").removeAttr("disabled");
}
});
This checks if the element is checked, when everything is check change the submit to show. This is just a snippet, you will need to expand.
Here is a method. Keep an array answered and add the question index to it unless that question has already been answered. Whene the array length is 10 then all questions have been answered
var answered = [];
function checkAllAns (index) {
if (answered.indexOf (index) >= 0)
answered.push (index);
if (answered.length == 10)
{
document.getElementById("stop-btn").style.display = "inline-block";
document.getElementById("stop-btn").style.opacity = "1";
}
}
I would suggest trying to go for simpler code and try to integrate it in a single solution. Something like this (untested):
function answered(){
return document.querySelectAll('.question.answered').length;
}
var answers = document.querySelectAll('.question .answer');
for (var i = 0; i < answers.length; i++) {
answers[i].onclick = function(e){
// This should be the question
e.target.parentNode.classList.add('answered');
// Check how many questions are answered
if (answered() > 10) {
// DO SOMETHING
}
}
}
Not tested, but in this way it's much easier. If you also used jQuery or a similar library, it would be much much more easy (as Bradley Wilson's answer point out).

Comparing two variables sting array to see if any value matches - javascript jquery

Hi I am trying to compare two arrays to each other and then hide a list element if any of the values match.
One array is tags that are attached to a list item and the other is user input.
I am having trouble as I seem to be able to cross reference one user input work and can't get multiple words against multiple tags.
The amount of user input words might change and the amount of tags might change. I have tried inArray but have had no luck. Any help would be much appreciated. See code below:
function query_searchvar() {
var searchquery=document.navsform.query.value.toLowerCase();
if (searchquery == '') {
alert("No Text Entered");
}
var snospace = searchquery.replace(/\s+/g, ',');
event.preventDefault();
var snospacearray = snospace.split(',');
$('li').each(function() {
var searchtags = $(this).attr('data-searchtags');
//alert(searchtags);
var searcharray = searchtags.split(',');
//alert(searcharray);
var searchtrue=-1;
for(var i = 0, len = searcharray.length; i < len; i++){
if(searcharray[i] == searchquery){
searchtrue = 0;
break;
}
}
if (searchtrue == 0) {
$(this).show("normal");
}
else {
$(this).hide("normal");
}
});
}
Okay so I've tried to implement the code below but have had no luck. It doesn't seem to check through both arrays.
function query_searchvar()
{
var searchquery=document.navsform.query.value.toLowerCase();
if(searchquery == '')
{alert("No Text Entered");
}
var snospace = searchquery.replace(/\s+/g, ' ');
event.preventDefault();
var snospacearray = snospace.split(' ');
alert(snospacearray[1]);
$('li').each(function() {
var searchtags = $(this).attr('data-searchtags');
alert(searchtags);
var searcharray = searchtags.split(' ');
alert(searcharray[0]);
jQuery.each(snospacearray, function(key1,val1){
jQuery.each(searcharray,function(key2,val2){
if(val1 !== val2) {$(this).hide('slow');}
});
});
});
}
Working code:
function query_searchvar()
{
var searchquery=document.navsform.query.value.toLowerCase();
if(searchquery == '')
{alert("No Text Entered");
}
var queryarray = searchquery.split(/,|\s+/);
event.preventDefault();
$('li').each(function() {
var searchtags = $(this).attr('data-searchtags');
//alert(searchtags);
var searcharray = searchtags.split(',');
//alert(searcharray);
var found = false;
for (var i=0; i<searcharray.length; i++)
if ($.inArray(searcharray[i], queryarray)>-1) {
found = true;
break;
}
if (found == true )
{
$(this).show("normal");
}
else {
$(this).hide("normal");
}
});
}
var snospace = searchquery.replace(/\s+/g, ',');
var snospacearray = snospace.split(',');
Note that you can split on regular expressions, so to the above would equal:
var queryarray = searchquery.split(/,|\s+/);
To find whether there is an item contained in both arrays, use the following code:
var found = searcharray.some(function(tag) {
return queryarray.indexOf(tag) > -1;
});
Although this will only work for ES5-compliant browsers :-) To support the others, use
var found = false;
for (var i=0; i<searcharray.length; i++)
if ($.inArray(searcharray[i], queryarray)>-1) {
found = true;
break;
}
In plain js, without jQuery.inArray:
var found = false;
outerloop: for (var i=0; i<searcharray.length; i++)
for (var j=0; j<queryarray.length; j++)
if (searcharray[i] == queryarray[j]) {
found = true;
break outerloop;
}
A little faster algorithm (only needed for really large arrays) would be to sort both arrays before running through them linear.
Here's psuedo code that should solve your problem.
get both arrays
for each item in array 1
for each element in array 2
check if its equal to current element in array 1
if its equal to then hide what you want
An example of this coude wise would be
jQuery.each(array1, function(key1,val1){
jQuery.each(array2,function(key2,val2){
if(val1 == val2) {$(your element to hide).hide();}
});
});
If there's anything you don't understand please ask :)

Can we get radiobuttonList.Items.Count in .aspx page

Can we get the count of total radiobuttonlist items from .aspx page. I have to call a javascript function onclientclick of a button and i want to loop through the total number of radiobuttonlist items. So can anyone tell me that can we get it from .aspx page. Because in my scenario i can not use code behind for this.
function ClearRBL() {
for (i = 0; i < RBLCOUNT; i++) {
document.getElementById('rblWorkerList_' + [i]).checked = false;
}
}
How can i get RBLCOUNT here from .aspx page only? If not possible then in Javascript please.
I don't know how the aspx side would work, but if you want to do it just in JavaScript you could do something like the following that doesn't need to know the total number of elements in advance:
function ClearRBL() {
var i = 0,
rbl;
while (null != (rbl = document.getElementById('rblWorkerList_' + i++)))
rbl.checked = false;
}
The above assumes that the element ids end in numbers beginning with 0 counting up by 1s; the while loop will keep going until document.getElementById() doesn't find a matching element (in which case it returns null). A less cryptic way of writing it is as follows:
function ClearRBL() {
var i = 0,
rbl = document.getElementById('rblWorkerList_' + i);
while (null != rbl) {
rbl.checked = false;
i++;
rbl = document.getElementById('rblWorkerList_' + i);
}
}
P.S. When the while loop finishes i will be equal to the number of radio buttons, which may be useful if you want to do something with that number afterwards.
Try this:- This is not exactly what you want but hope it will help you.
function GetRBLSelectionID(RadioButtonListID) {
var RB1 = document.getElementById(RadioButtonListID);
var radio = RB1.getElementsByTagName("input");
var isChecked = false;
var retVal = "";
for (var i = 0; i < radio.length; i++) {
if (radio[i].checked) {
retVal = radio[i].id;
break;
}
}
return retVal;
}
you can give a name all radio button and then get them like this.
var RBLCOUNT= document[groupName].length;
or
var RBLCOUNT= 0;
var inputs = document.getElementsByTagName('input');
for (var i = 0; i < inputs.length; ++i) {
if(inputs[i].type =="radio"){
RBLCOUNT++;
}
}
I just created a javascript function as mentioned by Karthik Harve and found the total number of rows generated dynamically as below: -
function ClearRBL() {
var rblLen = document.getElementById('rblWorkerList');
for (i = 0; i < rblLen.rows.length; i++) {
document.getElementById('rblWorkerList_' + [i]).checked = false;
}
}
It's working on both Mozila and IE.
Thanks alot to all who tried to help.

Scoring a Javascript Quiz Script

Hi I some javascript code written to quiz the user on 5 questions and then in theory output their score. As far as I can tell the questions are being scored, I just can't figure out how to output the response. I am having no issues fetching the correct html elements and displaying them. I believe the issue is in the looping elements of the window.onload function. The code is below,
<script type="text/javascript">
var rand = 0;
var right = 0;
window.onload = function () {
reset();
Rrand();
var rangQ = document.getElementById('area').getElementsByClassName('divide');
correct = document.getElementsByTagName('a'), i = 0;
for (i; i < correct.length; i++) {
if (correct[i].className == 'correct') {
correct[i].onclick = function () {
right++;
reset();
Rrand();
}
}
else if (correct[i].className != 'correct') {
correct[i].onclick = function () {
right--;
reset();
Rrand();
}
}
}
}
function Rrand() {
var rangQ = document.getElementById('area').getElementsByClassName('divide');
rangQ[rand].style.display = '';
rand++;
}
function reset() {
var rangQ = document.getElementById('area').getElementsByClassName('divide');
for (var i = 0; i < rangQ.length; i++) {
rangQ[i].style.display = 'none';
}
}
document.write(right);
</script>
window.onload is not executed immidiately. you are writing output, but variable right is changed after that.
you need to either move line
document.write(right);
into window.onload as last line (or after loop) or figure out other way that will be best for you

Categories