1

I was creating a quiz app in javascript

I want to change the color of buttons in question pallet of each question as the user attempts the question it should change to the button related to that question to green color.

i have used a multidimensional array for storing questions and answers and also the choice selected by user in array named questions and i am storing the value in questions[0][7] for question number 1 and questions[1][7] for question number two and so on.

i have pasted my code below please suggest a idea to achieve the above result

right now on attempting any question all the buttons are changing color to green

Thanks in advance

var questions = [
  ["q1", "1", "2", "3", "4", "5", "A", "not"],
  ["q2", "10", "20", "30", "40", "50", "B", "not"],
  ["q3", "10", "20", "30", "40", "50", "C", "not"],
  ["q4", "10", "20", "30", "40", "50", "D", "not"]
];

var pos = 0,
  choice, correct = 0,
  rscore = 0;

window.onload = function() {
  qus();
  // setQuestionOrder()
}

function qus() {
  document.getElementById("question").innerHTML = questions[pos][0];
  document.getElementById("c1").innerHTML = questions[pos][1];
  document.getElementById("c2").innerHTML = questions[pos][2];
  document.getElementById("c3").innerHTML = questions[pos][3];
  document.getElementById("c4").innerHTML = questions[pos][4];
  document.getElementById("c5").innerHTML = questions[pos][5];
}


function next() {

  var choices = document.getElementsByName("choices");
  for (var i = 0; i < choices.length; i++) {
    if (choices[i].checked) {
      choice = choices[i].value;
    }
  }

  questions[pos][7] = choice;

  if (choice == questions[pos][6]) {
    correct++;
    // alert('correct');
  } else {
    //alert('incorrect');
  }

  if (pos + 1 >= questions.length) {
    var r = confirm("Submit test?", );
    if (r == true) {
      document.write("You got " + correct + "  correct of " + questions.length + " questions<br><br>");
      correct = "0";
      pos = "0";

    } else {

    }




    return false;

  } else {
    pos++;
    //console.log(pos, questions.length);
    qus();
    check();
  }


}


function uncheck() {
  document.getElementById("r1").checked = false;
  document.getElementById("r2").checked = false;
  document.getElementById("r3").checked = false;
  document.getElementById("r4").checked = false;
  document.getElementById("r5").checked = false;
}

function check() {
  if (questions[pos][7] == "A") {
    document.getElementById("r1").checked = true;
  } else if (questions[pos][7] == "B") {
    document.getElementById("r2").checked = true;
  } else if (questions[pos][7] == "C") {
    document.getElementById("r3").checked = true;
  } else if (questions[pos][7] == "D") {
    document.getElementById("r4").checked = true;
  } else if (questions[pos][7] == "E") {
    document.getElementById("r5").checked = true;
  } else {
    uncheck();
  }
}



function w3_open() {
  document.getElementById("mySidebar").style.display = "block";
}

function w3_close() {
  document.getElementById("mySidebar").style.display = "none";
}


function q1() {
  pos = 0;
  qus();
  check();
}

function q2() {
  pos = 1;
  qus();
  check();
}

function q3() {
  pos = 2;
  qus();
  check();
}

function q4() {
  pos = 3;
  qus();
  check();
}

/// CODE TO CHANGE COLOR

if (questions[0][7] == "A" || "B" || "C" || "D" || "E") {
  document.getElementById("q1").style = "background-color:green;"
}
else if (questions[1][7] == "not") {
  document.getElementById("q2").style = "background-color:white;"
} 
else {
  document.getElementById("q1").style = "background-color:red;"
}


if (questions[1][7] == "A" || "B" || "C" || "D" || "E") {
  document.getElementById("q2").style = "background-color:green;"
} 
else if (questions[1][7] == "not") {
  document.getElementById("q2").style = "background-color:white;"
} 
else {
  document.getElementById("q2").style = "background-color:red;"
}
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">

<button class="w3-button w3-light-grey w3-large w3-right" onclick="w3_open() "><i class="fa fa-bars"></i></button>



<div class="w3-sidebar w3-bar-block w3-border-left top" style="display:block; width:10%; right:0;" id="mySidebar">
  <button onclick="w3_close()" class="w3-bar-item large">Close &times;</button>
  <a href="#" onclick="q1()" class="w3-bar-item w3-button " id="q1"> 1</a>
  <a href="#" onclick="q2()" class="w3-bar-item w3-button" id="q2"> 2</a>
  <a href="#" onclick="q3()" class="w3-bar-item w3-button" id="q3"> 3</a>
  <a href="#" onclick="q4()" class="w3-bar-item w3-button" id="q4"> 4</a>
