0

in my simple form, I use this simple client-side validation. The validation start when I press SUBMIT (change style input and span of form).

How can I validate the input even when the user fills in the field without going through the SUBMIT?


STYLE

<style>
.msc-login-form-input {
    display: flex;
}
.msc-login-form-input.success > input {
  color: #3F4254;
  background-color: #ffffff;
}
.msc-login-form-input.errore > input {
    background-color: #4d40ff;
    color: #ffffff;    
}
.msc-login-form-input.errore > input::-webkit-input-placeholder {
  color: #ffffff;
}
.msc-login-form-input.errore > input:-ms-input-placeholder {
  color: #ffffff;
}
.msc-login-form-input.errore > input::placeholder {
  color: #ffffff;
}
.msc-login-form-input > span {
    width: 35px;
    background-color: rgba(0,0,0,0.05);
    min-height: 100%;
    align-items: center;
    justify-content: center;
    text-align: center;
    display: flex;
}
.msc-login-form-input > span::before {
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
  content: "\f100";
}
.msc-login-form-input.success > span::before {
  content: "\f00c";
    color:#FF1493;
}
.msc-login-form-input.errore > span::before {
  content: "\f00d";
    color:#4d40ff;
}
</style>

HTML and JS This script checks the internal elements of the form. If, when I click on SUBMIT the fields are empty, then, it highlights the inputs with different styles and loads me different icons in the SPANs tag.

<form id="signinform" method="post" action="#" class="wp-user-form" autocomplete="off">
  <div class="msc-login-form-input">
    <input type="text" name="log" value="" id="user_login" placeholder="prova" required/>
    <span></span> </div>
  <div class="msc-login-form-input">
    <input type="password" name="pwd" value="" id="user_pass" placeholder="prova" required/>
    <span></span> </div>
  <div class="msc-login-form-input-sendh">
    <input type="submit" id="submit-login" name="submit-login" value="Submit" class="user-submit" />
  </div>
<script>
// ___________________________________________________________________
// validate contact form
const myform = document.getElementById('signinform');
myform.noValidate = true;

// custom form validation
myform.addEventListener('submit', validateForm);

// stop submission of valid form for demo
myform.addEventListener('submit', e => {
  
  e.preventDefault();

  const fd = new FormData(e.target);
  for (const [name, value] of fd.entries()) {
    console.log(name + ': ' + value);
  }
  
});


// form validation
function validateForm(e) {

  const
    form = e.target,
    field = Array.from(form.elements);
  
  // reset fields
  field.forEach(i => {
    i.parentElement.classList.remove('errore');
    i.parentElement.classList.add('success');
  });
  
  if (!form.checkValidity()) {

    // form is invalid - cancel submit
    e.preventDefault();
    e.stopImmediatePropagation();

    // apply invalid class
    field.forEach(i => {

      if (!i.checkValidity()) {

        // field is invalid - add class
        i.parentElement.classList.add('errore');
        i.parentElement.classList.remove('success');
      }
    });
  }
}
</script>
</form>

Thanks

Luca Kiebel
  • 9,790
  • 7
  • 29
  • 44
redblade
  • 29
  • 6
  • I feel like you are answering your own question. To validate on keyup you can add `keyup` listener (to the inputs) and validate there - as you are doing with validating on submit with the form. Or is there more to it? – Esszed Feb 01 '22 at 09:02
  • Hello, i am not an experienced developer so i asked for help. Anyway, if you intend to add onkeyup="validateForm()" (example) to the INPUT tag, I tried but it throws me error. – redblade Feb 01 '22 at 09:16
  • What exactly are you trying to validate on the keyup? – Esszed Feb 01 '22 at 09:27
  • The same thing that this script does by clicking on submit. What I would like to obtain is a validation check both by pressing the SUBMIT key and by filling in the fields correctly. If I click on SUBMIT and there are empty fields, the script adds new classes to the inputs and spans and highlights the empty fields for me. If I compile one correctly, however, the style remains in error until I click SUBMIT again. I wish it changed on Keyup. – redblade Feb 01 '22 at 09:33
  • In that case you can remove the error class on the Keyup instead of checking validation again. As it follows that once user presses key while in the input the input no longer will be empty. Would that be the wanted behavior? – Esszed Feb 01 '22 at 09:52
  • Exactly. This is behavior. – redblade Feb 01 '22 at 09:59
  • Please don't add SOLVED to the title of your question. If it has been solved by an answer, you can accept that answer, if you solved the problem yourself you can write your own answer and accept that. – Luca Kiebel Feb 01 '22 at 10:38

1 Answers1

