Javascript Radio Multiple Choice

Trying to have each validation message next to each radio button instead of just having the error at the bottom of each question.
I know I should be using span elements next to each item, but I’m not sure how to approach it with the code with the way I have it setup. Any help would be appreciated.

Also for my 3rd question. I’m validating 2 to 3 digit only integers, but when I put in the correct format, the message won’t disappear. Everything else works correctly.

<!--HTML -->

<!DOCTYPE html>
<html lang="en">

<head>
  <title>Orichalcum Quiz</title>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="images/favicon.ico">
  <link rel="stylesheet" href="css/normalize.css">
  <link rel="stylesheet" href="css/main.css">
  <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">
  <script src="scripts/quiz.js"></script>
</head>

<body>
  <header>
    <h1>Orichalcum Quiz</h1>
  </header>

  <main>

    <p>Click on the correct answer for each question and submit your results.</p>

    <form>
      <fieldset>
        <legend>Trivia Questions</legend>
        <label> Enter your Name</label>
		<input type="text" id="myText" name="fieldName" placeholder="Anonymous" value=""><br>
        <section id="radio1" class="questions">
          <p> Question 1) What was orichalcum valued as? <span class="choice_error">Please select a choice</span></p>
          <label><input type="radio" name="choice0" value="A">Gold</label><span>*</span>
          <label><input type="radio" name="choice0" value="B">Silver</label><span>*</span>
          <label><input type="radio" name="choice0" value="C">Bronze</label><span>*</span>
          <label><input type="radio" name="choice0" value="D">Copper</label><span>*</span>
          <span id="flag0"></span>
        </section>
        <section id="radio2" class="questions">
          <p> Question 2) What is the component that mostly makes up this material? <span class="choice_error">Please select a choice</span></p>
          <label><input type="radio" name="choice1" value="A">Zinc</label><span>*</span>
          <label><input type="radio" name="choice1" value="B">Nickel</label><span>*</span>
          <label><input type="radio" name="choice1" value="C">Brass</label><span>*</span>
          <label><input type="radio" name="choice1" value="D">Iron</label><span>*</span>
          <span id="flag1"></span>
		  <br>
		  <br>
        </section>
		<label>Question 3) How many ingots have been found in the shipwreck off the coast of Silicy? (Hint: 47)</label><br><br>
		<input type="text" id="answerText1" name="answerText1" value=""><span>*</span>
		<br>
		<br>
		<label>Question 4) What is orichalcum used for? (Hint: crafting)</label><br><br>
		<input type="text" id="answerText2" name="answerText2" value=""><span>*</span>
        <br>
		<br>
        <input type="button" onclick="returnResults()" value="Show Results">
		<br><br>
        <input type="button" id="button2" onclick="window.location.href = 'index.html';" value="Review">
        <p id="results"></p>
      </fieldset>
    </form>
  </main>
  <aside>

  </aside>
  <footer>
    <p align="center"> Anthony Kirkpatrick - Fall 2019 </p>
  </footer>
</body>

</html>
var answers = ["A", "C"],
  total = answers.length;


function getAnswer(QuestionId) 
{
  
  var answer = document.querySelector("#" + QuestionId + " input[type=radio]:checked");

  if (answer === null) 
  {
    document.querySelector("#" + QuestionId + " .choice_error").style.display = "inline";
  } 
  else 
  {
             
    document.querySelector("#" + QuestionId + " .choice_error").style.display = "";
    answer = answer.value;
  }

  return answer;
}



function getScore() 
{
  var score = 0;

  for (var i = 0; i < total; i++) 
  {
    document.getElementById("flag" + i).innerHTML = "";
	
    if (getAnswer("radio" + (i + 1)) == answers[i]) 
	{
      score += 1;
      document.getElementById("flag" + i).innerHTML = "Correct!";
    }

    else 
	{
      document.getElementById("flag" + i).innerHTML = "Incorrect!";
    }
  }
  
 
  return score;
}

var getResults = function() 
{	
  var x = document.getElementById("myText").value;
  var message = "";
  
  var answerInput1 = document.getElementById("answerText1").value.trim();
  var answerInput2 = document.getElementById("answerText2").value.trim();
   
  var validateInteger = /^\d{2,3}$/;
  var isValid = true;
  
   //score feedback
   if(getScore() == 0)
  {
	  message = "Nothing at all?...Okay, " + x+ ".";
  }
  else if(getScore() > 0)
  {
	  message = "Cool, but there's still more to answer, " + x + "!";
  }
  else if(getScore() == 2)
  {
	  message = "Perfect. Thanks for participating, " + x + "!";
  }
  
  //validating input text 1
  if (answerInput1 == "") 
  {
    document.getElementById("answerText1").nextElementSibling.firstChild.nodeValue = "This field is required.";
    isValid = false;
  } 
  else if(answerInput1 != validateInteger)
  {
	  document.getElementById("answerText1").nextElementSibling.firstChild.nodeValue = "Answer must be a 2- or 3- digit number";
	  isValid = false;
  }
  else
  {
    document.getElementById("answerText1").nextElementSibling.firstChild.nodeValue = "Correct!";
  }
  
  //validating input text 2
  if (answerInput2 == "") 
  {
    document.getElementById("answerText2").nextElementSibling.firstChild.nodeValue = "This field is required.";
    isValid = false;
  } 
  else 
  {
    document.getElementById("answerText2").nextElementSibling.firstChild.nodeValue = "Correct!";
  }

  return message;
}

function returnResults() 
{
  document.getElementById("results").innerHTML = getResults();
}
1 Like

Hello,

Here’s what I’ve tried to make the form work the way you want: https://codepen.io/wanzulfikri/pen/pozazae

Trying to have each validation message next to each radio button instead of just having the error at the bottom of each question.
I know I should be using span elements next to each item, but I’m not sure how to approach it with the code with the way I have it setup. Any help would be appreciated.

I’ve looked at your HTML but I am still not sure what you want the error display to look like.

If you want the error to be next to the checked radio button, you can try putting the <span>*</span> inside the label and modify the span's text. Since you already know how to target the checked radio button (look at getAnswer()), you can just use nextElementSibling to target its span sibling.

Another way is to give an id to the span elements next to each item. That way, you can query them directly with getElementById.

Also for my 3rd question. I’m validating 2 to 3 digit only integers, but when I put in the correct format, the message won’t disappear. Everything else works correctly.

Try using match instead of equality.

Every string has a match method so you can just invoke that and pass your regex into it.

For example:

var validateInteger = /^[0-9]{2,3}$/;

if(answerInput1.match(validateInteger)) {
 // logic
}

Though it might be better to not use Regex for number ranges and use straightforward equality expressions instead.

Oh yeah, it might be worthwhile to look into built-in form validation. That way you don’t need to use JS all the time to check if the field is filled or not. You can also set ranges of input too which might be useful for your digit validation eg <input type="number" min = 10 max= 100 />

Hopefully that helped.

If you want to display error message which should disappear after some time, use setTimeout() which should clear element’s. who contain errors message, innerHTML.
For making two div’s, for instance, to go side by side, use display: inline; on both elements who you wants to be side by side.