0

I am working on a form with multiple pages. On one page I have check boxes that I would require at least one to be selected before submission. How can I do that with javascript/html5?

It is all one form that changes pages with javascript. How on the last page can I have the form check, if at least one checkbox has been selected?

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("nextBtn").innerHTML = "Submit";
  } else {
    document.getElementById("nextBtn").innerHTML = "Next";
  }
  //... 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("regForm").submit();
    return false;
  }
  // Otherwise, display the correct tab:
  showTab(currentTab);
}

function validateForm() {
  // This function deals with validation of the form fields
  var x, y, i, valid = true;
  x = document.getElementsByClassName("tab");
  y = x[currentTab].getElementsByTagName("input");
  // A loop that checks every input field in the current tab:
  for (i = 0; i < y.length; i++) {
    // If a field is empty...
    if (y[i].value == "") {
      // add an "invalid" class to the field:
      y[i].className += " invalid";
      // and set the current valid status to false
      valid = false;
    }
  }
  // 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";
}
* {
  box-sizing: border-box;
}

body {
  background-color: #f1f1f1;
}

#regForm {
  background-color: #ffffff;
  margin: 100px auto;
  font-family: Raleway;
  padding: 40px;
  width: 70%;
  min-width: 300px;
}

h1 {
  text-align: center;  
}

input {
  padding: 10px;
  width: 100%;
  font-size: 17px;
  font-family: Raleway;
  border: 1px solid #aaaaaa;
}

/* Mark input boxes that gets an error on validation: */
input.invalid {
  background-color: #ffdddd;
}

/* Hide all steps by default: */
.tab {
  display: none;
}

button {
  background-color: #4CAF50;
  color: #ffffff;
  border: none;
  padding: 10px 20px;
  font-size: 17px;
  font-family: Raleway;
  cursor: pointer;
}

button:hover {
  opacity: 0.8;
}

#prevBtn {
  background-color: #bbbbbb;
}

/* Make circles that indicate the steps of the form: */
.step {
  height: 15px;
  width: 15px;
  margin: 0 2px;
  background-color: #bbbbbb;
  border: none;  
  border-radius: 50%;
  display: inline-block;
  opacity: 0.5;
}

.step.active {
  opacity: 1;
}

/* Mark the steps that are finished and valid: */
.step.finish {
  background-color: #4CAF50;
}
<form id="regForm" action="/action_page.php">
  <h1>Register:</h1>
  <!-- One "tab" for each step in the form: -->
  <div class="tab">Name:
    <p><input placeholder="First name..." oninput="this.className = ''" name="fname"></p>
    <p><input placeholder="Last name..." oninput="this.className = ''" name="lname"></p>
  </div>
  <div class="tab">Contact Info:
    <p><input placeholder="E-mail..." oninput="this.className = ''" name="email"></p>
    <p><input placeholder="Phone..." oninput="this.className = ''" name="phone"></p>
  </div>
  <div class="tab">
    <H3 id="subhead">AUDITORIUM ROOM SETUP & EQUIPMENT REQUESTS</H3>
    <label><label id="asterisk">*</label>Room Setup (Select all that apply):</label><br><br>
    <!-- <p><input placeholder="dd" oninput="this.className = ''" name="dd"></p> -->
    <br>
    <input id="element_3_1" name="Room-Setup" required type="checkbox" value="Auditorium-Seating-for-300" />
    <label class="choice" id="labelinput" for="element_3_1">Auditorium Seating for 300</label>

    <br>
    <input id="element_3_2" name="Room-Setup" class="elementcheckbox" type="checkbox" value="Auditorium-Seating-for-350" />
    <label class="choice" id="labelinput" for="element_3_2">Auditorium Seating for 350 (recommended max for Performances</label>

    <label class="choice" for="element_3_3">Auditorium Seating 400</label>
    <input id="element_3_3" name="Room-Setup" class="elementcheckbox" type="checkbox" value="Auditorium-Seating-400" />

    <label class="choice" for="element_3_4">Round Tables and Chairs</label>
    <input id="element_3_4" name="Room-Setup" class="elementcheckbox" type="checkbox" value="Round-Tables-and-Chairs" />

    <label class="choice" for="element_3_5">Other (Please note that we cannot change the auditorium setup during your event*)</label>
    <input id="element_3_5" name="Room-Setup" class="elementcheckbox" type="checkbox" value="Other" />
  </div>

  <div style="overflow:auto;">
    <div style="float:right;">
      <button type="button" id="prevBtn" onclick="nextPrev(-1)">Previous</button>
      <button type="button" id="nextBtn" onclick="nextPrev(1)">Next</button>
    </div>
  </div>
  <!-- Circles which indicates the steps of the form: -->
  <div style="text-align:center;margin-top:40px;">
    <span class="step"></span>
    <span class="step"></span>
    <span class="step"></span>
    <span class="step"></span>
  </div>
</form>
franiis
  • 1,378
  • 1
  • 18
  • 33
anon001
  • 15
  • 4

1 Answers1

1

Put a second classname in <div class="tab theFirstTabWithCheckboxes">

This code get that element and counts cheched inputs to a global variable

var checkboxes = document.querySelectorAll("tab.theFirstTabWithCheckboxes input");

var i = checkboxes.length;

window.count_nr_of_checked_boxes = 0;
while (i--) { //count down to 0
  if (checkboxes[i].checked) window.count_nr_of_checked_boxes++;
}

With querySelectorAll() you select in the same way as you select in CSS. Note how the dot operator is an and operator and the space operator means "input is inside ..." (it is evaluated from right to left).

Put the following line in the function validateForm()

if (count_nr_of_checked_boxes < 1) valid = false

You dont need to have window. on global variables

  • Sorry I had a typo in `while(--i)` that I edited to `while(i--)`. Then it decrements right after the condition, instead of before. If for example `i = 10` it counts down so the first `i` is 9 and the last `i` is 0 in the statement. Perfect indexing arrays where doing backwards is often fine and you do not need to remember `-1` on Array.length. The while loop stop when it see i == 0. –  Apr 27 '19 at 23:03