-3

As part of a Frontend Mentor challenge, I am creating a simple email validation for a subscription landing page. It simply checks whether the email field is empty, if so, it throws an error message. Another error message is shown if the user enters an incorrect email address.

I've created a function called checkInputs() which contains a conditional else if statement

When testing on live server, the first condition works fine, when I leave the email field empty, however, the second condition doesn't even run, nor does the third.

I've included the full in case it's anything else throwing the whole function off. I tested the function isEmail() which checks whether the email is valid, and it works fine for me.

const form = document.getElementById('form');
const email = document.getElementById('email');

form.addEventListener('submit', (e) => {
  e.preventDefault();
  checkInputs();
})

function checkInputs() {
  const emailValue = email.value;
  const emptyEmail = emailValue === '';
  const invalidEmail = !isEmail(emailValue);

  if (emptyEmail) {
    setErrorFor(email, 'Oops! Please add your email');
  } else if (invalidEmail) {
    setErrorFor(email, 'Oops! Please check your email');
  } else {
    setSuccessFor(emailValue);
  }
};

function setErrorFor(input, message) {
  const formGroup = input.parentElement;
  const small = formGroup.querySelector('small');
  formGroup.className = 'form-group error';
  small.innerHTML = message;
}

function setSuccessFor(input) {
  const formGroup = input.parentElement;
  formGroup.className = 'form-group success';
}

// checks if email is valid
function isEmail(email) {
  const regx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

  return regx.test(email);
}
<div class="form-group">
  <form id="form" method="POST" name="subscribe">
    <input type="email" placeholder="Email address" name="email" id="email" class="email-input error">
    <br>
    <small></small>
    <br>
    <button class="form-btn" type="submit">Request Access</button>
  </form>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236

3 Answers3

1

Console says:

Uncaught TypeError: Cannot set properties of undefined (setting 'className')

on

function setSuccessFor(input) {
  const formGroup = input.parentElement;
  formGroup.className = 'form-group success';
}

You are not passing a form element

  1. Change setSuccessFor(email);
  2. I advise to also change formGroup.classList.add('success');
  3. Perhaps remove the success before testing, although it is currently not possible to add a wrong email due the the HTML5 validation

const form = document.getElementById('form');
const email = document.getElementById('email');

form.addEventListener('submit', (e) => {
  e.preventDefault();
  checkInputs();
})

function checkInputs() {
  const emailValue = email.value;
  const emptyEmail = emailValue === '';
  const invalidEmail = !isEmail(emailValue);
  email.parentElement.classList.remove('success');
  if (emptyEmail) {
    setErrorFor(email, 'Oops! Please add your email');
  } else if (invalidEmail) {
    setErrorFor(email, 'Oops! Please check your email');
  } else {
    setSuccessFor(email);
  }
};

function setErrorFor(input, message) {
  const formGroup = input.parentElement;
  const small = formGroup.querySelector('small');
  formGroup.className = 'form-group error';
  small.innerHTML = message;
}

function setSuccessFor(input) {
  const formGroup = input.parentElement;
  formGroup.classList.add('success');
}

// checks if email is valid
function isEmail(email) {
  const regx = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;

  return regx.test(email);
}
.success { background-color:green }
<div class="form-group">
  <form id="form" method="POST" name="subscribe">
    <input type="email" placeholder="Email address" name="email" id="email" class="email-input error">
    <br>
    <small></small>
    <br>
    <button class="form-btn" type="submit">Request Access</button>
  </form>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
-3

This should fix it for you:

const emptyEmail = emailValue === '';

to

const emptyEmail = (emailValue) ? true : false;

Also you have an error in one of your functions:

function setErrorFor(input, message) {
    const formGroup = input.parentElement;
    const small = formGroup.querySelector('small');
    formGroup.className = 'form-group error'; 
    small.innerHTML = message;

Should be (closing bracket)

function setErrorFor(input, message) {
    const formGroup = input.parentElement;
    const small = formGroup.querySelector('small');
    formGroup.className = 'form-group error'; 
    small.innerHTML = message;
}
Jamie Burton
  • 481
  • 2
  • 7
  • How does that behave differently? – Cerbrus Oct 28 '22 at 11:16
  • I've honestly never seen a variable assigned like ```const emptyEmail = emailValue === ''``` in my whole career. I'll take your word that it's valid but i'd definitely still change it to what i have specified – Jamie Burton Oct 28 '22 at 11:20
  • 1
    `(emailValue) ? true : false` literally does **exactly** the same thing as simply testing the truthiness of `emailValue`. – Pointy Oct 28 '22 at 11:21
  • Thank you for taking the time to respond Jamie. I am still learning and trying my best :) The closing bracket was missing because I failed to copy and paste it properly. – Yazzybandyham Oct 28 '22 at 11:32
  • 1
    `(emailValue) ? true : false;`: Redundant `()`. You have your condition the wrong way around, as it will now return `false` if the email is empty. Instead of the whole ternary assignment, you can just cast the value to a boolean: `const emptyEmail = !emailValue` – Cerbrus Oct 28 '22 at 11:49
-3
const emptyEmail = emailValue ? true : false;