Home > Mobile >  Input fields validation in contact form - HTML/CSS
Input fields validation in contact form - HTML/CSS

Time:12-30

I have the following code:

//Contact Form Redirection
var form = document.getElementById("my-form");

async function handleSubmit(event) {
  event.preventDefault();
  var data = new FormData(event.target);
  fetch(event.target.action, {
    method: form.method,
    body: data,
    headers: {
      'Accept': 'application/json'
    }
  }).finally(() => {
    window.location = "thankyou.html";
  });
}
form.addEventListener("submit", handleSubmit)

//Contact Form Error Animation 
document.querySelector('form').addEventListener('submit', function (e) {
  var isValid = true;
  this.querySelectorAll('input, textarea').forEach(function (f) {
    if (!f.checkValidity()) {
      isValid = false;
      f.style.borderColor = "red";
      f.style.animation = "shake 0.82s forwards";
      setTimeout(function () { f.style.animation = "unset"; }, 820);
    } else {
      f.style.borderColor = "initial";
    }
  })
  if (!isValid) {
    e.preventDefault();
  }
})
/* Contact Form */

input[type=text],
[type=email],
select,
textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid #555;
  margin-top: 6px;
  margin-bottom: 16px;
  resize: vertical;
}

input[type=submit] {
  background-color: #0563bb;
  color: white;
  padding: 12px 20px;
  border: none;
  cursor: pointer;
}

input[type=submit]:hover {
  opacity: 0.9;
}

.contactform {
  position: relative;
  border-radius: 50px;
  background-color: #f2f2f2;
  padding: 5px;
  z-index: 2;
  display: block;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: auto;
  margin-top: 1%;
  width: 100%;
  animation-name: gradient;
  animation-duration: 3s;
  animation-iteration-count: infinite;
}

.contactform:hover {
  animation-name: gradient;
  animation-duration: 15s;
  animation-iteration-count: infinite;
}

