Submit Ajax form after Validation - javascript

I have a limited understanding of JavaScript, but with some copying and pasting I managed to make a form that gets sent via AJAX.
I'm also running the standard Boostrap 5 input validation. It all worked fine until I found out AJAX fires even without some fields missing.
Then I tried to put the AJAX stuff inside the validation function, but now I need to press "Submit" twice. I understand why, but I don't know how to solve it and would need some help.
This is what I came up with:
(function () {
'use strict'
// Fetch all the forms we want to apply validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
var frm = $('#orderform');
frm.submit(function (e) {
var formData = {
firstName_r: jQuery('#firstName_r').val(),
lastName_r: jQuery('#lastName_r').val(),
action:'the_ajax_mail'
};
$.ajax({
type : 'POST',
url : "<?php echo admin_url('admin-ajax.php'); ?>",
data : formData,
encode : true
}).done(function(data) {
console.log(data);
form.classList.remove('was-validated');
document.getElementById('submitForm').disabled = true;
}).fail(function(data) {
console.log(data);
});
e.preventDefault();
});
}, false)
})
})()
I know the part with var frm = $('#orderform'); and frm.submit(function (e) { needs to go, but I have no idea how...

Try this
(function() {
'use strict'
// Fetch all the forms we want to apply validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function(form) {
form.addEventListener('submit', function(event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
return
}
form.classList.add('was-validated')
var formData = {
firstName_r: jQuery('#firstName_r').val(),
lastName_r: jQuery('#lastName_r').val(),
action: 'the_ajax_mail'
};
$.ajax({
type: 'POST',
url: "<?php echo admin_url('admin-ajax.php'); ?>",
data: formData,
encode: true
}).done(function(data) {
console.log(data);
form.classList.remove('was-validated');
document.getElementById('submitForm').disabled = true;
}).fail(function(data) {
console.log(data);
});
e.preventDefault();
}, false)
})
})()

Related

how to post data using AJAX with validation using bootstrap 5?

How can I post ajax with form validation in bootstrap 5 ?
// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}
form.classList.add('was-validated')
}, false)
})
})()
I have a big problem with this. Can somebody help me?
The above starter code provided by bootstrap documentation uses the checkValidity() method of JavaScript Constraint Validation API to validate the form.
The HTMLInputElement.checkValidity() method returns a boolean value
which indicates validity of the value of the element. If the value is
invalid, this method also fires the invalid event on the element.
You can make the ajax request if validation is successful as below,
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}else{
//make your ajax request here
}
Here is an example ajax request using JavaScript Fetch API and FormData API
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
}else{
try {
const postData = new FormData(form)
const response = await fetch('url', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(postData)
});
//Response from server
const data = await response.json();
}catch(e){
//handle error
console.log(e)
}
}
(function () {
'use strict'
// Fetch all the forms we want to apply custom Bootstrap validation styles to
var forms = document.querySelectorAll('.needs-validation')
// Loop over them and prevent submission
Array.prototype.slice.call(forms)
.forEach(function (form) {
form.addEventListener('submit', function (event) {
if (!form.checkValidity()) {
event.preventDefault()
event.stopPropagation()
} else {
event.preventDefault(); // event.default or form submit
formPost(); // call function whatever you want
}
form.classList.add('was-validated')
}, false)
})
})()
function formPost(){
var form_data = $("form#mainform").serialize();
$.ajax({
url: "action.php",
method: "POST",
data: form_data,
// dataType:"json",
success: function (data) {
$('#queryResulDiv').html(data);
console.log(data);
},
error: function (xhr, ajaxOptions, thrownError) {
$('#queryResulDiv').html("ERROR:" + xhr.responseText + " - " + thrownError);
},
complete: function () {
}
})
}

problem with prevent and continue submit form after ajax execution

I have form with select. If select value is equal to 2 then part of form is sendign asynch via ajax and later the rest of the form should be sending via POST function. My problem is when I click submit ajax execution is performs correctly but POST method stuck, nothing happens. It looks like be page refresh.
My code
$('form').submit(function(e) {
if($('#car_type').val() == 2)
{
e.preventDefault();
e.returnValue = false;
var type = $('#new_type').val();
var number = $('#numer').val();
var form = $(this);
$.ajax({
url: "{{ url('cars/type') }}",
method: "POST",
context: form,
data: {type: type, number: number, _token: "{{ csrf_token() }}"},
success: function (result) {
if (result.result > 0) {
} else {
$("#msg").html("Errors, try again later!");
$("#msg").fadeOut(2000);
}
},
error: function (xhr) {
console.log(xhr.responseText);
},
complete: function() {
this.off('submit');
this.submit();
}
})
}
});

