I have a form that contains several questions. Some of these questions are checkbox inputs.
When a form question is generated, it follows the following structure:
<div class="checkbox">
<div class="checkbox required">
<div class="checkbox required">
that does NOT have any checkboxes checked, it should print an error message next to that question.Below is the code that I have. Both of the questions are required. It's fairly close, I just can't seem to get it quite right. It seems to treat all divs with "required" class as one object, rather than as each as their own individual object in the boxes.each
section.
Does anyone have any suggestions? Thank you in advance.
$(document).ready(function() {
$("button").click(function(e){
e.preventDefault();
var boxes = $('div.checkbox.required');
boxes.each(function(){
if($(this).is(":checked"))
{
$(".error", this).hide();
$("form").submit();
return true;
} else if($(this).not(":checked")) {
$(".error", this).show().html("Please fill out all required fields");
return false;
}
});
});
});
label { font-weight: bold; }
.form-horizontal label span.error { color: red; }
.form-horizontal label div.error { color: red; }
.error {
padding: 2px;
font-size: 15px;
background: #FFDFDF;
border: 1px solid #FFCACA;
border-radius: 5px;
font-weight: normal;
text-align: center;
display: none;
}
<div class="checkbox required">
<h3>Question 1</H3>
<div class="col-md-4">
<span class="error"></span>
<label id="8522[]">
<input type="checkbox" class="" id="input-8522" name="8522[]" value="23606">
Behavioral Follow-up
</label><br>
<label id="8522[]">
<input type="checkbox" class="" id="input-8522" name="8522[]" value="23607">
Medical Follow-up
</label><br>
</div>
</div>
<p><br></p>
<div class="checkbox required">
<h3>Question 2</H3>
<div class="col-md-4">
<span class="error"></span>
<label id="8524[]">
<input type="checkbox" class="" id="input-8524" name="8524[]" value="23608">
Mild
</label><br>
<label id="8524[]">
<input type="checkbox" class="" id="input-8524" name="8524[]" value="23609" checked="checked">
Moderate
</label><br>
<label id="8524[]">
<input type="checkbox" class="" id="input-8524" name="8524[]" value="23610">
Severe
</label><br>
</div>
</div>
<p><br></p>
<button type="button" class="btn btn-primary action-save">
<i class="fa fa-save"></i> Save changes
</button>
<script src="https://code.jquery.com/jquery-3.6.3.slim.min.js"></script>
There are a couple of issues I see.
The first is with the line if($(this).is(":checked"))
. $(this)
in this block is referring to a div.checkbox.required
since we are iterating through the list of elements that match this selector. <div>
elements do not get the :checked
property, so this will always evaluate to false
. Instead, we want to determine if the div.checkbox.required
contains any :checked
inputs. We could do that with:
const hasAnyChecked = $(this).find('input:checked').length > 0;
The next issue is that the $("form").submit()
is within the boxes.each
loop. This will not work because if, for example, the first div.checkbox.required
contains a :checked
input and is therefore valid, the form will be submitted before checking the remaining div.checkbox.required
elements to determine if they too are valid. Instead, we must use a variable to track that all div.checkbox.required
are in a valid state and then conditionally submit the form once the boxes.each
loop has completed.
The code becomes:
$(function() {
$('button').on('click', function () {
let isValid = true;
$('div.checkbox.required').each(function () {
const $this = $(this);
const hasAnyChecked = $this.find('input:checked').length > 0;
isValid = isValid && hasAnyChecked;
if (hasAnyChecked) {
$this.find('.error').hide();
} else {
$this.find('.error').text('Please fill out all required fields').show();
}
});
if (isValid) {
$("form").submit();
}
});
});
label {
font-weight: bold;
}
.form-horizontal label span.error {
color: red;
}
.form-horizontal label div.error {
color: red;
}
.error {
padding: 2px;
font-size: 15px;
background: #FFDFDF;
border: 1px solid #FFCACA;
border-radius: 5px;
font-weight: normal;
text-align: center;
display: none;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="checkbox required">
<h3>Question 1</H3>
<div class="col-md-4">
<span class="error"></span>
<label id="8522[]">
<input type="checkbox" class="" id="input-8522" name="8522[]" value="23606">
Behavioral Follow-up
</label><br>
<label id="8522[]">
<input type="checkbox" class="" id="input-8522" name="8522[]" value="23607">
Medical Follow-up
</label><br>
</div>
</div>
<p><br></p>
<div class="checkbox required">
<h3>Question 2</H3>
<div class="col-md-4">
<span class="error"></span>
<label id="8524[]">
<input type="checkbox" class="" id="input-8524" name="8524[]" value="23608">
Mild
</label><br>
<label id="8524[]">
<input type="checkbox" class="" id="input-8524" name="8524[]" value="23609" checked="checked">
Moderate
</label><br>
<label id="8524[]">
<input type="checkbox" class="" id="input-8524" name="8524[]" value="23610">
Severe
</label><br>
</div>
</div>
<p><br></p>
<button type="button" class="btn btn-primary action-save">
<i class="fa fa-save"></i> Save changes
</button>