.column {
  float: center;
  width: 50%;
  margin-top: 6px;
  padding: 20px;
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

@media screen and (max-width: 600px) {
  .column,
  input[type=submit] {
    width: auto;
    margin-top: 0;
  }
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}
<section id="contact">
  <div  data-aos="fade-up">
    <div >
      <div style="text-align:center">
        <div >
          <h2><br/>Get In Touch</h2>
        </div>
        <p>Feel Free To Reach Out To Me Through This Form! </p>
      </div>
      <div >
        <div >
          <form name="myform" action="https://formspree.io/f/xdobkgny" id="my-form" method="POST" novalidate>
            <label for="firstname">First Name</label>
            <input type="text" id="first name" name="firstname" placeholder="Your First Name.." required>
            <label for="lastname">Last Name</label>
            <input type="text" id="lastname" name="lastname" placeholder="Your Last Name.." required>
            <label for="email">Email:</label>
            <input type="email" id="email" name="email" placeholder="Your Email.." required>
            <label for="subject">Subject</label>
            <textarea id="subject" name="subject" placeholder="Lets Collaborate.." style="height:170px" required></textarea>
            <input type="submit" value="Submit">
          </form>
        </div>
      </div>
    </div>
  </div>
</section>

The form is running fine except it redirects to a page when there is no input in the field and when the error is thrown. Basically, it should not redirect me to a page when there is nothing typed in the input fields whereas its redirecting me to thankyou.html even when there is nothing in the input fields.

See this clip for the output I'm getting:

https://watch.screencastify.com/v/BSkuGitl5ACHDWEvGziM

How can I avoid this?

Update

https://watch.screencastify.com/v/RkgLmLAGztVduI26LV55

the animation does not work on one input field and I also would like the "please fill out this field" message to be removed and only have the shake animation

UPDATE2

Apparently, this is the JS code that sends the responses to email, so can you use this to make changes to your code?

var form = document.getElementById("my-form");

async function handleSubmit(event) {
  event.preventDefault();
  var data = new FormData(event.target);
  fetch(event.target.action, {
    method: form.method,
    body: data,
    headers: {
      'Accept': 'application/json'
    }
  }).finally(() => {
    window.location = "thankyou.html";
  });
}
myform.firstname.oninvalid = badEntrie
myform.lastname.oninvalid = badEntrie
myform.email.oninvalid = badEntrie
myform.subject.oninvalid = badEntrie

function badEntrie({ target }) {
  target.classList.add('shakingErr')
  setTimeout(() => { target.classList.remove('shakingErr') }, 820)
}
form.addEventListener("submit", handleSubmit)

CodePudding user response:

if for some reason you want to keep the novalidate you can instead loop through your elements to validate them (there are easier ways but im not sure if you are using any library).

you can do something like that:

let valid = true
validateInputs() {
    var elements = document.querySelectorAll("#my-form input[type=text]")

    for (var i = 0, element; element = elements[i  ];) {
        if (element.value === "")
            valid = false
            break
        }

and use that as your status which has no meaning now (thanks to novalidate)

CodePudding user response:

Looks like your form element has the "novalidate" attribute on it.

CodePudding user response:

The problem what i see is that your status var is null. Add the element with the id my-form-status in your dom then your code will work.

CodePudding user response:

First, you need to decide which fields and what you will validate. I wrote for you a simple example function how check some field on empty. (For name )

var form = document.getElementById("my-form");
var AllFieldStatus = false;
var statusName = false;
var statusLastName = false;
var statusEmail = false;
var statusTextfield = false;

function handleSubmit(event) {
  event.preventDefault();
  var status = document.getElementById("my-form-status");
  var data = new FormData(event.target);

  //// Validation on empty field
  statusName = checkNameField(document.getElementById("firstname"), statusName);

  /// the same operation with others fields

  if (statusName === false) {
    alert("Field name emty");
    return
  } else {
    console.log("Name not empty");
  }



  fetch(event.target.action, {
    method: form.method,
    body: data,
    headers: {
      'Accept': 'application/json'
    }
  }).then(response => {
    status.innerHTML = "Thanks for your submission!";
    form.reset()
  }).catch(error => {
    status.innerHTML = "Oops! There was a problem submitting your form"
  });
}
form.addEventListener("submit", handleSubmit)


function checkNameField(field, statusCheck) {

  el = field.value;
  if (el.length > 0) {
    return true;
  }

}
/* Contact Form */

input[type=text],
[type=email],
select,
textarea {
  width: 100%;
  padding: 12px;
  border: 1px solid #555;
  margin-top: 6px;
  margin-bottom: 16px;
  resize: vertical;
}

input[type=submit] {
  background-color: #0563bb;
  color: white;
  padding: 12px 20px;
  border: none;
  cursor: pointer;
}

input[type=submit]:hover {
  opacity: 0.9;
}

.contactform {
  position: relative;
  border-radius: 50px;
  background-color: #f2f2f2;
  padding: 5px;
  z-index: 2;
  display: block;
  margin-left: auto;
  margin-right: auto;
  margin-bottom: auto;
  margin-top: 1%;
  width: 100%;
  animation-name: gradient;
  animation-duration: 3s;
  animation-iteration-count: infinite;
}

.contactform:hover {
  animation-name: gradient;
  animation-duration: 15s;
  animation-iteration-count: infinite;
}

.column {
  float: center;
  width: 50%;
  margin-top: 6px;
  padding: 20px;
  display: block;
  margin-left: auto;
  margin-right: auto;
}

.row:after {
  content: "";
  display: table;
  clear: both;
}

@media screen and (max-width: 600px) {
  .column,
  input[type=submit] {
    width: auto;
    margin-top: 0;
  }
}

@keyframes shake {
  10%,
  90% {
    transform: translate3d(-1px, 0, 0);
  }
  20%,
  80% {
    transform: translate3d(2px, 0, 0);
  }
  30%,
  50%,
  70% {
    transform: translate3d(-4px, 0, 0);
  }
  40%,
  60% {
    transform: translate3d(4px, 0, 0);
  }
}
<section id="contact">
  <div  data-aos="fade-up">
    <div >
      <div style="text-align:center">
        <div >
          <h2><br />Get In Touch</h2>
        </div>
        <p>Feel Free To Reach Out To Me Through This Form! </p>
      </div>
      <div >
        <div >
          <form name="myform" action="https://formspree.io/f/xdobkgny" id="my-form" method="POST" novalidate>
            <label for="firstname">First Name</label>
            <input type="text" id="firstname" name="firstname" placeholder="Your First Name.." required>
            <label for="lastname">Last Name</label>
            <input type="text" id="lastname" name="lastname" placeholder="Your Last Name.." required>
            <label for="email">Email:</label>
            <input type="email" id="email" name="email" placeholder="Your Email.." required>
            <label for="subject">Subject</label>
            <textarea id="subject" name="subject" placeholder="Lets Collaborate.." style="height:170px" required></textarea>
            <input type="submit" value="Submit">
          </form>
        </div>
      </div>
    </div>
  </div>
</section>

You need check each field on empty status before you will send data. If all

statusName = true;
statusLastName = true;
statusEmail = true;
statusTextfield = true;

you will send otherwise make return function

CodePudding user response:

Try that :

const form = document.forms.myform
  ;
form.onsubmit = e =>
  {
  e.preventDefault()
  let data = Object.fromEntries( new FormData(form).entries())

  // for test
  console.clear()
  console.log('data', JSON.stringify(data))

  let validationOK = true
  for (let entrie in data) 
    {
    if (!form[entrie].checkValidity())
      {
      validationOK = false
      form[entrie].classList.add('shakingErr') 
      setTimeout(() => { form[entrie].classList.remove('shakingErr') }, 820)
      }
    }
  if (validationOK)
    {
    fetch( form.action,
      { method  : form.method
      , body    : data
      , headers : { Accept : 'application/json' }
      })
    .finally(() => { window.location = "thankyou.html" })
    }
  }
input,
select,
textarea {
  width         : 100%;
  padding       : 12px;
  border        : 1px solid #555;
  margin-top    : 6px;
  margin-bottom : 16px;
  resize        : vertical;
  }
textarea {
  height        : 170px;
  }
button {
  background-color : #0563bb;
  color            : white;
  padding          : 12px 20px;
  border           : none;
  cursor           : pointer;
  }
button:before {
  content        : attr(type);
  text-transform : capitalize;
  }
button:hover {
  opacity : 0.9;
  }
.contactform {
  position                  : relative;
  border-radius             : 50px;
  background-color          : #f2f2f2;
  padding                   : 5px;
  z-index                   : 2;
  display                   : block;
  margin-left               : auto;
  margin-right              : auto;
  margin-bottom             : auto;
  margin-top                : 1%;
  width                     : 100%;
  animation-name            : gradient;
  animation-duration        : 3s;
  animation-iteration-count : infinite;
  }
.contactform:hover {
  animation-name            : gradient;
  animation-duration        : 15s;
  animation-iteration-count : infinite;
  }
div.contactform > div:not(.row) {
  text-align : center;
  }
.column {
  float        : center;
  width        : 50%;
  margin-top   : 6px;
  padding      : 20px;
  display      : block;
  margin-left  : auto;
  margin-right : auto;
  }
.row:after {
  content : "";
  display : table;
  clear   : both;
  }
@media screen and (max-width: 600px) {
  .column,
  button {
    width      : auto;
    margin-top : 0;
    }
  }
.shakingErr {
  border-color: red;
  animation   : shake 0.82s forwards;
}
@keyframes shake {
  10%,90%     { transform: translate3d(-1px, 0, 0); }
  20%,80%     { transform: translate3d( 2px, 0, 0); }
  30%,50%,70% { transform: translate3d(-4px, 0, 0); }
  40%,60%     { transform: translate3d( 4px, 0, 0); }
  }
<section id="contact">
  <div  data-aos="fade-up">
    <div >
      <div>
        <div >
          <h2><br/>Get In Touch</h2>
        </div>
        <p>Feel Free To Reach Out To Me Through This Form! </p>
      </div>
      <div >
        <div >
          <form name="myform" action="https://formspree.io/f/xdobkgny" method="POST" novalidate >
            <label>First Name</label>
            <input name="firstname" type="text"  placeholder="Your First Name.." required>
            <label>Last Name</label>
            <input  name="lastname" type="text"  placeholder="Your Last Name.." required>
            <label>Email:</label>
            <input name="email"     type="email" placeholder="Your Email.." required>
            <label>Subject</label>
            <textarea  name="subject" placeholder="Lets Collaborate.." required></textarea>
            <button type="submit"></button>  
          </form>
        </div>
      </div>
    </div>
  </div>
</section>

  • Related