Sweepster
Sweepster

Reputation: 1949

Checking if checked radio button is returning true but should be false

This question is NOT like this. The problem here is stemming from an if condition that is retaining a prior value, while the other question is asking how to determine what type of input is shown on screen.

<html>
    <head>
        <meta charset="utf-8">
        <title>Untitled Document</title>
        <script type="text/javascript">
            function displayquestion(a, ignore){
                var b = a-1;
                var currentInput = '';
                var questions = document.getElementsByClassName("questionholder");
                var showRequired = document.getElementById("requiredMessage");

                function showNext (){
                    showRequired.style.display = "none";        

                    for(var i=0; i < questions.length; i++) {           
                        questions[i].style.display = "none";    
                    }

                    var nextQuestion = document.getElementById("question" + a);

                    if(nextQuestion !== null) {
                        nextQuestion.style.display = "block";
                    }   
                }

                // Check if question should ignore inputs
                if (ignore == 1) { // yes, ignore the inputs so move on to next question
                    console.log("path 1");

                    showNext();

                } else { //no, don't ignore the inputs
                    if (document.querySelector('input.input' + b).type == "radio") { //this is a radio input                
                        if (document.querySelector('input[type=radio]:checked')) { //a radio option is selected
                            console.log("path 2");

                            showNext();

                        } else { // no radio option is selected so show error                   
                            console.log("path 3");

                            showRequired.style.display = "block";
                        }               
                    } else { // not a radio input
                        if (document.querySelector('input.input' + b) !== null) {
                            var currentInput = document.querySelector('input.input' + b).value;
                        }

                        if (currentInput == '') { // the input is blank so show error
                            console.log("path 4");

                            showRequired.style.display = "block";

                        } else { // the input is not blank so move on to next question
                            console.log("path 5");

                            showNext();
                        }
                    }
                }
            }   
        </script>
    </head>
    <body>
        <div id="requiredMessage" style="display:none">
            <p>This field is required.</p>
        </div>
        <form id="TheForm" style="display:block;">
            <div data-toggle="buttons" class="questionholder multiplechoice" id="question13" style="display:block">
                <h5>The world is... </h5>
                <input class="input13" type="radio" id="round" name="isPrevRel" value="round">
                <label for="round">
                    <p class="radioChoice">round</p>
                </label>
                <br>
                <input class="input13" type="radio" id="square" name="isPrevRel" value="square">
                <label for="birthcombo">
                    <p class="radioChoice">Square</p>
                </label>
                <br>
                <a class="text2button radio" onclick="displayquestion(14)">Next</a>
            </div>
            <div data-toggle="buttons" class="questionholder multiplechoice" id="question14" style="display:none">
                <h5>Do you like snow?</h5>
                <input class="input14" type="radio" id="yes" name="snow" value="yes">
                <label for="yes">
                    <p class="radioChoice">Yes. If you'd like, explain why</p>
                </label>
                <input class="input14" type="radio" id="no" name="snow" value="no">
                <label for="no">
                    <p class="radioChoice">No</p>
                </label>
                <br>
                <input name="relSNonID1"><br>
                <a class="text2button radio" onclick="displayquestion(15)">Next</a>
            </div>
        </form>
    </body>
</html>

I have issues with my javascript function, which works as intended with input text fields AND with radio buttons, but not when the two are combined.

In short, I have a div that asks a questions and contains a pair of radio buttons, a text input, and a next button. When the user click next, the function displayquestion(a) fires.

The function checks to see if it is told to ignore the current question. If so, it hides the div and displays the next question.

If not, it checks to see if the document contains an input with a class of input# (where # corresponds to the div id question#) is a radio input. If it is, it checks to see if an of the radio options is selected. If none are selected, it shows an error message.

Otherwise, if the input is not a radio input, it checks to see if the input is blank. If it is blank, it shows an error message. If it is not blank, it hides the div.

It works as intended but only if the shown div contains ONLY a radio option set OR a text input.

As you can see, I have one question where a radio option must be made, with an optional text input.

The intended result should be that the error message displays until the user makes a radio selection. it does not matter if the text input is completed. Only if a radio option is selected and when the user clicks next, it should hide the div.

Instead, what happens is that the div hides whether the user does nothing at all, or makes a choice.

From what I've gathered, the issue is stemming from

document.querySelector('input[type=radio]:checked')

Where it appears that the condition is retaining its value from question 13 (the first div) even when the user sees question 14 (the second div). I know this because the console log is printing the same values when clicking next on both divs.

I believe it is because i'm not checking for input + b but I am unable to add the varible. What is the proper integration?

jsfiddle

Upvotes: 0

Views: 1218

Answers (1)

ADyson
ADyson

Reputation: 61914

Your primary issue is that when you are testing for checked radio buttons, it checks across all radio buttons in the page, not just the ones which are in the currently visible question. It's not a case of the variable "retaining" its value, it's simply that the scope of the selector is too broad, and it will return the first selected checkbox it finds - in this case, there happens to already be one from a previous question, so it returns that.

A couple of small changes can a) make your code a bit more efficient (less repeated querying of the same thing, and b) resolve your issue

1) for efficiency and readability, put the result of document.querySelector('input.input' + b); into a variable so you don't have to run the same query repeatedly in the if statements

2) to check if a radio button is selected within the current question, add a restriction to the selector to narrow the scope into the current question: document.querySelector("#question" + b + " input[type=radio]:checked")

