I’m building a simple function that checks whether or not all inputs are filled or empty for inputs with a particular class. The issue I am having is that the function runs correctly once, but doesn’t re-add the hide class if the input is empty.
<i class="text-success fa fa-check hide-info-complete" id="info-check"></i>
<input class="info-input" name="school" />
<input class="info-input" name="bus" />
function checkInfoFormOnBlur() {
var form_complete_check = document.getElementById("info-check");
$('.info-input').each(function() {
if ($(this).val() === '') {
form_complete_check.classList.add("hide-info-complete-check-mark");
} else if ($(this).val() !== '') {
form_complete_check.classList.remove("hide-info-complete-check-mark");
}
});
}
setInterval(function(){ checkInfoFormOnBlur(); }, 3000);
If both fields have a value, it works — but it doesn’t work when one input is empty after the first run. the hide-info-complete class does not get sent back to the i tag.
How can I recursively check whether or not all inputs are filled or empty with setInterval and properly remove the hide-info-complete class when an input no longer has a value.
- If the elements start out as blank, put the class on the element to start with so it is hidden
- Use an event handler to handle when the value changes, rather than an interval
- When the value changes, toggle the class so that it only has the class if any of the inputs are blank
var $infoCheck = $('#info-check');
var $inputs = $('.info-input').on('input', function(){
$infoCheck.toggleClass(
'hide-info-complete-check-mark',
$inputs.filter(function(){ return !this.value.trim(); }).length > 0
);
});
.hide-info-complete-check-mark { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<i class="text-success fa fa-check hide-info-complete hide-info-complete-check-mark" id="info-check">Info Check</i>
<input class="info-input" name="school" />
<input class="info-input" name="bus" />
Answer:
You need to change the check. Your code only is looking at the last index and that determines what happens. And it makes no sense to be doing it on a timer.
Add event listeners to the elements and I use filter to find any elements that are unchecked.
var inputs = $(".info-check")
var check = $("#info-check")
inputs.on("change", function() {
var isValid = inputs.filter(function(input) {
return this.value.trim().length === 0
}).length === 0
check.toggleClass('hide-info-complete', !isValid)
}).change()
.hide-info-complete {
visibility: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<i class="text-success fa fa-check hide-info-complete" id="info-check"></i>
<input class="info-check" name="school" />
<input class="info-check" name="bus" />
Doing it without jQuery
var inputs = Array.from(document.querySelectorAll(".info-check"))
var check = document.querySelector("#info-check")
var checkValid = function () {
var isValid = inputs.every(function(input) {
return input.value.trim().length > 0
})
check.classList.toggle('hide-info-complete', !isValid)
}
inputs.forEach(function (input) {
input.addEventListener("change", checkValid)
})
.hide-info-complete {
visibility: hidden;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<i class="text-success fa fa-check hide-info-complete" id="info-check"></i>
<input class="info-check" name="school" />
<input class="info-check" name="bus" />
and with HTML5 which requires no JavaScript at all.
form:invalid #info-check{
visibility: hidden;
}
<link href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" rel="stylesheet" />
<form>
<i class="text-success fa fa-check" id="info-check"></i>
<input class="info-check" name="school" required />
<input class="info-check" name="bus" required />
</form>
Tags: class, function, input, java, javascriptjavascript, jquery