Search code examples
javascriptdom-manipulation

Adding classes during runtime to html elements not working as expected


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/


Solution

  • 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 protected]</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