0

I am having a really hard time with a form validation and would appreciate some help. Essentially I have a form with various required fields, to include inputs, select, and textarea. One of the form fields is for an email address that I want to validate.

The problem I have is that I loop through the form elements using the querySelectorALL and check to see if a field is both required AND not empty. The problem I have is integrating a second validation for the email field. In the main loop, it may show as required and NOT empty, but could contain an invalid email value.

So I thought to create a second conditional in the for loop, to check if the name of the item is "Email", and if it was, check it for validity.

What I find is that submitting the form with the placeholder makes the field's placeholder text red. If I then put in an invalid email address, the field turns black, but if you look at my conditional, if it is an invalid email the value should stay red, but it does not.

I hope this is making sense. I have been at this for hours and really struggling.

function validateAppt() {
  var returnVal = true;
  var divElem = document.getElementById("appointmentform");
  var inputElements = divElem.querySelectorAll("input, select, textarea");
  inputElements.forEach(a => a.style.color = "black");
  inputElements.forEach(a => a.style.borderColor = "black");
  for (let i = 0; i < inputElements.length; i++) {
    if (inputElements[i].required && inputElements[i].value == "") {
      inputElements[i].style.borderColor = "red";
      if (inputElements[i].type != 'select-one') {
        inputElements[i].style.setProperty("--c", "red");
      } else {
        inputElements[i].style.color = "red";
      }
      returnVal = false;
    }


    if (inputElements[i].name == "Email") {
      if (!validateEmail(inputElements[i].value)) {
        inputElements[i].style.setProperty("--c", "red");
        inputElements[i].style.color = "red";
        console.log("InValid Email");
      } else {
        inputElements[i].style.color = "black";
        console.log("Valid Email");
      }
    }
  }

  if (!returnVal) {
    $("#appointment_introduction").css('color', 'red').text('Please complete required form fields.');
    $('html, body').animate({
      scrollTop: $('#appointment_introduction').offset().top - 200
    }, 2000);
    return false;
  } else {
    return true;
  }

}



function validateEmail(email) {
  var re = /^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))([a-zA-Z]{2,10}|[0-9]{1,3})(\]?)$/;
  return re.test(email);
}
Jon P
  • 19,442
  • 8
  • 49
  • 72
TMHDesign
  • 171
  • 1
  • 3
  • 11
  • Please include your HTML as well – Jon P Nov 28 '19 at 22:04
  • In the end, it is impossible to really validate a correct email address in JavaScript. Only the email provider can tell. For required you can simply use the attribute `required`. – Lain Nov 28 '19 at 22:14
  • For future references: https://stackoverflow.com/questions/46155/how-to-validate-an-email-address-in-javascript – Lain Nov 28 '19 at 22:19
  • @Lain raises a good point. You can only achieve so much with regex validation of emails. It's a fine balance of not being too restrictive while still providing meaningful validation. We use this monster : https://regex101.com/r/vvZe6c/2/tests – Jon P Nov 28 '19 at 22:32
  • Thanks of for the assistance. I have a script on the backend to check for validation as well, but I just want to minimize the majority of those visiting the website to enter a valid email from the start. What is confusing me is that if I submit the form with all placeholders, the email field is red as it should be. If I add a valid email, it is black, as it should be. But if I add an invalid email, the field stays black when I want it to be red. For whatever reason the attempt to cahnge the color gets ignored in the second conditional statement. I can change other styles, but not the color??? – TMHDesign Nov 28 '19 at 22:38
  • Please see my original comment - please include your HTML. Preferably as a [mcve] – Jon P Nov 28 '19 at 22:44
  • That would suggest the inputs name not being Email. – Lain Nov 28 '19 at 22:44

1 Answers1

0

I use default HTML5 validation everywhere with checkValidity method whether on whole form or on elements as needed and simple CSS classes to show the error. For little more complicated you can use also pattern attribute to use regexp. More read on https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Form_validation

Here is some minimal example:

const form = document.getElementById('someForm')
form.onsubmit = submit 

function submit(e) {
  e.preventDefault()
  this.classList.remove('invalid')
  if (!this.checkValidity()) {
    this.classList.add('invalid')
  }
}
form.invalid input:invalid {
  border: red 1px solid;
}
<form action="" id="someForm" novalidate>
  <input placeholder="email" type="email" required>
  <input type="text" placeholder="random text" required>
  <button>Submit</button>
</form>
user8672473
  • 236
  • 2
  • 8