I am encountering issues with my Ajax function combining it with Bootstrap validation. I guess it could be an issue with the form call in the Ajax function.
The email is properly sent as per PHP file, but not with Ajax function. I don't receive any error, but the Ajax call is ignored.
Do I have to redefine the form in the Ajax function ?
// Bootstrap forms validation
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
form.querySelector(".form-control:invalid").focus();
event.preventDefault()
event.stopPropagation()
}
else {
$.ajax({
type: "POST",
url: form.attr('action'),
datatype: "json",
data: form.serialize(),
beforeSend: function () {
form.find(":submit").html("Sending...").prop('disabled', true);
},
error: function (xhr, status, error) {
$(".toast").addClass('bg-danger');
$(".toast-body").text(xhr.status ': ' xhr.statusText);
$(".toast").toast("show");
},
success: function (data) {
if (data.success === true) {
form.removeClass('was-validated').trigger("reset");
$(".toast").addClass('bg-success');
}
else {
$(".toast").addClass('bg-danger');
}
$(".toast-body").text(data.message);
$(".toast").toast("show");
}
});
}
form.classList.add('was-validated')
}, false)
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="contact-form" method="post" action="/inc/contact.php" autocomplete="off" novalidate>
<div >
<div >
<div >
<input type="text" name="firstname" id="firstname"
placeholder="firstname" required>
</div>
</div>
<div >
<div >
<input type="text" name="lastname" id="lastname"
placeholder="Lastname" required>
</div>
</div>
<div >
<div >
<input type="email" name="email" id="email"
placeholder="Email" pattern="[a-z0-9._% -] @[a-z0-9.-] \.[a-z]{2,4}$"
required>
</div>
</div>
<div >
<div >
<input type="tel" name="phone" id="phone"
placeholder="Phone">
</div>
</div>
<div >
<div >
<input type="text" name="subject" id="subject"
placeholder="Subject" required>
</div>
</div>
<div >
<div >
<textarea name="message" id="message" cols="30"
rows="4" placeholder="Create a message here" required></textarea>
</div>
</div>
<div >
<div >
<div >
<div >
<button type="submit" >Send <i
></i></button>
</div>
</div>
<div >
<p >By clicking this button, you agree to the <a
href="" rel="nofollow">terms and
conditions</a>.</p>
</div>
</div>
</div>
</div>
</form>
CodePudding user response:
Here are a couple of observations and a working solution
A page can't be manipulated safely until the document is "ready." jQuery detects this state of readiness for you. Code included inside $( document ).ready() will only run once the page Document Object Model (DOM) is ready for JavaScript code to execute.
Move the event listener inside the $(document).ready(function() {/**/});Include
event.preventDefault()
inside theelse
block in order to cancel the submission before executing the else block.
Here is the solution
$(document).ready(function () {
submitForm();
});
function submitForm() {
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
form.querySelector(".form-control:invalid").focus();
event.preventDefault()
event.stopPropagation()
}
else {
event.preventDefault();
$.ajax({
type: "POST",
url: form.attr('action'),
datatype: "json",
data: form.serialize(),
beforeSend: function () {
form.find(":submit").html("Sending...").prop('disabled', true);
},
error: function (xhr, status, error) {
$(".toast").addClass('bg-danger');
$(".toast-body").text(xhr.status ': ' xhr.statusText);
$(".toast").toast("show");
},
success: function (data) {
if (data.success === true) {
form.removeClass('was-validated').trigger("reset");
$(".toast").addClass('bg-success');
}
else {
$(".toast").addClass('bg-danger');
}
$(".toast-body").text(data.message);
$(".toast").toast("show");
}
});
}
form.classList.add('was-validated')
}, false)
});
}
CodePudding user response:
I had to convert the form to a jQuery object -> $(form).
Here is the final code working. Thanks guys.
// Bootstrap forms validation
function submitForm() {
var forms = document.querySelectorAll('.needs-validation')
Array.prototype.slice.call(forms).forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
form.querySelector(".form-control:invalid").focus();
event.preventDefault()
event.stopPropagation()
}
else {
event.preventDefault();
$.ajax({
type: "POST",
url: $(form).attr('action'),
datatype: "json",
data: $(form).serialize(),
beforeSend: function () {
$(form).find(":submit").html("Sending...").prop('disabled', true);
},
error: function (xhr, status, error) {
$(".toast").addClass('bg-danger');
$(".toast-body").text(xhr.status ': ' xhr.statusText);
$(".toast").toast("show");
},
success: function (data) {
if (data.success === true) {
$(form).removeClass('was-validated').trigger("reset");
$(".toast").addClass('bg-success');
}
else {
$(".toast").addClass('bg-danger');
}
$(".toast-body").text(data.message);
$(".toast").toast("show");
}
});
}
form.classList.add('was-validated')
}, false)
});
}