</div>




<label class="xxlarge" id="question">
    
</label><br><br>


<input type="radio" name="choices" value="A" id="r1" class="radio"><label id="c1"></label><br><br>
<input type="radio" name="choices" value="B" id="r2" class="radio"><label id="c2"></label> <br><br>
<input type="radio" name="choices" value="C" id="r3" class="radio"><label id="c3"></label><br><br>
<input type="radio" name="choices" value="D" id="r4" class="radio"><label id="c4"></label><br><br>
<input type="radio" name="choices" value="E" id="r5" class="radio"><label id="c5"></label>

<br>
<br>
<br>

<button onclick="next()" class="btn green round">Save & Next</button>
  • 1
    `if (questions[0][7] == "A" || "B" || "C" || "D" || "E")` and the like, with those "or"s `||` as such, the condition always evaluates to `true` – GetSet Jul 14 '20 at 14:12
  • So what should I use instead? – Ritesh Singh Jul 14 '20 at 14:23
  • As @GetSet says, the actual condition always evaluates to true. Try somehting like the following: `var answers = ["A", "B", "C", "D", "E"]; if (answers.includes(questions[0][7]))...` – piraces Jul 14 '20 at 14:28
  • I will submit a complete solution below. – GetSet Jul 14 '20 at 15:03
  • Does this answer your question? [JavaScript: Simple way to check if variable is equal to two or more values?](https://stackoverflow.com/questions/12116326/javascript-simple-way-to-check-if-variable-is-equal-to-two-or-more-values) – Heretic Monkey Jul 14 '20 at 15:50
  • 1
    @GetSet thanks man it was explained so nicely ✌️ – Ritesh Singh Jul 14 '20 at 17:09

2 Answers2

0

/// CODE TO CHANGE COLOR

Define an array of possible answers and check the value store in question[0][7] is in that array or not instead of the logic you wrote.

possibleAnswers = ["A", "B", "C", "D", "E"];

if (possibleAnswers.includes(questions[0][7])) {
  document.getElementById("q1").style = "background-color:green;"
}
upender
  • 160
  • 1
  • 10
0

I will be using your existing coding style in this solution so you can easily see how these edits fix your problem.

But do note that you could really benefit by using more loops so as you are not repeating the same code, conditionals, and assignments over and over in raw source.

The major changes here are that the color changing code is now a function. Also, I fixed a logical error where revisting the same correct answer and choosing save, would have erroneously increased count again.

I placed comments in your source to show where and what changes I made.

var questions = [
  ["q1", "1", "2", "3", "4", "5", "A", "not"],
  ["q2", "10", "20", "30", "40", "50", "B", "not"],
  ["q3", "10", "20", "30", "40", "50", "C", "not"],
  ["q4", "10", "20", "30", "40", "50", "D", "not"]
];

var pos = 0,
  choice, correct = 0,
  rscore = 0;

window.onload = function() {
  qus();
  // setQuestionOrder()
}

function qus() {
  document.getElementById("question").innerHTML = questions[pos][0];
  document.getElementById("c1").innerHTML = questions[pos][1];
  document.getElementById("c2").innerHTML = questions[pos][2];
  document.getElementById("c3").innerHTML = questions[pos][3];
  document.getElementById("c4").innerHTML = questions[pos][4];
  document.getElementById("c5").innerHTML = questions[pos][5];
}


function next() {

  var choices = document.getElementsByName("choices");
  for (var i = 0; i < choices.length; i++) {
    if (choices[i].checked) {
      choice = choices[i].value;
    }
  }

  questions[pos][7] = choice;



  updateAnswerHinting(); // Do your answer hinting (history) in this next function

  // Get rid of incrementing correct because if a user revisits an answer and 
  // chooses save then it will get incremented again if were correct

  /*
  if (choice == questions[pos][6]) {
    correct++;
    // alert('correct');
  } else {
    //alert('incorrect');
  }
  */

  if (pos + 1 >= questions.length) {
    var r = confirm("Submit test?", );
    if (r == true) {

      // Calculate correct since we are no longer tallying it as we go
      correct = 0;
      for (var i = 0; i < questions.length; i++) {
        if (questions[i][USER_CHOICE] == questions[i][Q_ANSWER]) correct++;
      }

      document.write("You got " + correct + "  correct of " + questions.length + " questions<br><br>");
      correct = "0";
      pos = "0";

    } else {

    }




    return false;

  } else {
    pos++;
    //console.log(pos, questions.length);
    qus();
    check();
  }


}


function uncheck() {
  // You can use a loop for this. Consider using this technique for other parts of your code

  for (var i = 0; i < 5; i++) {
    document.getElementById("r" + (i + 1)).checked = false;
  }
  /*
    document.getElementById("r1").checked = false;
    document.getElementById("r2").checked = false;
    document.getElementById("r3").checked = false;
    document.getElementById("r4").checked = false;
    document.getElementById("r5").checked = false;
  */

}

function check() {
  if (questions[pos][7] == "A") {
    document.getElementById("r1").checked = true;
  } else if (questions[pos][7] == "B") {
    document.getElementById("r2").checked = true;
  } else if (questions[pos][7] == "C") {
    document.getElementById("r3").checked = true;
  } else if (questions[pos][7] == "D") {
    document.getElementById("r4").checked = true;
  } else if (questions[pos][7] == "E") {
    document.getElementById("r5").checked = true;
  } else {
    uncheck();
  }
}



function w3_open() {
  document.getElementById("mySidebar").style.display = "block";
}

function w3_close() {
  document.getElementById("mySidebar").style.display = "none";
}

function qx(p) {
  // p is Base 1 (starts from 1)
  pos = p - 1;
  qus();
  check();
}

// These functions are no longer needed since we now have qx()
/*
function q1() {
  pos = 0;
  qus();
  check();
}

function q2() {
  pos = 1;
  qus();
  check();
}

function q3() {
  pos = 2;
  qus();
  check();
}

function q4() {
  pos = 3;
  qus();
  check();
}
*/


/// CODE TO CHANGE COLOR
const USER_CHOICE = 7;
const Q_ANSWER = 6;

function updateAnswerHinting() {
  for (var i = 0; i < questions.length; i++) {
    var color = "white";
    if (questions[i][USER_CHOICE] == questions[i][Q_ANSWER]) {
      color = "green";
    } else if (questions[i][USER_CHOICE] != "not") {
      color = "red";
    }

    // To prevent future logical errors, check if element exists
    var el = document.getElementById("q" + (i + 1));

    if (el) el.style = "background-color:" + color;
  }
}

// This code was out of place anyway
/*
if (questions[0][7] == "A" || "B" || "C" || "D" || "E") {
  document.getElementById("q1").style = "background-color:green;"
}
else if (questions[1][7] == "not") {
  document.getElementById("q2").style = "background-color:white;"
} 
else {
  document.getElementById("q1").style = "background-color:red;"
}


if (questions[1][7] == "A" || "B" || "C" || "D" || "E") {
  document.getElementById("q2").style = "background-color:green;"
} 
else if (questions[1][7] == "not") {
  document.getElementById("q2").style = "background-color:white;"
} 
else {
  document.getElementById("q2").style = "background-color:red;"
}
*/
<head>
  <link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
</head>




<body>

  <button class="w3-button w3-light-grey w3-large w3-right" onclick="w3_open() "><i class="fa fa-bars"></i></button>



  <div class="w3-sidebar w3-bar-block w3-border-left top" style="display:block; width:10%; right:0;" id="mySidebar">
    <button onclick="w3_close()" class="w3-bar-item large">Close &times;</button>
    <a href="#" onclick="qx(1)" class="w3-bar-item w3-button " id="q1"> 1</a>
    <a href="#" onclick="qx(2)" class="w3-bar-item w3-button" id="q2"> 2</a>
    <a href="#" onclick="qx(3)" class="w3-bar-item w3-button" id="q3"> 3</a>
    <a href="#" onclick="qx(4)" class="w3-bar-item w3-button" id="q4"> 4</a>
  </div>




  <label class="xxlarge" id="question">
    
</label><br><br>


  <input type="radio" name="choices" value="A" id="r1" class="radio"><label id="c1"></label><br><br>
  <input type="radio" name="choices" value="B" id="r2" class="radio"><label id="c2"></label> <br><br>
  <input type="radio" name="choices" value="C" id="r3" class="radio"><label id="c3"></label><br><br>
  <input type="radio" name="choices" value="D" id="r4" class="radio"><label id="c4"></label><br><br>
  <input type="radio" name="choices" value="E" id="r5" class="radio"><label id="c5"></label>

  <br>
  <br>
  <br>

  <button onclick="next()" class="btn green round">Save & Next</button>
</body>

Also note, though not necessary logically, I created these constants to make your source more readable, and more ready for future changes:

const USER_CHOICE = 7;
const Q_ANSWER = 6;

These are indexes to your questions array to be used in place of the literals. I used them where I put code. Consider using them for the rest of your code.

GetSet
  • 1,511
  • 2
  • 10
  • 13