Alright so i have form validation function.the function runs through form validation functions that returns false if the field isn't valid.
The problem is when it get to the function that uses ajax to check if the field is valid.
for some reason its seems that it doesn't "wait" for ajax to return and returns false automatically.
is there a way around this?
Here is the code:
function form_validation(){
if (!NewValidationForm('pcode', 'Please fill in all the fields'))
return false;
if (!NewValidationForm('fname', 'Please fill in all the fields'))
return false;
if(!validate_coupon()){
alert("bad!!");
return false;
}
return true;
}
function validate_coupon(){
var url = $j("#site_url").val() + 'ajax_functions.php';
var coupon = $j("#pcode").val();
var result_status = false; // seem its jumps from here to:
$j.ajax({
type: "POST",
url: url,
data: { ajax: 'ajax', coupon: coupon}
}).success(function(insertID){
var obj = $j.parseJSON(insertID);
if(obj.status == 1){
result_status = true;
}
});
// straight over here
if(result_status == true){
return true;
}
}
Usually in this situation I do something like this in $(document).ready():
$('form').submit(function (evt) {
if (!$(this).attr('data-submitted')) {
evt.preventDefault();
$(this).attr('data-submitted', 'true');
// call your form validation code here that fires the ajax request
return false;
}
return true;
});
Then, in your $.ajax callback, when your validation completes, call $('form').submit(). This effectively uses an attribute on the form as a flag for whether the state of the validation request. When the user first submits the form, the flag gets set and the validation process begins. When the validation completes, the form's submit event is triggered, and since the flag is set, this time the form gets submitted like normal.
If this approach works for you, you'll probably want to add a little polish. For example, you'll probably want to disable the submit button before calling $.ajax and enable it again if the validation fails. You'll also probably want to remove the data-submitted attribute from the form if the validation fails, since the user might submit the form a second time and you presumably want to perform another validation in that case.
Related
When I press the Form Submit button, I want to action some validation (via an Ajax call), and change a screen value, before the Form is actually submitted.
My issue is that when I try this, and I manually action the Submit button, the screen value is not actually updated until the Form has been submitted. Too late!
Is there any way around this issue? I've tried to comment in the code exactly what I mean.
$("form").submit(function (event) {
// we prevent teh default action of the udpate button
event.preventDefault();
alert('In Jquery/JS.. button pressed / Prevented default');
// variables for "self" so we can access the form
// nativley using javascript and not jquery
var self = this,
root = 'https://jsonplaceholder.typicode.com';
// Now call Ajax, get results, and if good, manually call the
// submit button.
$.ajax({
url: root + '/posts/1',
method: 'GET',
success: function (data) {
alert('in ajax success');
}
}).done(function (data) {
alert('in ajax done - Title data = : ' + data.title);
if (data.title !== "") {
// We assign our Input Text field some data
$('#textfield').val(data.title);
// The on screen value actually hasn't updated :o(
alert('about to self submit');
// We go to submit... but our form isn't actually
// updated with the Ajax text yet...
// is that possible before we action the submit???
self.submit();
}
}).fail(function () {
alert('error');
});
});
See JSFiddle : https://jsfiddle.net/dave_pace/890zmj1f/
It is not what you think. JavaScript is single-threaded. Therefore, an alert statement is executed just after its previous statement. It doesn't wait for the previous statement to finish.
Adding to that, alert is quicker than setting the value in the textbox, and it actually blocks the thread until it is dismissed. That's why you cannot see the value set in the textbox, but can see the submit alert first.
Your fiddle is fine, and works as it should. If you want to test this, try to remove all the alert statements from your code, and try to submit your form to an actual URL, for example https://www.google.com.
Though submitting to Google will result in an error, you can actually see that the textbox is being populated before the submit happens.
basically i have a form and in that form i have a username textbox with a submit button.
now what i want is that before we submit the form i want to send the text value to server so the server could check if the username has not been taken by any other user and then submit the form, based on research i had, i found this tutorial useful https://scotch.io/tutorials/submitting-ajax-forms-with-jquery, altough this tutorial is using php for server coding and i am using java servlet but my ajax script never gets to execute.
here is my code:
<html>
<head>
<meta charset="utf-8" name="viewport" content="width=device-width, initial-scale=1">
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"> </script>
<script>
$(document).ready(function() {
// process the form
$('form').submit(function(event) {
// get the form data
// there are many ways to get this data using jQuery (you can use the class or id also)
var formData = {
'username' : $('input[name=UserName]').val(),
};
alert('hello');
// process the form
$.ajax({
type : 'POST', // define the type of HTTP verb we want to use (POST for our form)
url : '../postr', // the url where we want to POST
data : formData, // our data object
dataType : 'json', // what type of data do we expect back from the server
encode : true
})
// using the done promise callback
.done(function(data) {
// log data to the console so we can see
console.log(data);
// here we will handle errors and validation messages
});
// stop the form from submitting the normal way and refreshing the page
event.preventDefault();
});
});
</script>
<form class="Registration_Form" id="Registration_Form" action="../postr" method="POST">
<div id="Registeration_Username_DIV" class="Registeration_Username_DIV">
<input type="text" id="Registeration_Username_box" class="Registeration_Username_box"
name="UserName" onblur="Usernameerrorfunc(this, 'Usernameerror_spn', 'Usernamenowallow_spn');" maxlength="30" onclick="textboxfocus(this)"/>
</div>
<div class="Registration_Submit_Div">
<input type="submit" value="submit" id="SumbitForm_btn" class="SumbitForm_btn" name="Submit_btn"/>
</div>
</form>
<script>function Usernameerrorfunc(field, errordiv, Notallowcharserror_SPN){
if (field.value == '') {
field.style.borderColor = "red";
document.getElementById(Notallowcharserror_SPN).style.visibility = "hidden";
document.getElementById(errordiv).style.visibility = "visible";
} else if(!field.value.match(/^[a-zA-Z0-9~`!##\(\.)]+$/)){
field.style.borderColor = "red";
document.getElementById(Notallowcharserror_SPN).style.visibility = "visible";
document.getElementById(errordiv).style.visibility = "hidden";
} else {
field.style.borderColor = "rgb(150,150,150)";
document.getElementById(errordiv).style.visibility = "hidden";
document.getElementById(Notallowcharserror_SPN).style.visibility = "hidden";
}
}</script>
as you can see in my ajax script i have an alert() which it should pop up hello but it never does
Good Morning!
I think there are several things to say about your code. First of all your submit function:
$('form').submit(function(event) { ... }
Here you want to catch the submit-event when the user hits the button. Everything good, but since your button is of type=submit the browser will also react on the click and handle the submit-process by itself. Your function won't get called properly. To prevent this you have to escape the default behaviour of your form on submitting:
$('form').submit(function(event) {
event.preventDefault();
$.ajax({ ... });
}
This will do the trick to let the browser do what you want instead of handling the submit by itself.
So now your browser can run your ajax call.
Next thing: The ajax-call.
You did many things right, but some important things wrong. Look at the following structure:
$.ajax({
url: 'your_url_to_send_data_to',
type: 'post', //the method to use. GET or POST
dataType: 'json',
data: data, //your data: {key1:value1, key2:value2}
success: function(data) { //handle a successfull response (200 OK)
alert(data);
//here you can do with your data whatever you want
},
error: function(jqXHR, textStauts, errorThrown){ //handle every error. e.g. 500
alert(textStatus + ': '+errorThrown);
}
}});
This will handle the sending and the recieving of your request. The success function will get called if the server returns an 200 OK. Otherwise the error function gets called.
Now you just have to handle the request on server side properly.
Third thing: What's about the real submit after the name-check?
Since you preventDefault() the default browsers action, sou have to do it manually. You could think of triggering the submit again, but you would ran another time in your own function you've written so far.
Therefore you have to do it by your own. But wait! You can combine the two things in one call!
Think about this:
let the user fill your form
let him hit the submit button
preventDefault behaviour of your browser and build a FormData and put all your values in it
prepare your ajax call
send the FormData with your ajax call to your server
Handle name-check and all other things on server-side
answer the request
evalutate the answer in your success function
Note: On server side you have to print the application/json header to let the browser and finally your ajax call handle your answer properly.
Since you want a dynamic check of the user name availability, I suggest you react to the keyup event (note: I also added support for other possible change-incurring events in my demo below) and schedule a check run after a fixed delay. Once the delay transpires, if the user hasn't typed anything in the interim, you can run the AJAX check and update the page; if the user did type something in the interim, you can simply not run the check (yet). This means a check will automatically be run after every flurry of typing, as long as the user ceased typing for at least the hard-coded delay.
With regard to submitting, I would just allow the user to submit the form in the normal way without any last-second AJAX check of user name availability. You're still going to have to perform a server-side check for availability, in case the user disabled JavaScript or somehow constructed their own submit HTTP query, so you may as well depend on that server-side check upon form submission. The dynamic AJAX check is really only beneficial as a quick notification to the user, and so should only be provided if the user edits the user name, and then does not submit the form immediately. Most of the time the user will not submit the form immediately after editing a field, and most users can be relied upon to not submit the form if it is clearly indicated on the page that there is a validation failure.
var USERNAME_CHECK_DELAY = 800;
var userInputValCount = 0;
var userInputVal = '';
window.handlePossibleUserInputChange = function() {
let $userInput = $('#userInput');
let $checkDiv = $('#userCheckLine');
// if this event doesn't reflect a value change, ignore it
if ($userInput.val() === userInputVal) return;
userInputVal = $userInput.val();
// update the value count
let userInputValCountCapture = ++userInputValCount; // closure var
// schedule a potential check run
setTimeout(function() {
// only check the current name if the user hasn't typed since the provoking event
if (userInputValCountCapture !== userInputValCount) return;
checkUsername();
},USERNAME_CHECK_DELAY);
// update the status message
if ($userInput.val().trim() === '') {
$checkDiv.text('');
} else {
$checkDiv.attr({'class':'checking'});
$checkDiv.text('checking...');
} // end if
};
$('#userInput')
// listen to all events that could cause a change in the input value
.on('keyup change',handlePossibleUserInputChange)
// drop is special; the drop event unfortunately fires before the text is changed
// so we must defer the call until after the text is changed
// same with mouseup; occurs when clicking the input box X button in IE
// same with paste via context menu, rather than shortcut (which would trigger keyup)
.on('drop mouseup paste',function() { setTimeout(handlePossibleUserInputChange); })
;
var lastTaken = true;
window.checkUsername = function() {
let $checkDiv = $('#userCheckLine');
let $userInput = $('#userInput');
// just reset the check line if the input value is empty
if ($userInput.val().trim() === '') {
$checkDiv.text('');
return;
} // end if
// ... send ajax call, get result ...
// (for demo purposes, just invert the previous result)
let taken = lastTaken = !lastTaken;
if (taken) {
$checkDiv.attr({'class':'taken'});
$checkDiv.text('user name is taken.');
} else {
$checkDiv.attr({'class':'notTaken'});
$checkDiv.text('user name is available.');
} // end if
};
.taken { color:red; }
.notTaken { color:green; }
.checking { color:grey; font-style:italic; }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="form1">
<div>
<input id="userInput" type="text" placeholder="username"/>
<span id="userCheckLine"></span>
</div>
<input type="submit" value="Submit"/>
</form>
I think you should use the "remote" of jquery validation (https://jqueryvalidation.org/remote-method/) this check the validation of the field in the server. You need jquery.
$("#Registration_Form").validate({
rules: {
Registeration_Username_box: {
required: true,
remote: {
url: "check-email.php",
type: "post"
}
}
}
});
I am doing ajax cross domain request to my php page on server.
I am posting form from html via ajax to my php page on server.
Have problem with validation in client side.
I don't know how to do validation in client side before send form.
html form is standard form, posting input fields: name, last name, message....
My html form, client side:
<script type="text/javascript">
var output = $('.nesa');
$(document).ready(function(){
$("#form1").submit(function (e) {
e.preventDefault();
$.ajax({
url: 'http://www.example.com/form.php',
crossDomain: true, //set as a cross domain requests
type: 'post',
data: $("#form1").serialize(),
beforeSend: function (){
// add spinner
$('.spinner').append('<img id="animacija" src="spinnersmall.gif" alt="Loading" />');
},
success: function (data) {
$(".nesa").html(data);
alert("sent " + data);
},
error: function(){
output.text('Message is not sent!');
}
});
});
});
How to to validation? I try to put code in beforeSend but without success.
Or maybe to use submitHandler?
Idea is when user click submit, that validation start, and if fails to tell "insert your email address". Now when i click submit it send data to server. I want that first check input fields.
This form is actual working it sending data to server, but just need to figure out how to do validation. Where to put validation in ajax call?
Thanks
Create a function to validate form which return true/false. Call the function just before the $.ajax. check if return is false then return.. see the example below...
if(!validateForm())
return false;
First, are you actually using an AJAX form?
You explained that you load the form itself via AJAX, but do you send it that way, too? It looks to me that you're trying to send it the HTML way. You can hook into the click event of the send button before you send the form. However, since the button is added to the page at runtime, you need to register the event to document.
$(document).on('click', 'input[type=submit]', function() {
// Validate form
// Add error message on fail, and return
// Else submit form via AJAX
});
In either case, you can use jQuery's blur event as an alternative to validate each field when the user jumps to the next. You could even validate every time the user presses a key with keypress.
I always validate them right before I enter them into an AJAX call. Here is my exampel
$('#form_nieuwsbrief').bind('submit',function(){
var name = $('input[name=naamNieuwsbrief]').val();
var email = $('input[name=emailNieuwsbrief]').val();
var proceed = true;
if (name==""){
$('input[name=naamNieuwsbrief]').css({'border':'2px solid red'});
proceed = false;
}
if (email==""){
$('input[name=emailNieuwsbrief]').css({'border':'2px solid red'});
proceed = false;
}
if(proceed == false){
$("#msg").append("<div class='alert alert-danger' role='alert'>U bent informatie vergeten in te vullen.</div>");
setTimeout(function(){
$('.alert').fadeOut(400, function(){
$(this).remove();
})
;},10000
);
}
if(proceed == true){ // make the ajax call
This is just a quick one for a newsletter that just requests name and email. But the principle is the same. Just before you make an ajax call, create the if else statement with a variable you set if something is false. else you stick it tot he original validation, thus you can proceed.
Please validate the form before sending ajax request. If there is no error then ajax request should be send otherwise return false.
You can do like:
$("#form1").submit(function (e) {
e.preventDefault();
// Get the Login Name value and trim it
var name = $.trim($('#name').val());
// Check if empty of not
if (name === '') {
alert('Text-field is empty.');
return false;
}
});
You can see the demo Here's (http://jsfiddle.net/LHZXw/1/)
You can also make a function onKeyup.
You're already validating via server side correct? Why don't you use that same validation rules to appear like your client side - via Ajax. I have a tutorial on how to do that:
http://michaelsoriano.com/how-to-ajax-validate-forms/
When the city input field is blurred I get somnething via an ajax request and set that as the value of a hidden field in the same form that the city field resides in.
$('input#city').on('blur', function() {
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
}
});
});
If the user submits the form immediately after blurring off the city field sometimes due to latency the hidden field is not populated because the SQL on the other end is taking too long.
The form that both these fields are in is also submitted via ajax:
$('form#find-users').on('submit', function() {
if(NO_AJAX_CURRENTLY_RUNNING_ON_PAGE) {
// do stuff
}
});
How to detect if no ajax is running on the page? This will ensure that the city ajax was completed and the hidden field populated before the form is processed.
EDIT
Actually it won't, it will only prevent the form from being submitted. But if I can detect that then I can use a setInterval and keep trying to run that code until it runs because ajax is complete. Ideally there will be something in jQuery that waits until other ajax is complete and then submits.
Use jQuery's Ajax Events. As long as all of your Ajax calls are generated using jQuery, you have a way of knowing if any Ajax calls are outstanding.
$(document).ready(function() {
var ajaxBusy = false;
$(document).ajaxStart( function() {
ajaxBusy = true;
}).ajaxStop( function() {
ajaxBusy = false;
});
});
Edit:
So that answers your direct question about "How do I know if there is any Ajax call running."
Alternatively, you could disable the form's submit buttons when run your blur handler, and then re-enable it when you're done.
$('input#city').on('blur', function() {
var submit = $(this).closest('form').find(':submit:enabled');
submit.prop('disabled', true);
$.ajax('get/something?param=val').done(function(response) {
$('input:hidden[name="something"]').val(response);
}).always(function() {
submit.prop('disabled', false);
});
});
Edit 2:
So now we're at the point where we would like to delay the form submission until all current Ajax calls have completed. We let people click on the submit button, but if there are pending Ajax calls we don't do anything right away.
We can use a Deferred object to help us with this.
$(document).ready(function() {
var ajaxDefer = $.Deferred().resolve();
$(document).ajaxStart( function() {
ajaxDefer = $.Deferred();
}).ajaxStop( function() {
ajaxDefer.resolve();
});
$('form#find-users').on('submit', function() {
ajaxDefer.always(function() {
// Code here will always be executed as soon as there are no
// Ajax calls running.
// this points to the deferred object (ajaxDefer), so use the closure
// to carry over any variables you need.
});
});
});
When we're just starting out, we set up our ajaxDefer object in a resolved state. That means any functions attached using .always() will execute immediately.
When the first Ajax call starts, we replace the old ajaxDefer object with a new one that has not been resolved. Any new functions attached using ajaxDefer.always() will be deferred until later.
When the last Ajax call completes, we call ajaxDefer.resolve(), which causes any unexecuted deferred functions to execute. Now we're back to our initial state, where any newly-attached functions will execute immediately.
When somebody tries to submit the form, create an anonymous function that does the work and attach it to ajaxDefer. It will get executed when appropriate, depending on if there are any outstanding Ajax requests or not. Be mindful of your closures.
Use this to check if AJAX calls are currently in-progress using JQuery:
if ($.active == 0) {
...
}
you can put a variable in the global namespace, perhaps named ajaxLock and toggle it on when AJAX starts and off when the response comes. Then check it before allowing submit.
something like
var ajaxLock = 1;
$('input#city').on('blur', function() {
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
ajaxLock = 0;
}
});
});
Use a lock variable like you suggested:
$('input#city').on('blur', function() {
window.AJAX_CURRENTLY_RUNNING_ON_PAGE = true;
$.ajax({
url: 'get/something?param=val',
success: function(response) {
$('input:hidden[name="something"]').val(response);
},
complete: function() { window.AJAX_CURRENTLY_RUNNING_ON_PAGE = false; }
});
});
$('form#find-users').on('submit', function() {
if(window.AJAX_CURRENTLY_RUNNING_ON_PAGE) {
return;
}
//dostuff
});
What i could have done on this circumstances is to use plugin like block ui or disable the form submit button,the reason is you need to be interactive in your design,you may well able to lock the form submission,but its better to give a message or have a modal gray out
I originally had the return true/false in my ajax callback, and realized it's probably not in the right context to be called, so I rewrote my function as follows, but it is still not working. Is the submit variable not carrying through from the callback function either? The confirmation (if .btn-danger) is working, but not just if you hit submit and confirmation is not needed)
$('#form').submit(function(e){
var submit = false;
if($('.btn-danger').length){
submit = true;
} else {
$.ajax({
url: base_path+"ajax/myajaxfile",
type: "post",
data: {
data1 : $("#amount").val(),
data2 : $("option:selected").val()
},
dataType: "json",
success: function(data) {
if (data.needconfirmation === 'true'){
$('#edit-submit').val("Confirm");
$('#edit-submit').removeClass("btn-primary");
$('#edit-submit').addClass("btn-danger");
$('#payment-form').after('<span class="warning"> Do you really wanna?</span>');
} else {
submit = true;
}
},
error: function(data) {
alert("an error has occurred");
}
});
}
if (submit){
return true;
} else {
return false;
}
});
I think your issue is that ajax calls are asynchronous by default - so the return value of the function is being evaluated before the success function is ever called, and therefore the submit variable is still false.
You need to either make the ajax call synchronous:
async: false
or probably better would be to restructure it.
One of the most confusing aspects of doing AJAX for the first time is Asynchronous part. With normal Javascript (well, normal jQuery at least), you handle a submit like so:
$('#form').submit(function(e){
var submit = /*Figure out if it was a success or not*/;
if (submit){
return true;
} else {
return false;
}
});
An event triggers a submission, you figure out whether or not it's valid, and then you either proceed or you don't.
With an AJAX submission though that "Figure out if it was a success" step happens outside the normal flow of things. This means that what you want to do is ALWAYS return false; you don't know whether to proceed yet, so don't proceed. Your AJAX callback (the "success:" function in your AJAX call's options) is whether the "figure out" code goes, and your's currently has the right idea with "success = true" ... except that by the time it resolves, your original submit function will already be over (you'll have returned false to it).
So, what you then need to do is modify your success handler to do ... whatever it is that normally would happen when you submit. This might be as simple as form.submit() of a hidden form, or it might be more complex; I don't know your app. Hopefully this gives you the basic idea though.
$.ajax is asynchronous, so the rest of your code continues on before the success callback happens, so it setting submit = true doesn't affect the check at the end of your function.
The confirmation (if .btn-danger) is working, but not just if you hit submit and confirmation is not needed
How do you know if confirmation is needed or not? You may want to add a check for that where you check for .btn-danger.
Also, you can clean up the last bit of your code by just doing
return submit;