0

I am trying to create a form with some basic client side validation. In the form i have 3 input fields for, username, email and password. Initially they have a common class that is input. Also i attached a sibling paragraph element to these input elements, these paragraph element contains some input specification that has to be displayed to user if user enters something invalid.

In CSS i have basically created two classes, valid and invalid, valid just turns the border of input elements to green, and invalid turns border to red and sets the paragraph element opacity to 1 from 0(initial style).

In script file to check validity of user's input i have three boolean variables, isUserNameValid, isEmailValid, isPasswordValid, all these three are initially set to false.

Now i am adding these CSS classes during runtime as user inputs. Adding classes (valid and invalid) is working fine for first input element that is username input element, but as soon as i go to next input element that is email and type a single letter, script is adding class valid to email input element instead of invalid, even though isEmailValid is false.

I tried my best to figure out why it's adding class valid even though i am explicitly saying if the isEmailValid is equals to false add a class of invalid and remove class valid, instead it's doing the opposite.

I have attached the fiddle link, also i am not very much experienced in JavaScript, so, explanation in simple English is appreciated.

    if(username.length > 5) {
        isUserNameValid = true
    }
    if(email.length > 10) {
        isEmailValid = true
    }
    if(password.length > 10) {
        isPasswordValid = true
    }

    if(isUserNameValid === true && isEmailValid === true && isPasswordValid === true) {
        loginButton.disabled = false
        loginButton.style.cursor = 'pointer'
    } else {
        console.log('username',username, isUserNameValid)
        console.log('email',email, isEmailValid)
        console.log('password',password, isPasswordValid)
        loginButton.disabled = true
        loginButton.style.cursor = 'default'
        if(isUserNameValid === false) {
            e.target.classList.add('invalid')
            e.target.classList.remove('valid')
        }
        if(isEmailValid === false) {
            e.target.classList.add('invalid')
            e.target.classList.remove('valid')
        }
        if(isPasswordValid === false) {
            e.target.classList.add('invalid')
            e.target.classList.remove('valid')
        }
        if(isUserNameValid === true) {
            e.target.classList.add('valid')
            e.target.classList.remove('invalid')
        }
        if(isEmailValid === true) {
            e.target.classList.add('valid')
            e.target.classList.remove('invalid')
        }
        if(isPasswordValid === true) {
            e.target.classList.add('valid')
            e.target.classList.remove('invalid')
        }
    }

FIDDLE LINK: https://jsfiddle.net/weg9jy0c/5/

