Build a Telephone Number Validator Project - Build a Telephone Number Validator

Tell us what’s happening:

I have written all of the code and everything works fine but when i run the tests only the first 6 user stories pass and everything else fails. The failed ones say:

When the #user-input element contains 1 555-555-5555 and the #check-btn element is clicked, the #results-div element should contain the text “Valid US number: 1 555-555-5555”.

and

Failed:When the #user-input element contains (275)76227382 and the #check-btn element is clicked, the #results-div element should contain the text "Invalid US number: (275)76227382".

Your code so far

<!DOCTYPE html>
<html lang="en">
<head>
  <title>Telephone Number Validator</title>
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta charset="UTF-8">
  <link rel="stylesheet" href="styles.css">
  <!-- Fonts -->
  <link rel="preconnect" href="https://fonts.googleapis.com">
  <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <link href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap" rel="stylesheet">
</head>
<body>
  <h1>Telephone Number Validator</h1>
  <div id="input-div">
    <label id="input-label">Enter phone number</label>
    <input type="text" id="user-input" maxlength= "16">
  </div>
    <!-- RESULTS -->
    <p id="result-text" class="hidden"></p>
    <div id="results-div" class="hidden">

    </div>

  <div id="button-div">
    <button id="check-btn">Check</button>
    <button id="clear-btn">Clear</button>
  <div>
  <script src="script.js"></script>
</body>
const userInput = document.getElementById("user-input");
const result = document.getElementById("result-text");
const checkButton = document.getElementById("check-btn");
const clearButton = document.getElementById("clear-btn");
const logDiv = document.getElementById("results-div");

const numberRegex = /(?:^)1?[^2-9|0]?(\([0-9][0-9][0-9]\)|[0-9][0-9][0-9])[\s-]?[0-9][0-9][0-9][\s-]?[0-9][0-9][0-9][0-9](?:$|\s)/

const isValid = (num) => numberRegex.test(num)

let resultLog = [];

let counter = 0;

checkButton.addEventListener("click", () => {
  if(userInput.value === ""){
    alert("Please provide a phone number");
    return;
  }

  // result.textContent = isValid(userInput.value) ? "Valid" : "Not valid";

  if(isValid(userInput.value)){
    resultLog.push(userInput.value);
    logDiv.classList.remove("hidden");

  if(!document.getElementById("log-head")){
    const logHead = document.createElement("p");
    logHead.id = "log-head";
    logHead.textContent = "Result Log";
    logDiv.appendChild(logHead);
  }

  if(counter < 3){
    const logEl = document.createElement("p");
    logEl.id = "log-el";
    logDiv.appendChild(logEl);
    logEl.textContent = userInput.value;
    counter++;
  }

  if(resultLog.length > 3){
    const logEl1 = logDiv.querySelector(":nth-child(2)");
    const logEl2 = logDiv.querySelector(":nth-child(3)");
    const logEl3 = logDiv.querySelector(":nth-child(4)");

    resultLog[2] = resultLog[1];
    resultLog[1] = resultLog[0];
    resultLog[0] = userInput.value;
    logEl3.textContent = resultLog[2];
    logEl2.textContent = resultLog[1];
    logEl1.textContent = resultLog[0];
  }

  result.classList.remove("hidden");
  result.textContent = `Valid US number: ${userInput.value}`;
  userInput.value = "";
    

  }else if(!isValid(userInput.value)) {
    result.classList.remove("hidden");
    result.textContent = `Invalid US number: ${userInput.value}`;
  }
  console.log(resultLog)
})

clearButton.addEventListener("click", () => {
  counter = 0;
  result.textContent = "";
  result.classList.add("hidden");
  while(logDiv.firstChild) {
    logDiv.removeChild(logDiv.firstChild);
  }
  resultLog = [];
})
body {
  margin: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #082032
}

h1 {
  font-family: Poppins;
  font-size: 35px;
  color: #B85C38;
  text-align: center;
  transition: 0.5s;
}

#input-div {
  display: flex;
  flex-direction: column;
  align-items: center;
  color: #ffffff;
  font-size: 25px;
  font-family: Poppins;
}

#input-label {
  text-align: center;
  transition: 0.5s;
}

#user-input {
  width: 230px;
  height: 48px;
  margin-top: 10px;
  margin-bottom: 10px;
  background-color: #2C394B;
  border: none;
  border-radius: 10px;
  transition: 0.5s;
  color: white;
  font-size: 25px;
  text-align: center;
}