1

As per your comment. Instead of running validation again you can just add event listener that listens for Keydown (or Keyup) and then removes the class displaying the error.

const myform = document.getElementById("signinform");
myform.noValidate = true;

// custom form validation
myform.addEventListener("submit", validateForm);

// stop submission of valid form for demo
myform.addEventListener("submit", (e) => {
  e.preventDefault();

  const fd = new FormData(e.target);
  for (const [name, value] of fd.entries()) {
    console.log(name + ": " + value);
  }
});

// form validation
function validateForm(e) {
  const form = e.target,
    field = Array.from(form.elements);

  // reset fields
  field.forEach((i) => {
    i.parentElement.classList.remove("errore");
    i.parentElement.classList.add("success");
  });

  if (!form.checkValidity()) {
    // form is invalid - cancel submit
    e.preventDefault();
    e.stopImmediatePropagation();

    // apply invalid class
    field.forEach((i) => {
      if (!i.checkValidity()) {
        // field is invalid - add class
        i.parentElement.classList.add("errore");
        i.parentElement.classList.remove("success");
      }
    });
  }
}

//  remove the error class on Keydown input
const formInputs = document.querySelectorAll(".msc-login-form-input");
formInputs.forEach((input) => {
  input.addEventListener("keydown", () => {
    input.classList.remove("errore");
    input.classList.add("success");
  });
});
.msc-login-form-input {
  display: flex;
}
.msc-login-form-input.success > input {
  color: #3f4254;
  background-color: #ffffff;
}
.msc-login-form-input.errore > input {
  background-color: #4d40ff;
  color: #ffffff;
}
.msc-login-form-input.errore > input::-webkit-input-placeholder {
  color: #ffffff;
}
.msc-login-form-input.errore > input:-ms-input-placeholder {
  color: #ffffff;
}
.msc-login-form-input.errore > input::placeholder {
  color: #ffffff;
}
.msc-login-form-input > span {
  width: 35px;
  background-color: rgba(0, 0, 0, 0.05);
  min-height: 100%;
  align-items: center;
  justify-content: center;
  text-align: center;
  display: flex;
}
.msc-login-form-input > span::before {
  font-family: "Font Awesome 5 Free";
  font-weight: 900;
  content: "\f100";
}
.msc-login-form-input.success > span::before {
  content: "\f00c";
  color: #ff1493;
}
.msc-login-form-input.errore > span::before {
  content: "\f00d";
  color: #4d40ff;
}
<form id="signinform" method="post" action="#" class="wp-user-form" autocomplete="off">
  <div class="msc-login-form-input">
    <input type="text" name="log" value="" id="user_login" placeholder="prova" required/>
    <span></span> </div>
  <div class="msc-login-form-input">
    <input type="password" name="pwd" value="" id="user_pass" placeholder="prova" required/>
    <span></span> </div>
  <div class="msc-login-form-input-sendh">
    <input type="submit" id="submit-login" name="submit-login" value="Submit" class="user-submit" />
  </div>
</form>

Also your script tags should not be inside the form. They should be at the bottom of your page or in the <head> using async.

Esszed
  • 597
  • 1
  • 3
  • 15
  • Wow, this is how it works! Thank you very much. Just a consideration. Now, when I type, the style of the input field changes correctly while the icon in the span remains the default one. This too, when the user types, must change from the default or error to the successful one. – redblade Feb 01 '22 at 10:27
  • SOLVED adding: input.addEventListener("keydown", () => input.classList.add("success")); Many thanks!! – redblade Feb 01 '22 at 10:33
  • Just to be sure. You don't have to have to create another listener. Just put it in the callback function as well. See the revised answer. – Esszed Feb 01 '22 at 10:38
  • One last thing. Is it possible to add a listner that checks if the field is empty after the user has deleted the text? Now, if the field is empty, the input changes to an error; if I start typing, it changes to success (very good). If however, I realize I am wrong and delete the content, it remains in the success state. I would like it to return to an error state. Thank you. – redblade Feb 01 '22 at 11:07
  • Definitely possible. You can add listener directly to the input and check its value whether and once it is empty add appropriate class. – Esszed Feb 01 '22 at 12:06
  • But ... adding onblur="myFunction()" in the tag input? Isn't it possible to include everything in the script? – redblade Feb 01 '22 at 13:05
  • I don't really know what you mean. Maybe ask another question? You can create event listener for the onblur event to have it inside the script. – Esszed Feb 01 '22 at 13:10
  • Sorry but I didn't understand how and where to insert that event to also check the empty field. – redblade Feb 01 '22 at 13:30