1

I made a form with js validation that sets an error function (setErrorFor) if the input is not valid. The form has a submit button that shows an animated checkmark if the input is valid (function showSucces). When the input is not valid it needs to not show that checkmark. So I created a function (stopSendingData) to prevent the succes function from executing. But now the checkmark is not showing at all, even if the input is valid.

So I tried to change the if statement in the stopSendingData function and I tried it by changing the way to stop it but non of the attempts made the checkmark only showing when the input is valid. I really look forward to hear from what I am doing wrong and how to solve this.

// Listen for a submit
document.querySelector(".contactForm").addEventListener("submit", submitForm);

function submitForm(e) {
  e.preventDefault();

  checkInputs(); //val
  showSucces();
}

function showSucces() {
  document.getElementById("submitButton").classList.add("clicked");
  setTimeout(() => {
    document.getElementById("submitButton").classList.remove("clicked");
  }, 4000);
}

//form validaton
const namecontact = document.getElementById('namecontact'); //Val
const email = document.getElementById('email'); //Val
const message = document.getElementById('message'); //Val

function checkInputs() {
  //Get the values from the inputs
  const nameValue = namecontact.value.trim();
  const emailValue = email.value.trim();
  const messageValue = message.value.trim();
  const numbers = /^[0-9]+$/;

  if (nameValue === '') {
    setErrorFor(namecontact, "Name cannot be blank.");
  }

  if (nameValue.match(numbers)) {
    setErrorFor(namecontact, "Name can not contain number(s).");
  }

  if (emailValue === '') {
    setErrorFor(email, "Email cannot be blank.");
  } 
  else if (!isEmail(emailValue)) {
    setErrorFor(email, 'Email is not valid.');
  }

  if (messageValue === '') {
    setErrorFor(message, "Message cannot be blank.");
  }
  
  stopSendingData();
}

function setErrorFor(input, errorMessage) {
  const formControl = input.parentElement; //.form-control
  const small = formControl.querySelector('small');

  //add error message inside small
  small.innerText = errorMessage;

  // add error class
  formControl.className = 'form-control error';
}

function isEmail(email) {
  return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(email);
}

function stopSendingData() {
  // const small = document.querySelector('small');
  const small = getElementsByTagName('small');
  const formControl = small.parentElement; //.form-control
  
  if (formControl.className = 'form-control error') {
    return false;
  }
}
.contactForm {
  flex: 0%;
  margin: 0px 0px;
  width: 21%;
  position: absolute;
  margin: 90px 0px 0px 10.5px;
  left: 0px;
  /* max-width : 100%; */
  /* opacity   : 0.39; */
}

.name,
.email,
.subject {
  position: relative;
  width: 279px;
  height: 39px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

.message {
  position: relative;
  width: 279px;
  height: 60px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

::placeholder {
  margin-top: 0px;
  font-size: 12px;
}

.fas.fa-exclamation-circle {
  color: red;
  width: 15px;
  height: 15px;
  position: absolute;
  /* visibility : visible; */
  top: 15px;
  right: 60px;
}


/* 
.form-control input {
    border : 1px solid transparent;
  } */

.form-control {
  position: relative;
}

.form-control i.fas.fas.fa-exclamation-circle {
  visibility: hidden;
}

small {
  position: absolute;
  left: 75px;
  visibility: hidden;
  top: 24.9px;
  font-size: 13.5px;
  font-weight: bolder;
  z-index: 9;
  width: 300px;
}

.form-control.error input {
  border-color: red;
}

.form-control.error textarea {
  border-color: red;
}

.form-control.error i.fas.fas.fa-exclamation-circle {
  visibility: visible;
  color: red;
}

.form-control.error small {
  color: red;
  visibility: visible;
}

#submitButton {
  margin: 9px 0px 0px 42px;
  width: 277.2px;
  height: 27px;
}

#submitButton {
  position: relative;
  cursor: pointer;
  height: 30px;
  width: 90px;
  transition: all 1250ms cubic-bezier(0.19, 1, 0.22, 1);
}

#submitButton.clicked {
  background-color: rgb(4, 221, 250);
  color: rgb(21, 21, 24);
  font-weight: bold;
  font-size: 16.2px;
  opacity: 0.6;
  padding-top: 1.7px;
}

#submitButton.clicked span {
  animation: spanShrink 1.8s ease-in-out forwards;
}

