1

I made a contact form with JavaScript validation but the validation function does not work. Although it does not show any errors in the console. The submit funtion itself does work and shows an alert box when you submit the form.

The validation function adds a CSS error class and then should show the error message, the error border and the erros symbol. When I add the error class manually to the HTML file the erros signs do show. But with the funtcion it does not.

I think maybe it has to do something with the way how I add the function to the form. But I checked everything and it just seems to look fine. Who knows what is going wrong? Some help would be very much appreciated! Thanks in advance!

var firebaseConfig = {
  apiKey: " /* anominzed by editor */ ",
  authDomain: " /* anominzed by editor */ ",
  databaseURL: " /* anominzed by editor */ ",
  projectId: " /* anominzed by editor */ ",
  storageBucket: " /* anominzed by editor */ ",
  messagingSenderId: " /* anominzed by editor */ ",
  appId: " /* anominzed by editor */ ",
  measurementId: " /* anominzed by editor */ "
};
// Initialize Firebase
firebase.initializeApp(firebaseConfig);

//Reference contactInfo collections
let contactInfo = firebase.database().ref("infos");

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

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

  checkInputs(); //val

  //Get input values
  let name = document.querySelector(".name").value;
  let email = document.querySelector(".email").value;
  let message = document.querySelector(".message").value;
  console.log(name, email, message);

  saveContactInfo(name, email, message);

  //Refresh after submit
  document.querySelector(".contactForm").reset();

  //Call send email function
  sendEmail(name, email, message);
}


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

//form validaton
function checkInputs() {
  //Get the values from the inputs
  const nameValue = namecontact.value.trim();
  const emailValue = email.value.trim();
  const messageValue = message.value.trim();

  if (nameValue === '') {
    setErrorFor(namecontact, "Name cannot be blank");
  }
  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");
  }
}

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

  small.forEach(element => {
    small.innerText = errorMessage;
  })

  //add error message inside small


  // 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);
}


//Save infos to Firebase
function saveContactInfo(name, email, message) {
  let newContactInfo = contactInfo.push();

  newContactInfo.set({
    contactname: name,
    email: email,
    message: message,
  });
}

function showSucces() {
  alert("succesfully sent")
}

//Send Email function
function sendEmail(name, email, message) {
  Email.send({
    Host: "smtp.gmail.com",
    Username: "[email protected]",
    To: "[email protected]",
    From: "[email protected]",
    Subject: `${name} sent you a message`,
    Body: `Name: ${name} <br/> Email: ${email} <br/> Message: ${message}`,
  }).then((message) => showSucces());
}
/* master styles */

html {
  height: 100%;
}

.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: 45px;
  padding: 9px 15px 15px 15px;
  margin-left: 39.9px;
  font-size: 12px;
}

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

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

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

.form-control {
  position: relative;
}

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

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

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

small {
  position: absolute;
  left: 66px;
  visibility: hidden;
  top: 27px;
}

#submitButton {
  margin: 9px 0px 0px 42px;
  width: 277.2px;
  height: 63px;
}
<html lang="en" id="html">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Liara Skara</title>
  <link rel="preconnect" href="https://fonts.gstatic.com">
  <link rel="stylesheet" href="styles.css">
  <!-- <script src='https://kit.fontawesome.com/a076d05399.js'></script> -->
</head>

<body id="bodyContactpage">
  <form method="POST" class="contactForm" id="form">

    <!-- <div class="backgroundImg" style="background-image: url('Images/LiaraEyesOpen.png');"> -->
    <div class="form-control">
      <input class="name" id="namecontact" type="text" placeholder="Name" required/><br>
      <i class="fas fa-exclamation-circle" id="exclamation1"></i>
      <small class="small" id="small1">Error mesagge</small>
    </div>
    <div class="form-control">
      <input class="email" id="email" type="email" placeholder="E-mail" required/><br>
      <i class="fas fa-exclamation-circle" id="exclamation2"></i>
      <small class="small" id="small2">Error mesagge</small>
    </div>
    <div class="form-control">
      <input class="subject" type="text" placeholder="Subject" /><br>
      <i class="fas fa-exclamation-circle" id="exclamation3"></i>
      <small class="small" id="small3">Error mesagge</small>
    </div>
    <div class="form-control">
      <textarea class="message" id="message" name="" id="" cols="30" rows="10" placeholder="Message" required></textarea><br>
      <i class="fas fa-exclamation-circle" id="exclamation4"></i>
      <small class="small" id="small4">Error mesagge</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>
<script src="https://smtpjs.com/v3/smtp.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.7/firebase.js"></script>
<script src="myscript.js">
</script>
</body>

</html>

2
  • Note that you have an invalid HTML markup. You having more closing tags then you have opening tags. Commented Jun 21, 2021 at 12:37
  • Thanks @tacoshy I changed it. Commented Jun 21, 2021 at 12:47

3 Answers 3

1

There are couple of errors in setErrorFor function.

  1. The JavaScript function getElementsByClassName return a HTMLCollection.

    Try converting it to an Array using Array.from(HTMLCollection), i.e, Array.from(formControl) in your case.

  2. While looping through the Array(formControl) using forEach function below:

    small.forEach(element => { small.innerText = errorMessage; })

    you should refer to element and not small. It should be element.innerText. You also need to set the visibility property for the element with class = 'small' from hidden to visible.

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

Comments

1

I had to comment out all the firebase stuff to get your code to run: it was failing to initialise without a complete config, and throwing an error that prevented all the rest of your code from running.

Once I had done that, I found an error in your setErrorFor function:

small.forEach is not a function

This is because getElementsByClassName (and also querySelectorAll) does not return an array, but a HTMLCollection. This doesn't have map or forEach methods.

Instead, you can use:

for (const el of small) {
    el.innerText = errorMessage
}

In general, however, my advice would be to add descriptive logging to your code, so you can follow exactly what is happening. You may also wish to enable "Preserve/persist logs" in your browser devtools settings, in case the logs are being cleared by an unexpected page reload.

Comments

0

Thanks for your help! I have solved it and it is working now, by taking the function out of the other submit function. And I changed the setErrorFor function to this;

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';
}

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.