3) There was an error which prevented the "Square" option from being selected in the first question - the accompanying label's for attribute was wrong, it should be <label for="square">

By the way I don't think it's possible or desirable to combine the two tests (as you mention in the comments) because they don't do the same thing. The first test checks what kind of input the first input in the question is, and the second test checks the status of that input (once we know it's definitely a radio button).

Demo:

function displayquestion(a, ignore) {
  var b = a - 1;
  var currentInput = '';
  var questions = document.getElementsByClassName("questionholder");
  var showRequired = document.getElementById("requiredMessage");

  function showNext() {
    showRequired.style.display = "none";

    for (var i = 0; i < questions.length; i++) {
      questions[i].style.display = "none";
    }

    var nextQuestion = document.getElementById("question" + a);

    if (nextQuestion !== null) {
      nextQuestion.style.display = "block";
    }
  }

  // Check if question should ignore inputs
  if (ignore == 1) { // yes, ignore the inputs so move on to next question
    console.log("path 1");

    showNext();

  } else { //no, don't ignore the inputs
    var input = document.querySelector('input.input' + b);
    if (input.type == "radio") { //this is a radio input				
      if (document.querySelector("#question" + b + " input[type=radio]:checked")) { //a radio option is selected
        console.log("path 2");

        showNext();

      } else { // no radio option is selected so show error					
        console.log("path 3");

        showRequired.style.display = "block";
      }
    } else { // not a radio input
      if (input !== null) {
        var currentInput = input.value;
      }

      if (currentInput == '') { // the input is blank so show error
        console.log("path 4");

        showRequired.style.display = "block";

      } else { // the input is not blank so move on to next question
        console.log("path 5");

        showNext();
      }
    }
  }
}
body {
  font-family: arial;
}

h1 {
  font-size: 0.75em;
}

h5 {
  font-size: 0.5em;
  line-height: 1.5em;
  margin-block-start: 0;
  margin-block-end: 0;
}

h6 {
  font-size: 0.35em;
  margin-block-start: 0;
  margin-block-end: 0;
}

br {
  line-height: 0.2em;
}

p {
  display: block;
  margin-block-start: 0;
  margin-block-end: 0;
  margin-inline-start: 0px;
  margin-inline-end: 0px;
}

.Title {
  text-align: center;
  font-size: 3em;
  text-decoration: underline;
}

form {
  margin: 0 auto;
  width: 75%;
  text-align: center;
  font-size: 3em;
}

form#filledForm {
  display: table;
  table-layout: fixed;
  margin: 0 auto;
  width: 100%;
  font-size: 1em;
}

form#filledForm th {
  text-align: left;
}

form#filledForm td {
  width: auto;
  font-size: 0.75em;
  vertical-align: bottom;
}

form#filledForm tr.aligncenter td {
  font-size: 0.75em;
  vertical-align: initial;
}

form#filledForm input[name=relSNonID1] {
  margin-top: 0;
}

form#filledForm input[name=relSNonID2] {
  margin-top: 0;
}

.questionholder {
  display: none;
}

input {
  line-height: 1em;
  font-size: 1em;
  text-align: center;
  width: 100%;
  margin-bottom: 0.5em;
}

input[name=relSNonID1] {
  margin-top: 0.2em;
}

input[name=relSNonID2] {
  margin-top: 0.2em;
}

input[type=radio] {
  margin-bottom: 0;
  visibility: hidden;
}

input[type="radio"]:checked+label {
  border-style: solid;
  padding: 10px;
}

div[data-toggle="buttons"] label.active {
  color: #7AA3CC;
}

div[data-toggle="buttons"] label {
  display: inline-block;
  margin-bottom: 0;
  vertical-align: top;
  cursor: pointer;
  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}

div[data-toggle="buttons"] label:hover {
  color: #7AA3CC;
}

div[data-toggle="buttons"] label:active,
div[data-toggle="buttons"] label.active {
  -webkit-box-shadow: none;
  box-shadow: none;
}

.text2button {
  border-style: solid;
  padding: 10px;
  cursor: pointer;
}

.multiplechoice {
  line-height: 0.5em;
}

.radio {
  line-height: 2em;
}

.radioChoice {
  font-size: 0.5em;
  cursor: pointer;
}

#result p {
  text-align: center;
  font-size: 2em;
}
<div id="requiredMessage" style="display:none">
  <p>This field is required.</p>
</div>

<form id="TheForm" style="display:block;">
  <div data-toggle="buttons" class="questionholder multiplechoice" id="question13" style="display:block">
    <h5>The world is... </h5>
    <input class="input13" type="radio" id="round" name="isPrevRel" value="round"><label for="round"><p class="radioChoice">round</p></label><br>
    <input class="input13" type="radio" id="square" name="isPrevRel" value="square"><label for="square"><p class="radioChoice">Square</p></label><br>
    <a class="text2button radio" onclick="displayquestion(14)">Next</a>
  </div>
  <div data-toggle="buttons" class="questionholder multiplechoice" id="question14" style="display:none">
    <h5>Do you like snow?</h5>
    <input class="input14" type="radio" id="yes" name="snow" value="yes"><label for="yes"><p class="radioChoice">Yes. If you'd like, explain why</p></label>
    <input class="input14" type="radio" id="no" name="snow" value="no"><label for="no"><p class="radioChoice">No</p></label><br>
    <input name="relSNonID1"><br>
    <a class="text2button radio" onclick="displayquestion(15)">Next</a>
  </div>
</form>

Upvotes: 1

Related Questions