@keyframes spanShrink {
  15% {
    opacity: 0;
  }
  85% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#submitButton .checkmark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  stroke-width: 3;
  stroke: rgb(18, 19, 19);
  stroke-miterlimit: 10;
  width: 51px;
  height: 51px;
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
}

#submitButton.clicked .checkmark {
  animation: stroke 1.5s ease-in-out 0.6s forwards;
}

@keyframes stroke {
  20% {
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dashoffset: 0;
  }
  70% {
    stroke-dashoffset: 48;
  }
}
<form method="POST" class="contactForm" id="form">
  <div class="form-control">
    <input class="name" id="namecontact" type="text" placeholder="Name" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation1"></i>
    <small></small>
  </div>
  <div class="form-control">
    <input class="email" id="email" placeholder="E-mail" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation2"></i>
    <small></small>
  </div>
  <div class="form-control">
    <input class="subject" type="text" placeholder="Subject" /><br>
  </div>
  <div class="form-control">
    <textarea class="message" id="message" cols="30" rows="10" placeholder="Message"></textarea><br>
    <i class="fas fa-exclamation-circle" id="exclamation4"></i>
    <small></small>
  </div>
  <button id="submitButton" type="submit">
    <span>Launch</span>
    <svg class="checkmark" viewBox="0 0 52 52">
      <path fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
    </svg>
  </button>
  
  </div>
  
</form>
biberman
  • 5,606
  • 4
  • 11
  • 35
Zenz
  • 31
  • 9

3 Answers3

1

To solve your problem you simply have to move the call of showSucces() to the end of stopSendingData(). Otherwise you call it everytime when the form is submitted, even if the check failes.


By the way: There are some issues in your code:

  • you have to call getElementsByTagName() with document. before it:
const small = document.getElementsByTagName('small');
  • getElementsByTagName() produces a collection of elements, not a single one, so that you can't get a parent element this way. Therefor you have to loop over the collection:
for (i = 0; i < small.length; i++) {
  if (small[i].parentElement.classList.contains('error')) {
    return false;
  }
}
  • you have a closing div to much (at the end of the form)

Working example:

// Listen for a submit
document.querySelector(".contactForm").addEventListener("submit", submitForm);

function submitForm(e) {
  e.preventDefault();

  checkInputs(); //val
}

function showSucces() {
  document.getElementById("submitButton").classList.add("clicked");
  setTimeout(() => {
    document.getElementById("submitButton").classList.remove("clicked");
  }, 4000);
}

//form validaton
const namecontact = document.getElementById('namecontact'); //Val
const email = document.getElementById('email'); //Val
const message = document.getElementById('message'); //Val

function checkInputs() {
  //Get the values from the inputs
  const nameValue = namecontact.value.trim();
  const emailValue = email.value.trim();
  const messageValue = message.value.trim();
  const numbers = /^[0-9]+$/;

  if (nameValue === '') {
    setErrorFor(namecontact, "Name cannot be blank.");
  }

  if (nameValue.match(numbers)) {
    setErrorFor(namecontact, "Name can not contain number(s).");
  }

  if (emailValue === '') {
    setErrorFor(email, "Email cannot be blank.");
  } else if (!isEmail(emailValue)) {
    setErrorFor(email, 'Email is not valid.');
  }

  if (messageValue === '') {
    setErrorFor(message, "Message cannot be blank.");
  }

  stopSendingData();
}

function setErrorFor(input, errorMessage) {
  const formControl = input.parentElement; //.form-control
  const small = formControl.querySelector('small');

  //add error message inside small
  small.innerText = errorMessage;

  // add error class
  formControl.className = 'form-control error';
}

function isEmail(email) {
  return /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(email);
}

function stopSendingData() {
  const small = document.getElementsByTagName('small');

  for (i = 0; i < small.length; i++) {
    if (small[i].parentElement.classList.contains('error')) {
      return false;
    }
  }

  showSucces();
}
.contactForm {
  flex: 0%;
  margin: 0px 0px;
  width: 21%;
  position: absolute;
  margin: 90px 0px 0px 10.5px;
  left: 0px;
}