How to run JavaScript code on Success of Form submit?

I have an Asp.Net MVC web application. I want to run some code on the successful response of the API method which is called on form submit.
I have the below Code.
#using (Html.BeginForm("APIMethod", "Configuration", FormMethod.Post, new { #class = "form-horizontal", id = "formID" }))
{
}
$('#formID').submit(function (e) {
$.validator.unobtrusive.parse("form");
e.preventDefault();
if ($(this).valid()) {
FunctionToBeCalled(); //JS function
}
}
But FunctionToBeCalled() function gets called before the APIMethod(), but I want to run the FunctionToBeCalled() function after the response of APIMethod().
So I made the below changes by referring this link. But now the APIMethod is getting called twice.
$('#formID').submit(function (e) {
$.validator.unobtrusive.parse("form");
e.preventDefault();
if ($(this).valid()) {
//Some custom javasctipt valiadations
$.ajax({
url: $('#formID').attr('action'),
type: 'POST',
data: $('#formID').serialize(),
success: function () {
console.log('form submitted.');
FunctionToBeCalled(); //JS function
}
});
}
}
function FunctionToBeCalled(){alert('hello');}
So I am not able to solve the issue.
If you want to execute some work on success, fail, etc. situation of form submission, then you would need to use Ajax call in your view. As you use ASP.NET MVC, you can try the following approach.
View:
$('form').submit(function (event) {
event.preventDefault();
var formdata = $('#demoForm').serialize();
//If you are uploading files, then you need to use "FormData" instead of "serialize()" method.
//var formdata = new FormData($('#demoForm').get(0));
$.ajax({
type: "POST",
url: "/DemoController/Save",
cache: false,
dataType: "json",
data: formdata,
/* If you are uploading files, then processData and contentType must be set to
false in order for FormData to work (otherwise comment out both of them) */
processData: false, //For posting uploaded files
contentType: false, //For posting uploaded files
//
//Callback Functions (for more information http://api.jquery.com/jquery.ajax/)
beforeSend: function () {
//e.g. show "Loading" indicator
},
error: function (response) {
$("#error_message").html(data);
},
success: function (data, textStatus, XMLHttpRequest) {
$('#result').html(data); //e.g. display message in a div
},
complete: function () {
//e.g. hide "Loading" indicator
},
});
});
Controller:
public JsonResult Save(DemoViewModel model)
{
//...code omitted for brevity
return Json(new { success = true, data = model, message = "Data saved successfully."
}
Update: If SubmitButton calls a JavaScript method or uses AJAX call, the validation should be made in this method instead of button click as shown below. Otherwise, the request is still sent to the Controller without validation.
function save(event) {
//Validate the form before sending the request to the Controller
if (!$("#formID").valid()) {
return false;
}
...
}
Update your function as follows.
$('#formID').submit(function (e) {
e.preventDefault();
try{
$.validator.unobtrusive.parse("form");
if ($(this).valid()) {
$.ajax({
url: $('#formID').attr('action'),
type: 'POST',
data: $('#formID').serialize(),
success: function () {
console.log('form submitted.');
FunctionToBeCalled(); //JS function
}
});
}
}
catch(e){
console.log(e);
}
});
Check the browser console for fetching error. The above code will prevent of submitting the form.
I think line $.validator.unobtrusive.parse("form") were throwing error.
For that use you need to add the following jQuery libraries.
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.9/jquery.validate.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validation-unobtrusive/3.2.11/jquery.validate.unobtrusive.min.js"></script>
I think you should remove razor form tag if you want to post your form using ajax call and add post api URL directly to ajax request instead of getting it from your razor form tag using id:
Here is the revised version of your code :
<form method="post" id="formID">
<!-- Your form fields here -->
<button id="submit">Submit</button>
</form>
Submit your form on button click like:
$('#submit').on('click', function (evt) {
evt.preventDefault();
$.ajax({
url: "/Configuration/APIMethod",
type: 'POST',
dataType : 'json',
data: $('#formID').serialize(),
success: function () {
console.log('form submitted.');
FunctionToBeCalled(); //JS function
}
});
});
function FunctionToBeCalled(){alert('hello');}
You need to use Ajax.BeginForm, this article should help [https://www.c-sharpcorner.com/article/asp-net-mvc-5-ajax-beginform-ajaxoptions-onsuccess-onfailure/ ]
The major thing here is that I didn't use a submit button, I used a link instead and handled the rest in the js file. This way, the form would nver be submitted if the js file is not on the page, and with this js file, it initiates a form submission by itself rather than th form submitting when the submit button is clicked
You can adapt this to your solution as see how it respond. I have somthing like this in production and it works fine.
(function() {
$(function() {
var _$pageSection = $('#ProccessProductId');
var _$formname = _$pageSection.find('form[name=productForm]');
_$formname.find('.buy-product').on('click', function(e) {
e.preventDefault();
if (!_$formname.valid()) {
return;
}
var formData = _$formname.serializeFormToObject();
//set busy animation
$.ajax({
url: 'https://..../', //_$formname.attr('action')
type: 'POST',
data: formData,
success: function(content) {
AnotherProcess(content.Id)
},
error: function(e) {
//notify user of error
}
}).always(function() {
// clear busy animation
});
});
function AnotherProcess(id) {
//Perform your operation
}
}
}
<div class="row" id="ProccessProductId">
#using (Html.BeginForm("APIMethod", "Configuration", FormMethod.Post, new { #class = "form-horizontal", name="productForm" id = "formID" })) {
<li class="buy-product">Save & Proceed</li>
}
</div>

If user manipulates the form id what is the best practice to secure it or stop this?

If user changes the formID what should i do to make the ajax call and jquery validation success.
<form id="formID" action="">
(function ($, W, D)
{
var JQUERY4U = {};
JQUERY4U.UTIL =
{
setupFormValidation: function ()
{
$("#formID").validate({
rules: {
input:"required",
},
messages: {
input: "required",
},
submitHandler: function (form) {
var form = $('#formID')[0];
var formData = new FormData(form);
$.ajax({
type: 'post',
url: '/',
data: formData,
contentType: false,
processData: false,
success: function(data) {
if (data.response == true) {
alert('true');
} else {
alert('false');
}
}, error: function (jqXHR, exception) {
console.log(jqXHR.status);
}
});
}
});
}
}
$(D).ready(function ($) {
JQUERY4U.UTIL.setupFormValidation();
});
})(jQuery, window, document);
Just remove var form = $('#formID')[0]; in the submitHandler. The form element is already exposed as an argument
The plugin will have already initialized before an ID could be changed by user in console and probably before any userscript or browser extension also
Changing an ID does not affect events already attached to that element.
Beyond that you can't control what a user does in their browser and just need to make sure your back end is secure

event.preventDefault(); only works some of the time with submit form

I am using the Mailchimp API to submit a form. The goal is to prevent the default callback provided by Mailchimp. The majority of the time event.preventDefault() is behaving as it should. Then randomly it will not work:
$(function () {
var $form = $('#mc-embedded-subscribe-form');
$('#mc-embedded-subscribe').on('click', function(event) {
if(event) event.preventDefault();
register($form);
});
});
function register($form) {
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
data: $form.serialize(),
cache : false,
dataType : 'json',
contentType: "application/json; charset=utf-8",
error : function(err) { alert("Could not connect to the registration server. Please try again later."); },
success : function(data) {
if (data.result != "success") {
// Something went wrong, do something to notify the user. maybe alert(data.msg);
var message = data.msg
var messageSh = data.msg.substring(4);
if (data.msg == '0 - Please enter a value' || data.msg == '0 - An email address must contain a single #') {
$('#notification_container').html('<span class="alert">'+messageSh+'</span>');
} else {
$('#notification_container').html('<span class="alert">'+message+'</span>');
}
} else {
// It worked, carry on...
var message = data.msg;
$('.popup-promo-container').addClass('thanks');
$('.checkboxes, #mc_embed_signup_scroll').addClass('hidden');
$('.complete-promo').html(message).removeClass('hidden');
setTimeout(function() {
document.querySelector('.popup-promo').style.display = "none";
},20000);
}
}
});
}
Try
take off ready function.
remove if on event
Code:
var $form = $('#mc-embedded-subscribe-form');
$('#mc-embedded-subscribe').on('click', function(event) {
event.preventDefault();
register($form);
});

Categories

Resources