1

I am working with a form validation using JavaScript. When submit the form, the warning statement would appear under the input tag. However, if I click again, the warning statement would be created again. I understand there is a method that we can use HTML to solve this issue. But I was wondering how to solve only using JavaScript.

const form = document.querySelector('.apply__form');


form.addEventListener('submit', e => {
  e.preventDefault();
  const requireAnswers = document.querySelectorAll('.answer');
  for (let requireAnswer of requireAnswers) {
    if (requireAnswer.parentElement.classList.contains('required') && !requireAnswer.value) {
      const warningStatement = document.createElement('p');
      warningStatement.classList.add('warning__message');
      warningStatement.innerText = `Please fill ${requireAnswer.previousElementSibling.innerText}`;
      requireAnswer.parentElement.appendChild(warningStatement);
    }
  }
})
body, html {
  box-sizing: border-box;
  font-size: 16px;
}

.wrapper {
  width: 100%;
  background:#f0f0f0;
  padding: 30px 0;
}

.apply__form {
  border-top: 8px solid #085a23;
  margin: 0 auto;
  max-width: 645px;
  background: #fff;
  padding: 50px;
}

.form__title {
  font: normal normal bold 1.8rem "Microsoft JhengHei";
}

.event__info {
  margin: 2rem 0;
  font: normal normal normal 0.9rem "Microsoft JhengHei";
}

.event__info .event__place {
  margin-top: 0.5rem;
}

.notice {
  color: #e74149;
  font: normal normal normal 1rem "Microsoft JhengHei";
}

.notice::before {
  content: "*";
  padding-right: 5px;
}

.questions {
  width: 100%;
}

.question {
  font: normal normal normal 1rem "Microsoft JhengHei";
  margin-top: 50px;
}

.question .question__title {
  margin-bottom: 20px;
}

.question .question__title::after {
  content: "*";
  color: #e74149;
  padding-left: 5px;
}

.question:nth-child(4) .type1 {
  margin-bottom: 23px;
}

.question:nth-child(6) .question__title::after {
  content: none;
}

.sub__title{
  margin-bottom: 30px;
}

.question .answer {
  width: 250px;
  padding: 5px;
}

.button__section {
  margin-top: 55px;
  font: normal normal normal 1rem "Microsoft JhengHei";
}

.submit__btn {
  background: #fad312;
  border-radius: 3px;
  outline: none;
  border: none;
  padding: 1rem 2rem;
  margin-bottom: 20px;
  cursor: pointer;
}

.warning {
  font-size: 14px;
}

.copy__right {
  height: 30px;
  background: #000;
  color: #999;
  text-align: center;
  padding: 15px 0;
  line-height: 30px;
  font-family: "Microsoft JhengHei";
}

.warning__message {
  color: #e74149;
  font-size: 14px;
  position: absolute;
}
<!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="reset.css">
  <link rel="stylesheet" href="style.css">
  <title>Lazy-Form</title>
</head>

<body>
  <div class="wrapper">
    <form class="apply__form">
      <h1 class="form__title">Form</h1>
      <div class="event__info">
        <p class="event__time">Event date</p>
        <p class="event__place">Event Location</p>
      </div>
      <h3 class="notice">Must</h3>
      <div class="questions">
        <div class="question required">
          <p class="question__title">Nickname</p>
          <input type="text" placeholder="Answer" class="answer">
        </div>
        <div class="question required">
          <p class="question__title">email</p>
          <input type="text" placeholder="Answer" class="answer">
        </div>
        <div class="question required">
          <p class="question__title">phone</p>
          <input type="text" placeholder="Answer" class="answer">
        </div>
        <div class="question required">
          <p class="question__title">type</p>
          <div class="type1">
            <input type="radio" name="answer" id="bed">
            <label for="bed">dream</label>
          </div>
          <div class="type2">
            <input type="radio" name="answer" id="phone">
            <label for="phone">walk around</label>
          </div>
        </div>
        <div class="question required">
          <p class="question__title">How do you know?</p>
          <input type="text" placeholder="Answer" class="answer">
        </div>
        <div class="question">
          <p class="question__title">Others</p>
          <input type="text" placeholder="Answer" class="answer">
        </div>
      </div>
      <div class="button__section">
        <button class="submit__btn">Submit</button>
      </div>
    </form>
  </div>
  <script src="app.js"></script>
</body>

</html>

2
  • It's not super clear what the problem is. "However, if I click again, the warning statement would be created again." What does that mean? When you click submit again right away the message stays? The message duplicates and there are now 2? It appears even when you've fixed the input text? Commented Jul 27, 2020 at 13:12
  • Sorry about this confusion. What I mentioned is that if I click the submit button, there is a new warning message after the old one if checking the elements page in the DevTools. Commented Jul 27, 2020 at 13:21

1 Answer 1

2

Use an if statement along with .querySelectorAll with .length to check for the existence of a warning label for the given answer's parent:

if (requireAnswer.parentElement.classList.contains('required') && !requireAnswer.value) {
      //Check to see if the parentElement has an element with className .warning__message
      //If .length is zero, it will create a warning element, else it will skip it
      if(!requireAnswer.parentElement.querySelectorAll('.warning__message').length){
          const warningStatement = document.createElement('p');
          warningStatement.classList.add('warning__message');
          warningStatement.innerText = `Please fill 
          ${requireAnswer.previousElementSibling.innerText}`;
          requireAnswer.parentElement.appendChild(warningStatement);
      }
      
}
Sign up to request clarification or add additional context in comments.

Comments

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.