.name,
.email,
.subject {
  position: relative;
  width: 279px;
  height: 39px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

.message {
  position: relative;
  width: 279px;
  height: 60px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 13.2px;
}

::placeholder {
  margin-top: 0px;
  font-size: 12px;
}

.fas.fa-exclamation-circle {
  color: red;
  width: 15px;
  height: 15px;
  position: absolute;
  top: 15px;
  right: 60px;
}

.form-control {
  position: relative;
}

.form-control i.fas.fas.fa-exclamation-circle {
  visibility: hidden;
}

small {
  position: absolute;
  left: 75px;
  visibility: hidden;
  top: 24.9px;
  font-size: 13.5px;
  font-weight: bolder;
  z-index: 9;
  width: 300px;
}

.form-control.error input {
  border-color: red;
}

.form-control.error textarea {
  border-color: red;
}

.form-control.error i.fas.fas.fa-exclamation-circle {
  visibility: visible;
  color: red;
}

.form-control.error small {
  color: red;
  visibility: visible;
}

#submitButton {
  margin: 9px 0px 0px 42px;
  width: 277.2px;
  height: 27px;
}

#submitButton {
  position: relative;
  cursor: pointer;
  height: 30px;
  width: 90px;
  transition: all 1250ms cubic-bezier(0.19, 1, 0.22, 1);
}

#submitButton.clicked {
  background-color: rgb(4, 221, 250);
  color: rgb(21, 21, 24);
  font-weight: bold;
  font-size: 16.2px;
  opacity: 0.6;
  padding-top: 1.7px;
}

#submitButton.clicked span {
  animation: spanShrink 1.8s ease-in-out forwards;
}

@keyframes spanShrink {
  15% {
    opacity: 0;
  }
  85% {
    opacity: 0;
  }
  100% {
    opacity: 1;
  }
}

#submitButton .checkmark {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  stroke-width: 3;
  stroke: rgb(18, 19, 19);
  stroke-miterlimit: 10;
  width: 51px;
  height: 51px;
  transform-origin: 50% 50%;
  stroke-dasharray: 48;
  stroke-dashoffset: 48;
}

#submitButton.clicked .checkmark {
  animation: stroke 1.5s ease-in-out 0.6s forwards;
}

@keyframes stroke {
  20% {
    stroke-dashoffset: 0;
  }
  50% {
    stroke-dashoffset: 0;
  }
  70% {
    stroke-dashoffset: 48;
  }
}
<form method="POST" class="contactForm" id="form">
  <div class="form-control">
    <input class="name" id="namecontact" type="text" placeholder="Name" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation1"></i>
    <small></small>
  </div>
  
  <div class="form-control">
    <input class="email" id="email" placeholder="E-mail" /><br>
    <i class="fas fa-exclamation-circle" id="exclamation2"></i>
    <small></small>
  </div>
  
  <div class="form-control">
    <input class="subject" type="text" placeholder="Subject" /><br>
  </div>
  
  <div class="form-control">
    <textarea class="message" id="message" cols="30" rows="10" placeholder="Message"></textarea><br>
    <i class="fas fa-exclamation-circle" id="exclamation4"></i>
    <small></small>
  </div>
  
  <button id="submitButton" type="submit">
    <span>Launch</span>
    <svg class="checkmark" viewBox="0 0 52 52">
      <path fill="none" d="M14.1 27.2l7.1 7.2 16.7-16.8"/>
    </svg>
  </button>
</form>
biberman
  • 5,606
  • 4
  • 11
  • 35
0

The answer to you question is pretty easy, just create a class say animating and write the code:

.animating{
    animation: animation-name 1s 1;
}

and then go to javascript file and add the lines as required with some changes:

//let the element to be animated have id = 'input1'
document.getElementById('input1').classList.add('animating');//to add animation
//or
document.getElementById('input1').classList.remove('animating');//to remove animation
0

well, apart from the fact that you are visibly annoyed with the indentation and that it makes reading your code painful, the first problem with your code is that you do not use any name attributes in your form, whereas those- these are essential because they are the reference used on the data sent to the server

They are also very useful in JS, because they also serve as a direct reference in forms

<form name="my-form-name" id="my-form-id"  .... 

  <input name="namecontact" type="text" placeholder="Name" />

javascript use:

const myForm = document.forms['my-form-name']  
// or myForm = document.querySelector("#my-form-id")
  
  
// usage
 
function checkInputs()
  {
  const nameValue = myForm.namecontact.value.trim()
//                    |       | 
//                    |     name attribute 
//                    |
//                  form element
// ...

myForm.onsubmit = e =>
  {
  e.preventDefault()
  checkInputs() 
  showSucces() 
  }
Mister Jojo
  • 20,093
  • 6
  • 21
  • 40