How to prevent form from submitting with AJAX validation - javascript

How to prevent form from submit when I am using ajax to validate it. The problem is that the ajax is asynchronous and the real result ( which is false in my case ) comming later. Is making Ajax to sync is the right way? This is my piece of code:
$('#w0').on('beforeSubmit', function(e){
let loadDate = $('#dstrequest-load_date').val()
let shippingDate = $('#dstrequest-shipping_date').val()
let requestId = '".($model->isNewRecord ? 0 : $model->id)."'
let trucks = $('.container-items_truck').find('.truck-item')
let ids = []
let result = true
$.each(trucks, function(){
let id = $(this).find('select').first().val()
if(ids.indexOf(id) === -1)
ids.push(id)
})
$.ajax({
method: 'post',
url: '/erp/distribution/dst-vehicle/check-truck-engage-date',
data: {
load_date: loadDate,
shipping_date: shippingDate,
trucks: ids,
request_id: requestId
}
})
.done(function(data){
let selects = $('select[name$=\"[truck_id]\"]')
$.each(selects, function(){
let val = $(this).val()
if(data.indexOf(val) !== -1){
$('#w0').yiiActiveForm('updateAttribute', $(this).attr('id'), ['".Yii::t('distribution', 'distributionCore.busy_truck')."'])
result = false
}
})
})
.always(function(data){
let transfer_wrapper = $('.transfer-wrapper')
$.each(transfer_wrapper, function(){
if($(this).is(':visible')){
let fields = $(this).find('input, select')
$.each(fields, function(){
if($(this).val() == ''){
let id = $(this).attr('id')
$('#w0').yiiActiveForm('updateAttribute', id, ['" . Yii::t('distribution', 'distributionCore.please_fill_the_field') . "'])
result = false
}
})
}
})
})
// HERE THE RESULT SHOULD BE FALSE BECAUSE OF THE AJAX VALIDATION BUT IT'S TRUE BECAUSE OF THE ASYNC BEHAVIOUR.
return result
})

Is making Ajax to sync is the right way?
No. Synchronous HTTP requests from JS are deprecated. Never use them.
You need to either:
Always halt
Always prevent normal form submission.
After you have validated the input, using Ajax, use JS to resubmit the form (without repeating validation).
Validate in advance
Do the validation as the data is entered, field by field.
Hopefully, the Ajax will be finished by the time the last field is completed and the form submitted.
That at that point, if the Ajax isn't finished, you either have to risk submitting the form without knowing the result of the Ajax validation or fall back to the first option I suggested.

Related

Checking the return value of $.get with Javascript

