Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

validate a multiple tabs with multiple radio buttons

Tags:

I have a form, which has multiple tabs that displays 10 questions in each one and include (true/false) radio groups (generated by php code, so I don't know their names OR how many will appear), and I need to check whether they are checked or not on next button clicked. If not I want to show the user which question was not answered (no alert message, but it can be in a label with a green or red check icon).

I've tried googling the problem, but none of the previous answers were good to use in my case.

enter image description here

Edit: This is a part of my code:

<form  id="questionForm" action="" method="post" role="form">
  <input type="hidden" name="login" value="<?php echo $_SESSION['login-user']?>"/>
  <input type="hidden" name="pass_user" value="<?php echo $_SESSION['pass_user']; ?>"/>
  <?php
  $blocks_questions = array_chunk($questions, 10);
  foreach($blocks_questions as $cle=>$question_block) {?>
    <div class='tab'>
      <?php
      foreach ($question_block as $key => $question) {
        $id_quiz_qst=$question['id_quiz'].",".$question['id_qst'];?>
        <div class="form-group qst-row">
          <div class="row">
            <div class="col-sm-10"><p><?php echo $question['question'] ?></p>
            </div>
            <div class="col-sm-2">
              <span class="question-rbtn" >
                <span class="switch radio-switch fixed-width-lg">
                  <input name="<?php echo $id_quiz_qst?>" id="<?php echo $id_quiz_qst."_on";?>" value="Vrai" <?php if (isset($_POST[$id_quiz_qst]) && $_POST[$id_quiz_qst]=="Vrai") echo "checked";?> type="radio">
                  <label for="<?php echo $id_quiz_qst."_on";?>" class="radioCheck">Vrai</label>

                  <input name="<?php echo $id_quiz_qst?>" id="<?php echo $id_quiz_qst."_off";?>" value="Faux" type="radio" <?php if (isset($_POST[$id_quiz_qst]) && $_POST[$id_quiz_qst]=="Faux") echo "checked";?>>
                  <label for="<?php echo $id_quiz_qst."_off";?>" class="radioCheck">Faux</label>
                  <a class="slide-button btn"></a>
                  <label style="display:inline; float:right; position:absolute; font-size:18px;">
                    <i class="good icon_check_alt2" style="color:#17944d ;"></i>
                    <i class="not-good icon_close_alt2" style="color:#ff5032 ;"></i>
                  </label>
                </span>
              </span>
            </div>
          </div>
        </div>
      <?php } ?>
    </div>
    <?php
  } ?>
  <div style="overflow:auto;">
    <div class="text-center">
      <a class="next-prev" id="prevBtn" onclick="nextPrev(-1)"><i class="fa arrow_carrot-2left_alt "></i></a>
      <a class="next-prev" id="nextBtn" onclick="nextPrev(1)"><i class="fa arrow_carrot-2right_alt"></i></a>
    </div>
  </div>
  <!-- Circles which indicates the steps of the form: -->
  <div style="text-align:center;margin-top:10px;">
    <span class="step"></span><span class="step"></span><span class="step"></span><span class="step"></span><span class="step"></span>
  </div>
  <div id="submit-area" class="text-center">
    <button id="submit_answers" name="submit_answers" type="submit" onclick="myfunc();" class="btn btn-primary btn-lg">Valider</button>
    <button type="reset" class="btn btn-primary btn-lg">Annuler</button>

  </div>
</form>



<script>
  var currentTab = 0; // Current tab is set to be the first tab (0)
  showTab(currentTab); // Display the current tab

  function showTab(n) {
    // This function will display the specified tab of the form...
    var x = document.getElementsByClassName("tab");
    x[n].style.display = "block";
    //... and fix the Previous/Next buttons:
    if (n == 0) {
      document.getElementById("prevBtn").style.display = "none";
    } else {
      document.getElementById("prevBtn").style.display = "inline";
    }
    if (n == (x.length - 1)) {
      document.getElementById("submit-area").style.display="block";
      document.getElementById("nextBtn").style.display = "none";
    } else {
      document.getElementById("nextBtn").style.display = "inline";
    }
    //... and run a function that will display the correct step indicator:
    fixStepIndicator(n)
  }

  function nextPrev(n) {
    // This function will figure out which tab to display
    var x = document.getElementsByClassName("tab");
    // Exit the function if any field in the current tab is invalid:
    if (n == 1 && !validateForm()) return false;
    // Hide the current tab:
    x[currentTab].style.display = "none";
    // Increase or decrease the current tab by 1:
    currentTab = currentTab + n;
    // if you have reached the end of the form...
    if (currentTab >= x.length) {
      // ... the form gets submitted:
      document.getElementById("questionForm").submit();
      return false;
    }
    // Otherwise, display the correct tab:
    showTab(currentTab);
  }
  x = document.getElementsByClassName("tab");
  y = x[currentTab].getElementsByTagName("input");

  function changeColor(){
    x = document.getElementsByClassName("tab");
    y = x[currentTab].getElementsByTagName("input");

  }
  function validateForm() {
    // This function deals with validation of the form fields
    var x, y, i, good, not_good, valid = true;
    x = document.getElementsByClassName("tab");
    y = x[currentTab].getElementsByTagName("input");
    good = document.getElementsByClassName("good");
    not_good = document.getElementsByClassName("not-good");

    // A loop that checks every input field in the current tab:
    //  alert(y[0].getElementById("btv").name);
    var indexinc =0;
    for (i = 0; i < y.length; i++) {
      // If a field is empty...
      //y[i].parentNode.className =     y[i].parentNode.className.replace("invalid","");
      if (!y[i].checked) {
        indexinc++;
        // add an "invalid" class to the field:
        not_good[i].style.display="block";
        // and set the current valid status to false
        valid = false;
      }
      else{
        good[i].style.display="block";
        valid = true;
      }
    }
    if(indexinc == 10)//Verify that he did answer all 22 questions and check that we have the 22 inputs not 44 inputs (vrai/faux)
    valid = true;
    // If the valid status is true, mark the step as finished and valid:
    if (valid) {
      document.getElementsByClassName("step")[currentTab].className += " finish";
    }
    return valid; // return the valid status
  }
  function fixStepIndicator(n) {
    // This function removes the "active" class of all steps...
    var i, x = document.getElementsByClassName("step");
    for (i = 0; i < x.length; i++) {
      x[i].className = x[i].className.replace(" active", "");
    }
    //... and adds the "active" class on the current step:
    x[n].className += " active";
  }
</script>
like image 673
it4Astuces Avatar asked Apr 02 '19 12:04

it4Astuces


1 Answers

You can evaluate this with your html structure, using querySelectorAll and verifying that at least one radio button of a section is selected, this functions will work but I would recommend them to put them in a class, or a IIFE, to avoid declaring them in the global scope...

function nextTab(e) {
  if (validate(e)){
   console.log("go to next tab");
  } 
}
function validate(element) {
  let val = true;
  let select = element.closest("section");
  select.querySelectorAll('.radio-container').forEach(function(container){
    let radioChecked = container.querySelectorAll("input:checked");
    container.style.backgroundColor = "white";
    if(!radioChecked.length) {
      val = val && false;
      container.style.backgroundColor = "red";
    }
  });
  return val;
}
<section id="tab1">
  <div class="radio-container">
    <input type="radio" name="gender" value="male"> Male
    <input type="radio" name="gender" value="female"> Female
    <input type="radio" name="gender" value="other"> Other
  </div>
  <div class="radio-container">
    <input type="radio" name="gender1" value="male"> Male
    <input type="radio" name="gender1" value="female"> Female
    <input type="radio" name="gender1" value="other"> Other
  </div>
  <div class="radio-container">
    <input type="radio" name="gender2" value="male"> Male
    <input type="radio" name="gender2" value="female"> Female
    <input type="radio" name="gender2" value="other"> Other
  </div>
  <button type="button" onclick="nextTab(this)">Continue</button>
</section>

UPDATE

You could use the same idea in your case you can get the tab section with your currentTab variable, within this tab you can get all your ".question-rbtn" elements, and with these elements you can verify if at least one radio button is checked...

function nextPrev(n) {

    // Validate radio buttons
    if(!validate()) return;

    // This function will figure out which tab to display
    var x = document.getElementsByClassName("tab");
    // Exit the function if any field in the current tab is invalid:
    if (n == 1 && !validateForm()) return false;
    // Hide the current tab:
    x[currentTab].style.display = "none";
    // Increase or decrease the current tab by 1:
    currentTab = currentTab + n;
    // if you have reached the end of the form...
    if (currentTab >= x.length) {
      // ... the form gets submitted:
      document.getElementById("questionForm").submit();
      return false;
    }
    // Otherwise, display the correct tab:
    showTab(currentTab);
  }

  function validate() {
  let val = true;
  let select = document.getElementsByClassName("tab")[currentTab];
  select.querySelectorAll('.question-rbtn').forEach(function(container) 
  {
    let radioChecked = container.querySelectorAll("input:checked");
    container.style.backgroundColor = "white";
    if(!radioChecked.length) {
      val = val && false;
      container.style.backgroundColor = "red";
    }
  });
  return val;
}
like image 135
Renzo Calla Avatar answered Oct 15 '22 11:10

Renzo Calla