Keep EventListener running untill the box is checked

Viewed 56

The Context

I have a form where text fields must pass validation before the checkbox to accept terms and conditions is shown.

The Problem

I want the code to hide the element, even after validation has passed temporarily, for example, if a user changes the text in an input field to subsequently fail validation.

Currently

I have been successful so far in getting the checkbox to be hidden until validation has passed with:

form.addEventListener("input", function(){
    eval();
    if (evalResult === true) {
        showBox();
    } else {
        hideBox();
    }
});

where showBox and hideBox use object.style.visibility to hide the respective DOM element.

The eval() function does the validation and returns a boolean to the evalResult variable.

However

If a user changes the text in an input field, after showBox has been called, the check box remains visible. The issue with this, is that invalidated data may be sent to the server.

Some research shows that a loop may be the answer, but I can't have the loop running out.

Would this be a case for using a debounce()? I think that might unfortunately be a bit beyond my knowledge at the moment.

All help will be greatly appreciated.

Edit

If there is a way to keep the handler running until the checkbox is checked?

Edit 2 As requested here is the eval() function


function eval () {
   
    let isFirstNameValid = checkFirstName(),
    isLastNameValid = checkLastName(),
    isEmailValid = checkEmail(),
    isTelephoneValid = checkTelephone();

    let isFormValid = 
    isFirstNameValid &&
    isLastNameValid &&
    isEmailValid &&
    isTelephoneValid;

    if (isFormValid) {
        evalResult = true;
    }
};

Edit 3

I have changed the name of the eval() function to evaluate() to not interfere with the existing eval() function..

Edit 4 The Working Code



function showBox() {
    document.getElementById("terms").style.visibility = "visible";
    console.log("a wild box appeared!");
};

function hideBox() {
    document.getElementById("terms").style.visibility = "hidden";
    console.log("the box fled!");
};

let valid = ""

document.querySelector("form").addEventListener("input", function(){
    let valid = false;
    if (checkFirstName(),
    checkLastName(),
    checkEmail(),
    checkTelephone() === true) {
        valid = true;
    } else {
        valid = false;
    };
    console.log(valid);
    if (valid === true) {
        showBox();
    } else {
        hideBox();
    };
});
1 Answers

Let me introduce you to setTimeout! Simply call it with a callback and a time (in milliseconds) and it will call your callback once the time has passed.

Also I highly suggest not using eval in 99.9% of cases.

const formEl = document.querySelector("form");
const firstNameEl = formEl.querySelector("input[name='firstName']");
const lastNameEl = formEl.querySelector("input[name='lastName']");
const acceptTermsLabelEl = formEl.querySelector("label");

const validate = () => {
    if (!firstNameEl.value || !firstNameEl.value.length)
    return false;
    if (!lastNameEl.value || !lastNameEl.value.length)
    return false;
  
  return true;
}

const showBox = () => {
    acceptTermsLabelEl.style.display = "initial";
}

const hideBox = () => {
    acceptTermsLabelEl.style.display = "none";
}

let showBoxTimeout = null;

formEl.addEventListener("input", () => {
    const isValid = validate();
  
  if (isValid) {
    if (!showBoxTimeout)
        // store our setTimeout in a variable to avoid duplications of the setTimeout
        showBoxTimeout = setTimeout(() => {
        validate() ? showBox() : hideBox()
        if (validate())
            showBox();
        else
            hideBox();
          
        showBoxTimeout = null;
        
      }, 3000);
  } else {
    hideBox();
  }

Here's a JSFiddle to mess around with! https://jsfiddle.net/5wtf0gyv/

Related