Prevent a submission of a form via POST and submit once conditions are met.
Form is being submitted, I am not sure how to check if the function (which passes an HTML input into Python that checks a database if the user exists (Returns in JSON format true if it doesn't and false if it exists).
I have tried checking if the function is true, which for most cases work, I wonder if it is the $.get is an odd case?
document.getElementById("register").addEventListener("click", function(event) {
event.preventDefault();
let input = document.getElementsByName("username");
function(check) {
$.get('/check?username=' + input.value, function(data) {
document.querySelector('ul').innerHTML = data;
})
if (check()) {
this.submit();
}
else {
alert ("username is taken!");
return false;
}
#app.route("/check", methods=["GET"])
def check():
# Check the http parameter for username.
username = request.args.get("username")
check = db.execute("SELECT username FROM users WHERE username = :username", username=username)
if not check:
return jsonify(True)
else:
return jsonify(False)
I want the alert to flash and prevent form submission of the function runs and returns json(False) - which would indicate the username is taken
But right now it is submitting the form.
$.get() is asynchronous so you can't return a value from check()
Instead do the submit inside $.get() callback if response is true
document.getElementById("register").addEventListener("click", function(event) {
event.preventDefault();
let input = document.getElementsByName("username")[0];
$.getJSON('/check?username=' + input.value, function(data) {
if (data) {
document.querySelector('**formSelector**').submit()
} else {
// notify user
}
});
})

jQuery Ajax POST and return data

I have a form with AJAX submit.
This form is working, but I have the impression that the functions are not correct.
jQuery(document).ready(function(){
var myForm = $("#ajax_form"), email = $("#email"), emailInfo = $("#emailInfo"), ck1 = $("#ck1"), ck2 = $("#ck2"), ck3 = $("#ck3");
jQuery('#ajax_form').submit(function(){
var dados = jQuery( this ).serialize();
jQuery.ajax({
type: "POST",
url: "check.php", // Checking data
data: dados,
beforeSend: function(){
emailInfo.html("<font color='blue'>Checking..</font>");
if(dados == "email=") // >>> This field, how to check if the field is blank?
{
email.focus();
emailInfo.html("<font color='red'>Required.</font>");
return false;
}
},
success: function(data){
if(data == "invalid")
{
emailInfo.html("<font color='red'>Invalid.</font>");
}
else if(data != "0")
{
email.val(data); // This field, how to display the data sent in the email field? not the return of PHP,
ck1.css("display", "none");
ck2.css("display", "inline");
}
else
{
ck1.css("display", "none");
ck2.css("display", "none");
ck3.css("display", "inline");
}
}
});
return false;
});
});
I think that has a lot of wrong code, for example:
if(dados == "email=") // >>> This field, how to check if the field is blank?
and >>
email.val(data); // This field, how to display the data sent in the email field? not the return of PHP,
I tried to update but not return any results
Test Code
//if (email.val() == "")
//{
//email.focus();
alert(email.val()); // op1
alert(dados); // op2
alert($.trim($('email').val())); // op3
emailInfo.html("<font color='red'>Required.</font>");
return false;
//}
if insert an email, the only option that returns is op2 email=teste#teste.com
I think your code is trying to validate email by ajax before submitting form. If so this code seems ok to me out of a few points.
return false at the end of submit call may not work on firefox. Use e.preventDefault();. Look at this post. If you try this code on chrome it may fail beacuse you have no return true anywhere.
Your second code block is ok. email.val(data); is equal to $("#email").val(data);. I think you are trying to set the email input value to the result.
if(dados == "email=") can be changed to if (email.val() != ''). So you wont need to dados also.
You don't use myForm variable nowhere. It should be deleted.
If validating the email on server side is not a must think about validating on client side.
The returned data value is echoed from your PHP file. There are two approaches to take to validate your data:
Do it in the frontend with JS prior to sending your form.
Do it with your PHP code in the separate file.
email.val(data); // This field, how to display the data
sent in the email field? not the return of PHP
I am guessing that you want to ensure that the value doesn't get deleted if the user sends an invalid request (thus having to type the value in again).
What you can do is store the values of what the user has entered on form submit but prior to sending the AJAX request: var emailVal = email.val();
jQuery(document).ready(function(){
var myForm = $("#ajax_form"), email = $("#email"), emailInfo = $("#emailInfo"), ck1 = $("#ck1"), ck2 = $("#ck2"), ck3 = $("#ck3");
jQuery('#ajax_form').submit(function(){
var dados = jQuery( this ).serialize();
var emailVal = email.val(); // Assign the entered input to an emailVal variable
jQuery.ajax({
type: "POST",
url: "check.php", // Checking data
data: dados,
beforeSend: function(){
emailInfo.html("<font color='blue'>Checking..</font>");
if(dados == "email=") // >>> This field, how to check if the field is blank?
{
email.focus();
emailInfo.html("<font color='red'>Required.</font>");
return false;
}
},
success: function(data){
if(data == "invalid")
{
emailInfo.html("<font color='red'>Invalid.</font>");
}
else if(data != "0")
{
email.val(emailVal); // Store the entered value back into the email input
ck1.css("display", "none");
ck2.css("display", "inline");
}
else
{
ck1.css("display", "none");
ck2.css("display", "none");
ck3.css("display", "inline");
}
}
});
return false;
});
});
Another Note
I would also like to point out this: if(data == "invalid")
I have found that PHP can send back error messages within the data along with whatever you ask it to return. If you have any error in your PHP code, this will never hit because invalid will never be the only string of characters in the returned data value. To protect yourself, I would do either two things:
Return an HTTP error and do error handling within the error callback of the AJAX function: https://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Return a unique word and search for that word within the returned data string:
PHP
if(!validEmailCheck($email)){
echo('invalidRAWR');
}
JS
if(data.indexOf('invalidRAWR') != -1) // Built in PHP errors will never return 'invalidRAWR'

How to reset event.preventDefault() of a form submit event?

I have a form that submits shopping cart data to a payment gateway (WorldPay) payment processing page. I need to perform a couple of extra logic the moment the custom decides to proceed to the payment but before the form submission itself. Basically, I simply want to generate a unique reference to the order at the very last moment.
Here is the jQuery code for the submit event:
$(function(){
$('#checkout-form').submit(function(e){
var $form = $(this);
var $cartIdField = $('#cartId');
console.log($cartIdField.val());
if($cartIdField.val() == ''){
e.preventDefault();
$.ajax({
url: baseUrl + '/shop/ajax/retrieve-shopping-cart-reference/',
data: {}, type: 'post', dataType: 'json',
success: function(json){
if(json.error == 0){
$('#cartId').val(json.data.cart_reference_number);
$form.submit();
}else{
alert(json.message);
}
}
});
}else{
console.log('Submitting form...'); //Does not submit!
}
});
});
The problem is that during the second submit triggered within the success: clause, the form isn't submitted still. I am assuming event.preventDefault() persists beyond the current condition.
How can I get around this?
For performe the any operation before form submit i used the following menthod hope it wil help
$('#checkout-form').live("submit",function(event){
//handle Ajax request use variable response
var err =false;
var $form = $(this);
//alert($form);
var values = {};
$.each($form.serializeArray(), function(i, field) {
values[field.name] = field.value;
});
//here you get all the value access by its name [eg values.src_lname]
var $cartIdField = $('#cartId');
console.log($cartIdField.val());
if($cartIdField.val() == ''){
$.ajax({
// your code and condition if condition satisfy the return true
// else return false
// it submit your form
/*if(condition true)
{
var err =true;
}
else
{
var err = false;
}*/
})
}
else
{
return true;
}
if(err)
{
return false
}
else
{
return true;
}
})
e.preventDefault() remove default form submit attribute which can not be reverted if applied once.
Use below code instead to prevent a form before submitting. This can be reverted.
$('#formId').attr('onsubmit', 'return false;');
And below code to restore submit attribute.
$('#formId').attr('onsubmit', 'return true;');
Only call e.preventDefault() when you really need to:
if(not_finished_yet) {
e.preventDefault();
}

Submit form if ajax validator returns true using jquery

I am not sure where I'm going wrong. The idea is that before the form is submitted, one of the input fields is sent to a server-side validator via ajax. If the response is 1, the input is valid and the form should be submitted. If the response is 0, the form should not be submitted. The issue is that I can't figure out how to set a variable within the ajax request function that will prevent the form from being submitted. This is what I have:
$("#form").submit(function() {
var valid= false;
var input = $("#input").val();
$.ajax({
type: "POST",
url: "validator.php",
data: "input=" + input,
success: function(msg){
valid = (msg == 1) ? true : false;
if(!valid) {
$("#valid_input").html("Please enter valid info");
} else {
$("#valid_input").html("");
}
}
});
return valid;
});
The problem is that the $.ajax request is asynchronous and takes a while to complete. Therefore the function carries on and returns false before the success function is event executed.
To solve this you could add async: false to you settings for the AJAX call, but this would suspend execution until the AJAX call returns.
Another solution would be to create a hidden input in the form called valid:
<input type="hidden" name="valid" value="false" />
Then within the submit function but before the ajax call create a reference to the from var $form = $(this). Then if the AJAX call returns valid change the value of this hidden input, and submit the form again:
$('input[name="valid"]').val('true');
$form.submit();
And then at the end of the submit function only return false if the value of the hidden input is true:
if ($('input[name="valid"]').val() == 'false') {
$.ajax({ ... }); // changes the value of the hidden input from false to true
return false;
}
The success function runs when the HTTP response arrives so valid will always be false.
Call the form's .submit() method if it is valid (and make sure you don't have a form control with the name or id submit as that will clobber the method).
this is assuming that you have loaded the ajax validate plugin and the ajax form plugin,
http://malsup.com/jquery/form/
http://bassistance.de/jquery-plugins/jquery-plugin-validation/
the example below will make all forms with class "ajaxForm" validate and then if valid submit via ajax...
$( document ).ready( function(){setupForms();} );
function setupForms(){
var ajaxOptions = { beforeSubmit:checkForm,
success:function(){
// the ajax was successful
}
};
$( '.ajaxForm' ).ajaxForm( ajaxOptions );
$( '.ajaxForm' ).validate();
}
function checkForm(data,form){
var valid = $(form).valid();
return valid;
}

$.Post with Form submit

...Some form gets submitted...
$.("form").submit(function() {
saveFormValues($(this), "./../..";
}
function saveFormValues(form, path) {
var inputs = getFormData(form);
var params = createAction("saveFormData", inputs);
var url = path + "/scripts/sessions.php";
$.post(url, params);
}
The weird thing is that if i add a function to the
$.post(url, params, function(data) {
alert(data);
}
I get a blank alert statement.
Within scripts/sessions.php i have a function to save whatever the $_POST information is to a file, and the sessions.php never saves this saveFormValues call. It never shows up to the file. But if i keep trying to get it to save, about once every 15 will actually allow it to be saved. This leads me to believe that the forms POST is somehow blocking this value saving post. Any help?
add a return false; to the submit function to prevent the form from submitting:
$.("form").submit(function() {
saveFormValues($(this), "./../.."); return false });
UPDATE:
if you want to later submit the form, keep a variable to indicate if it can be submitted:
var canSubmit = false;
$.("form").submit(function() {
if(!canSubmit)
{
saveFormValues($(this), "./../..");
return false;
}
});
and later:
$.post(url, params, function(data) {
alert(data);
canSubmit = true;
$.("form").submit();
}
So instead of doing a $.post i tried doing a $.ajax with asynch set to false. It saves the form values every ... like 3/5 times... any new suggestions?
You need to cancel the original submit by returning false from the handler. Update: If you want the original form submission to continue, then you can remove the handler and re-submit the form from the post callback.
$.("form").submit(function() {
saveFormValues($(this), "./../..");
return false; // cancels original submit and allows AJAX post to complete
});
function saveFormValues(form, path) {
var inputs = getFormData(form);
var params = createAction("saveFormData", inputs);
var url = path + "/scripts/sessions.php";
$.post(url, params, function() {
$('form').unbind('submit').trigger('submit');
});
}
So i decided to create an associative list of items that will not be saved from a form.
$nosave = array("password" => true, "confirmPassword" => true,
"descriptionCount" => true, "detailedDescriptionCount" => true,
"submit" => true, "action" => true, "p" => true);
//Then i decided to go through the $_POST information and save it to the SESSION info.
foreach ($_POST as $key => $value) {
if ($key != $id && !array_key_exists($key, $nosave)) {
//saves the value to the form.
$_SESSION[$id][$key] = $value;
}
}
//The $id is a hidden input.. name="formId" value="someUniqueId" That way whenever
//the form info is saved, its saved under a unique area and can be easily unset.
Instead of doing it through jQuery, i just called a function that roughly does all of that in my sessions.php file.

Categories