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

Tell us what’s happening:

I cannot seem to pass all of the tests for this project despite the output seeming to be correct. I pass the first test:

" 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."

but the remaining tests fail. I have tested my regex with every test phone number in the tests, they all act accordingly. I have modified this line:

output.innerHTML += <h2 class="output-text">${el}</h2>;

to either

output.innerText += el;
OR
output.textContent += el;

with no success. I can’t find the problem with my output.

Thank you for your time.

Your code so far

<!-- file: index.html -->
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href = "styles.css">
    <title>US Telephone number validator</title>
  </head>
  <body>
    <main>
      <h1 id="title">US Telephone number validator</h1>
      <div class="phone-container">
        <div class="phone-header">
          <div class="phone-camera"></div>
        </div>
        <div class="phone-screen">
          <label for="user-input">Enter a phone number</label>
          <input id="user-input" type="text"/>
          <div id="results-div">
          </div>
        </div>
        <div class="phone-footer">
          <button id="check-btn">Check</button>
          <button id="clear-btn">Clear</button>
        </div>
      </div>
    </main>
    <script src="script.js"></script>
  </body>
</html>
/* file: styles.css */
:root {
  --dark-grey: #1a1a1a;
  --grey: #4d4d4d;
  --light-grey: #d9d9d9;
}

*, 
*::before, 
*::after {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  background-color: var(--grey);
  color: white;
  font-family: tahoma;
}

main {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

#title {
  margin: 50px;
  text-align: center;
}

.phone-container {
  height: 500px;
  width: 300px;
  background-color: var(--dark-grey);
  border-radius: 20px;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
}

.phone-header {
  height: 30px;
  width: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
}

.phone-camera {
  height: 20px;
  width: 20px;
  border-radius: 50%;
  background-color: var(--grey);
}

.phone-screen {
  color: var(--dark-grey);
  height: 400px;
  width: 90%;
  background-color: var(--light-grey);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-start;
}

label {
  margin: 15px;
  font-size: 1.5rem;
}

#user-input {
  height: 3rem;
  font-size: 1.5rem;
  width: 80%;
  margin-bottom: 50px;
}

#results-div {
  height: 200px;
  width: 80%;
  overflow-y: auto;
}

.phone-footer {
  height: 50px;
  width: 100%;
  display: flex;
  flex-direction: row;
  align-items: center;
  justify-content: center;
}

#check-btn, #clear-btn {
  height: 70%;
  width: 100px;
  margin: 10px;
}

.output-text {
  text-align: center;
  margin-bottom: 10px;
}
/* file: script.js */
const userInput = document.getElementById("user-input");
const checkBtn = document.getElementById("check-btn");
const clearBtn = document.getElementById("clear-btn");
const output = document.getElementById("results-div");

const regex = /^1? ?(\(\d{3}\)|\d{3})[ -]?\d{3}[ -]?\d{4}$/;
const outputArr = [];

const checkInput = (str) => {
  if (userInput.value === "") {
    alert("Please provide a phone number");
  } else if (regex.test(str)) {
    outputArr.push(`Valid US number: ${str}`);
    updateOutput(outputArr);
  } else {
    outputArr.push(`Invalid US number: ${str}`);
    updateOutput(outputArr);
  }
};

const updateOutput = (array) => {
  output.innerHTML = "";
  array.forEach((el) => {
    output.innerHTML += `<h2 class="output-text">${el}</h2>`;
  });
};

const clearOutput = () => {
  outputArr.length = 0;
  output.innerHTML = "";
};

checkBtn.addEventListener("click", () => {
  checkInput(userInput.value);
  userInput.value = "";
});

userInput.addEventListener("keydown", (e) => {
  if (e.key === "Enter") {
    checkInput(userInput.value);
    userInput.value = '';
  }
});

clearBtn.addEventListener("click", clearOutput);

Your browser information:

User Agent is: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:121.0) Gecko/20100101 Firefox/121.0

Challenge Information:

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

It is because you are concatenating to the output output.innerHTML +=. Make that an assignment instead (or I guess you can clear it between).

That is certainly not it, lasjorg. The final project allows for multiple text elements to be in the #results-div element.

This is more complex, but I figured it out. It has to do with the way you handle updateOutput and specifically, that first line that is clearing the innerHTML and rebuilding it each time. Although you can technically code this that way, it is highly inefficient because every time you add another phone number to the stack, the element is dumped, and then re-rendered. And it has caught the parser offguard when it’s trying to read the element.

To solve this, do not dump the content inside of your #results-div. Instead, append the Valid US number: and Invalid US number: strings to #results-div each time. The parser doesn’t care what element you use: h2, p, div, etc. to display Valid or Invalid.

1 Like

I guess technically it is because you are not cleaning the outputArr array between runs. The test is cleaning the results-div element between runs but because you are not clearing the outputArr array (unless the clear button is clicked) the end result is it will use the content of the array from the previous run.

Edit: just so it is clear what I mean.

const updateOutput = (array) => {
  output.innerHTML = "";
  array.forEach((el) => {
    output.innerHTML += `<h2 class="output-text">${el}</h2>`;
  });
  outputArr.length = 0; // clear array
};
1 Like

Thank you both for looking at this. lasjorg’s original comment did pass all the tests but I will try to make this more efficient as well.

1 Like

I guess either way works, but clearing the array might be the more “correct” solution.