#user-input:hover, #user-input:focus {
  border-radius: 30px;
  outline: none;
  background-color: #334756;
}

#button-div {
  display: flex;
  justify-content: center;
}

#check-btn {
  width: 80px;
  height: 35px;
  margin-top: 10px;
  margin-bottom: 10px;
  background-color: #2C394B;
  border: none;
  border-radius: 8px;
  transition: 0.3s;
  color: white;
  font-size: 15px;
  text-align: center;
  cursor: pointer;
  margin-right: 10px;
}

#check-btn:hover {
  border-radius: 12px;
  outline: none;
  background-color: #2C3947;
}

#clear-btn {
  width: 80px;
  height: 35px;
  margin-top: 10px;
  margin-bottom: 10px;
  background-color: #2C394B;
  border: none;
  border-radius: 8px;
  transition: 0.3s;
  color: white;
  font-size: 15px;
  text-align: center;
  cursor: pointer;
  margin-left: 10px;
}

#clear-btn:hover {
  border-radius: 12px;
  outline: none;
  background-color: #2C3947;
}

#result-text {
  font-size: 20px;
  font-family: Poppins;
  color: white;
  letter-spacing: 0.4px;
  margin: 10px 0px
}

#results-div {
  padding: 0px;
  width: 240px;
  display: flex;
  flex-direction: column;
  align-items: center;
}

#log-head {
  font-size: 20px;
  font-family: Poppins;
  color: white;
  margin-bottom: 10px;
}

#log-el {
  list-style-type: none;
  color: white;
  font-family: Poppins;
  margin: 5px;
}

.hidden {
  display: none;
}

@media screen and (max-width: 370px){
  h1 {
    font-size: 30px;
  }

  #input-label {
    font-size: 20px;

  }

/*  */
  #log-head {
    font-size: 20px;
  }

  #log-el {
    font-size: 16px;
  }
/*  */

  #user-input {
    width: 200px;
    height: 43px;
    font-size: 20px;
  }

}

@media screen and (max-width: 317px) {
  h1 {
    font-size: 25px;
  }
}

Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36

Challenge Information:

Build a Telephone Number Validator Project - Build a Telephone Number Validator

Get rid of the global variables

Can you please explain why I need to remove the global variables?

Global variables can destroy the reusability of your functions because there isn’t a magic code fairy going around resetting them for you. I don’t like that so many of the practice projects teach global variable abuse as it makes debugging your projects much harder.

Understood. So if i remove them, wouldnt the resultLog and counter reset if i put them inside of the event listener?

I would pass everything around as function arguments and return values

Okay, thanks. Will try and see how it goes :slight_smile:

1 Like

Hmm… it seems like i need some help with this. Do i need to create another function with arguments (counter and resultLog[ ])? If so, can you explain how its gonna work? Also, how can i have an array as an argument?

I do not want to reset the resultLog[ ] and counter unless “clear” button is clicked. I cant think of another way to make this code work lol.

Forgot to upload this image just to explain better. I mean, everything works just fine but idk why it wont pass

You should get rid of both of those variables.

Okay, but please explain what i should do after. Im not understanding how to make the code work if i get rid of these variables.

I can’t design the answer for you though.

Do you know what function arguments and return values are? You should only use function arguments and return values for your stateful data.

I know what they are. Ill try to figure it out and reply to your message with what i come up with

For example, why does resultLog need to be available outside of this function?

I have declared resultLog outside of the event listeners because i need to use it on both and i want it to store the userInput values. This array should not be reset until the user clicks the “clear” button.

If, for example i declare it on the checkButton.addEventListener(…) the array will be reset whenever i click the “check” button

Why is it absolutely required in the global scope though? Having to hide information in the global scope means your logic isn’t well encapsulated, which then leads to the sorts of bugs you’re seeing.

Okay, will try to come up with a solution

I came up with this one. I created a function that holds the variables and event listeners and i call the function at the end of the code. This way i remove the global variables like you said so now they are only local variables and usable only inside the function that i created.

The code looks like this:

function encapsulatedVar() {
let resultLog =[ ]; // i removed the variable from the global scope

let counter = 0; // i removed this variable from the global scope too


rest of the code

}

encapsulatedVar();

But the project still wont pass. It fails the same user stories.

The new function is being called where? Still being called in the global scope?

Yeah, that doesn’t look like it actually addresses the issue.

Why can’t this function hold all of your logic instead of hiding state outside of this function?