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>