1

GOAL: I want the valid icon to show when the input has a valid attribute of true. and the invalid icon to show when it's false && the input has a length of 1 or more characters.

(phoneInputs function): in the console, it outputs "incomplete" for every keypress until the length = 10. When it reaches 10 characters, it says good and sets the valid attribute to true.

(formCheck function): adds or removes a .hidden class depending upon the length. (This is the part that isn't working because I'm trying to target the input's valid attribute. The attribute via the inspector seems to be working and functioning perfectly, via the phoneInputs function)

I've tried console.log() the following:

  1. input.target - shows the correct input element.
  2. input.target.valid - undefined
  3. input.target.getAttribute('valid') - returns an error

Any help?

https://codepen.io/gold240sx/pen/wvyqPpP?editors=1111

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <script src="https://kit.fontawesome.com/1758b3260f.js" crossorigin="anonymous"></script>
  <style>
       .hidden {
          display: none;
       }
  </style>
  <script>
    const formCheck = (input) => {
       const chxVer = input.target.parentElement.querySelector('.bool-form-val')
       const validIco = chxVer.querySelector('.check')
       const invalidIco = chxVer.querySelector('.x')

       if (input.target.getAttribute("valid")==true) {
           validIco.classList.remove('hidden')
           invalidIco.classList.add('hidden')
       } else if (input.target.getAttribute("valid")==false) {
           input.target.setAttribute('valid', false)
           console.log(input.target.valid)
           validIco.classList.add('hidden')
           invalidIco.classList.remove('hidden')
       } else {}
       console.log(input.target.getAttribute("valid"))
   }

   const phoneInputs = document.querySelectorAll('.phone-number');
   phoneInputs.forEach((input) => {

       const boolFormChecks = document.querySelectorAll('.bool-form-val');

       input.addEventListener('keyup', (e) => {
    
           formCheck(e)
           //US numbers only
           if (input.value.length === 10) {
               input.setAttribute('valid', true)
               // console.log(input.target.isValid)
               console.log('phone number good')
               console.log(input.value) //Outputs final phone number
           } else {
              // console.log(input.validity.valid)
              input.setAttribute('valid', false)
              // console.log(input.value.length)
              console.log("incomplete")
           }
       })
    })
  </script>
  <title>Document</title>
</head>
<body>
    <div class="input">
      <input 
         type="text"
         name="phoneNumber" 
         id="signup-phoneNumber" 
         placeholder="Phone Number" 
         class="icoinput phone-number" 
         maxlength="10"
      >
      <div class="bool-form-val">
        <i class="fa-solid fa-square-check check hidden"></i>
        <i class="fa-solid fa-square-x x hidden"></i>
      </div>
  </div>
</body>
</html>
3
  • input.getAttribute('valid') ? Commented May 22, 2022 at 21:10
  • console.log(input.getAttribute('valid'))- Returns: TypeError: input.getAttribute is not a function. (In 'input.getAttribute('valid')', 'input.getAttribute' is undefined),... hence the target. EDIT: I should add, this is being inserted right above the if statement within the formCheck function. Commented May 22, 2022 at 21:18
  • 1
    @MichaelMartell You're calling formCheck before adding the attribute valid to the input. You need to place the function call after you set the attribute. Commented May 22, 2022 at 21:31

1 Answer 1

1

You have two issues:

  1. getAttribute() always returns a string but you compare it with true and this comparison will always be false. You should instead do input.target.getAttribute("valid") == "true".
    For the opposite check, you should just do it in the else, there's no need for a input.target.getAttribute("valid") == "false" (which won't work anyway since you never set the value to false).

  2. You do formCheck(e) at the beginning of the keyup listener, before setting the valid attribute in the next lines. That means if you type the 10th character, you check the value of valid, which is still not true, and THEN since it's the 10th character you set it to true.
    You should thus do formCheck(e) at the end of the function.

Here's your code with the 2 fixes done:

const formCheck = (input) => {
  const chxVer = input.target.parentElement.querySelector('.bool-form-val')
  const validIco = chxVer.querySelector('.check')
  const invalidIco = chxVer.querySelector('.x')

  if (input.target.getAttribute("valid") == "true") {
    validIco.classList.remove('hidden')
    invalidIco.classList.add('hidden')
  } else {
    input.target.setAttribute('valid', false)
    console.log(input.target.valid)
    validIco.classList.add('hidden')
    invalidIco.classList.remove('hidden')
  }
  console.log(input.target.getAttribute("valid"))
}

const phoneInputs = document.querySelectorAll('.phone-number');
phoneInputs.forEach((input) => {

  const boolFormChecks = document.querySelectorAll('.bool-form-val');

  input.addEventListener('keyup', (e) => {


    //US numbers only
    if (input.value.length === 10) {
      input.setAttribute('valid', true)
      // console.log(input.target.isValid)
      console.log('phone number good')
      console.log(input.value) //Outputs final phone number
    } else {
      // console.log(input.validity.valid)
      input.setAttribute('valid', false)
      // console.log(input.value.length)
      console.log("incomplete")
    }
    formCheck(e)

  })
})
.hidden {
  display: none;
}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <script src="https://kit.fontawesome.com/1758b3260f.js" crossorigin="anonymous"></script>
  <title>Document</title>
</head>

<body>
  <div class="input">
    <input type="text" name="phoneNumber" id="signup-phoneNumber" placeholder="Phone Number" class="icoinput phone-number" maxlength="10">
    <div class="bool-form-val">
      <i class="fa-solid fa-square-check check hidden"></i>
      <i class="fa-solid fa-square-x x hidden"></i>
    </div>
  </div>
</body>

</html>

Sign up to request clarification or add additional context in comments.

5 Comments

Wouldn't the input.target.getAttribute("valid")==true comparison usually succeed, since non-empty strings are truthy and it's not a strict comparison? Or do I need to be whacked with a wet trout?
The loose equality operator (==) compares both value after converting them to a common type. For a string and a boolean, they are both converted to numbers before comparing. Number("true") is NaN and Number(true) is 1. And since NaN is not equal to 1, "true" is not equal to true.
Oh, huh. I guess I never realized "truthy" only means that if (<truthy value>) will succeed
Yes! You could also think of it like this: a value is truthy if Boolean(value) returns true!
Thank you for the descriptive explanation! getAttribute is new to me so this definitely, although seemingly minuscule, was a very important and wonderful thing to learn! Thank you so much for your time and help! <br><br> P.S. The whacked with a wet trout was funny as hell!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.