Ayush Mishra
  • 267
  • 3
  • 14
  • Does this answer your question? [How to validate an email address in JavaScript](https://stackoverflow.com/questions/46155/how-to-validate-an-email-address-in-javascript) – kmoser May 12 '20 at 08:28
  • @kmoser no, my question is not about how to validate email address – Ayush Mishra May 12 '20 at 08:30
  • @kmoser i am not able to figure out why its adding a class of valid even though while console logging the boolean variable isEmailValid its false and i have given a condition where if isEmailValid is set to false add class of invalid, but its adding valid, hence its doing opposite. – Ayush Mishra May 12 '20 at 08:36
  • 1
    e.target refers to the element that triggered the validation. Without checking what the target actually is, you just go and blindly set classes on it. Oops! Add `console.log('e.target = ' + e.target.name)` to line 3 of your fiddle's JS (make it the first statement that executes) See the problem now? – enhzflep May 12 '20 at 08:36
  • 1
    Don't do it in this way, mix every field validation together will make you and others headache. Check `e.target` on which field, and do validation on that field only. – Jack Ting May 12 '20 at 08:39
  • Your JS code is not the same as the JSFiddle code. Does the JSFiddle code do what you want? – kmoser May 12 '20 at 08:40
  • @kmoser i just posted a part of js fiddle code. – Ayush Mishra May 12 '20 at 08:42
  • 1
    This is the quick fix https://jsfiddle.net/Lsf9va5d/ – Nick May 12 '20 at 08:44
  • @Nick, i am beginner in js, so what i learnt is e.target refers to where event occurred, so if i am doing some event of (keyup) in this case, on email input,so as per my understanding e.target refers to email input, so why can't i change values on e.target. I mean why should i select that input element with id #email, even though it refers to e.target only. It would be great if you could please explain this. – Ayush Mishra May 12 '20 at 08:51
  • 1
    @enhzflep explained what was wrong in their comment. Those blocks of code check whether a particular input is valid but then set the class of the input that triggered the event to valid regardless of whether that is the input which is valid or not. – Nick May 12 '20 at 08:53

1 Answers1

1

will this work for you?

https://jsfiddle.net/gnca42xp/1/

const form = document.querySelector('.main-form')
form.addEventListener('keyup', (e) => {
  const loginButton = document.querySelector('.login-btn')
  const username = document.querySelector('#name').value
  const email = document.querySelector('#email').value
  const password = document.querySelector('#password').value
  let isUserNameValid = false;
  let isEmailValid = false;
  let isPasswordValid = false;

  currentUpdateField = e.target.getAttribute('id');

  if (username.length > 5) {
    isUserNameValid = true
  }
  if (email.length > 10) {
    isEmailValid = true
  }
  if (password.length > 10) {
    isPasswordValid = true
  }

  if (isUserNameValid === true && isEmailValid === true && isPasswordValid === true) {
    e.target.classList.remove('invalid')
    loginButton.disabled = false
    loginButton.style.cursor = 'pointer'
  } else {
    console.log('username', username, isUserNameValid)
    console.log('email', email, isEmailValid)
    console.log('password', password, isPasswordValid)
    loginButton.disabled = true
    loginButton.style.cursor = 'default'
    if (isUserNameValid === false && currentUpdateField === 'name') {
      e.target.classList.add('invalid')
      e.target.classList.remove('valid')
    }
    if (isEmailValid === false && currentUpdateField === 'email') {
      e.target.classList.add('invalid')
      e.target.classList.remove('valid')
    }
    if (isPasswordValid === false && currentUpdateField === 'password') {
      e.target.classList.add('invalid')
      e.target.classList.remove('valid')
    }
    if (isUserNameValid === true && currentUpdateField === 'name') {
      e.target.classList.add('valid')
      e.target.classList.remove('invalid')
    }
    if (isEmailValid === true && currentUpdateField === 'email') {
      e.target.classList.add('valid')
      e.target.classList.remove('invalid')
    }
    if (isPasswordValid === true && currentUpdateField === 'password') {
      e.target.classList.add('valid')
      e.target.classList.remove('invalid')
    }
  }

})
.input {
  outline: none;
}

.valid {
  border: 1px solid rgb(89, 224, 89);
}

input+p {
  opacity: 0;
}

.invalid {
  border: 2px solid rgb(245, 101, 101);
}

input.invalid+p {
  opacity: 1;
  color: orange;
}
<html>
<title>Demo Form</title>

<body>
  <form class="main-form" method="post">
    <input class="input" type="text" name="username" id="name" placeholder="Username">
    <p>Username must have more than 5 characters</p>
    <input class="input" type="email" name="email" id="email" placeholder="Email">
    <p>Email must of format <b>email@site.domain</b></p>
    <input class="input" type="password" name="password" id="password" placeholder="Password">
    <p>Password must have more than 5 characters and aplhanumeric with a special character</p><br>
    <button type="submit" class="login-btn" disabled>Register</button>
  </form>
</body>

</html>

What happens in your case

1) First user enters data in username it is valid after 5 characters 2) then user enters data in email field, here e.target is email field, but as from your code, isUsernameInvalid is defined false, and added class to e.target which is email field.

That is why your code is not working

So what i have done is,

I am getting id on the current updating field, and then adding or removing classes only if id matches

Kiran Shinde
  • 5,732
  • 4
  • 24
  • 41