intercept form submit with jQuery - javascript

I want to intercept a submit via jQuery and first check if a file is present on the server. If it's present continue with the request, if not display a message and don't send the request. This is what I have:
$("#methodForm").submit(function(e){
checkIndex('upload/segments.gen').done(function() {
return true;
}).fail(function () {
e.preventDefault();
alert("No index present!");
return false;
});
});
this is the checkIndex():
function checkIndex(file){
return $.ajax({
url : file,
type:'HEAD'
});
}
What happens is this: The file is present on the server, but the checkIndex returns with fail. First I see the alert popup and then it continues and sends the post request to the server.
I use the checkIndex() for other purposes as well where it works like expected so I'm pretty sure the error is somewhere in the submit routine. But I can't find out what's wrong with it.

You can't return out of a callback to an asynchronous method(such as ajax). Instead, prevent the submit all together, then submit it when you are ready.
$("#methodForm").submit(function(e){
e.preventDefault();
var form = this;
checkIndex('upload/segments.gen').done(function() {
form.submit(); // submit bypassing the jQuery bound event
}).fail(function () {
alert("No index present!");
});
});

It does'nt really work like that, checkIndex is asynchronous, so by the time it returns anything, the form is submitted, and the return statements are in a different scope as well, try something more like this:
$("#methodForm").submit(function(e){
e.preventDefault(); //prevent submit
var self = this;
checkIndex('upload/segments.gen').done(function() {
self.submit(); //submit if ajax OK
}).fail(function () {
alert("No index present!");
});
});

Related

Form that already being validated by JS. Need to have it also clear fields on submit

I have a web form that is part of a CMS, therefore I am not able to alter the input field of the submit button. The form is already being validated by JS, so I need to add a line to the existing code below that will clear the fields.
Currently, the page redirects to a Thank you page on submit. I want it to continue doing that. But, currently, if the user hits the back button on their browser, the data is still there. I need it to submit the data, clear the fields, then redirect to the thank you page.
$('form').submit(function(event)
{
if (validateForm())
return true;
event.preventDefault();
});
Have you tried adding document.querySelector('form').reset() above the return statement? In jquery that might just be $(this).reset(), I'm not sure.
if (data.status) {
$(this).find('input').val('');
// code to redirect to success page here
}
If form is successfully sent, then set the value of all inputs in the sent form to a string with the length of 0.
$('form').submit(function(event) {
event.preventDefault();
if (!validateForm()) {
return false;
} else {
formSubmit($(this));
}
}
);
function formSubmit(form) {
var url = form.attr('action');
var method = form.attr('method');
var data = form.serialize();
$.ajax({
method: method
, url: url
, data: data
})
.done(function (data) {
try {
$(this).find('input').val('');
// code to redirect to success page here
} catch (e) {
console.log(e);
}
});
}
FE validation is bad practice in my honest opinion, just good for lowering the amount of HTTP requests to the server. The hard form data validation should happen on the BE.

Javascript jQuery run ajax, get response before POST

Is there anyway to run an ajax script and have it get a response before running a form POST.
I don't want to post the main form via ajax. I just want it to work whereas when the user hits submit I want ajax to make a call and check a value then when the response comes back then the form will POST via the browser if the response is successful.
Thanks!
you need to intercept the submit event with preventDefault(), then make your ajax call and decide if you should submit the form or not (either traditional POST, or another ajax call)
sample code:
$('.form-selector').on('submit', function(e) {
e.preventDefault();
$.ajax({
// some call you want to make
}).done(function() {
e.target.submit(); // this submits the form without generating the event again
}).fail(function() {
// validation failed, do someting here
});
});
Why do not you try two Ajax call. On success of first ajax call you can POST your data.
So here I mean to say do validation on first Ajax call call and on Success of it do another Ajax call and POST your data to server.
var ajax=false; // form has not been submitted, AJAX not responded
$("form").submit( function(e){
if ( ajax == true ) return true; // if AJAX response, process form normally
// if no AJAX response, prevent form from submitting
e.preventDefault();
// talk to server
$.ajax({
....,
success: function(){
// AJAX successful! change value of variable, and submit form
ajax = true;
$("form").trigger("submit");
})
});
return false;
});
Use onSubmit method of your element, as in <form .... onSubmit="fetchData()">
Now, make your own function:
function fetchData(){
// send your ajax data and validate.
return true; // true or false depending on what you validated
}

jQuery Ajax Race Condition?

I have the below JavaScript code that iterates through a list of textfields on a page. It takes the text in the textfield as a price, sends it to the server via an AJAX GET, and gets the parsed double back from the server. If any of the returned prices are less than an existing price, the form shouldn't submit.
The problem is that the form is submitting before all the AJAX requests are finished because of the non-blocking immediate response nature of the Ajax calls. I need to set up a wait() function (or a callback when all the Ajax methods are complete) but don't know how to do that with jQuery.
Any suggestions?
// .submitForm is a simple button type="button", not type="submit"
$(".submitForm").click(function(e){
var submittable = validatePrices();
if (submittable) {
$("#myForm").submit();
}
});
function validatePrices() {
var submittable = true;
$(".productPrice").each(function(){
var $el = $(this);
$.ajax({
type: "POST",
url: "/get_price.jsp",
async: false,
dataType: "html",
data: "price=" + $el.val(),
success: function(data)
{
var price = new Number(data.split("|")[1]);
var minPrice = new Number($el.data("min-price"));
if (price < minPrice)
{
$el.addClass("error");
$(".dynamicMessage").show().addClass("error").append("<p>ERROR</p>");
submittable = false;
}
}
});
return submittable;
});
}
You're already using synchronous AJAX (a really bad idea for your user experience), so that's not the problem. The problem is that you need to cancel the default action in the "submit" handler:
$(".submitForm").click(function(e){
var submittable = validatePrices();
e.preventDefault(); // this line
if (submittable) {
$("#myForm").submit();
}
});
Using a synchronous HTTP request back to your server for each separate field is going to make your site terribly slow. You're going to have to check the parameters at the server again when you submit the form anyway, so it'd be much better to just check then and return an error.
edit — now that the situation is clearer, I think that the way to proceed is to stop doing the AJAX validation checks completely. Why? Well, even if you perform those tests, you still need to make essentially the same validity tests when the form is actually submitted. You can't rely on the JavaScript validation code actually running, as in any other form validation scenario. If you're doing the validation at form submission time anyway, it'll save on a bunch of HTTP requests to just do it all at the same time.
You're not canceling the form submission. You have to work strictly with the ajax callbacks (if you would like to use them asynchronously, which would be nice).
$(".submitForm").click(function(e){
e.preventDefault();
validatePrices().done(function () { /* ajax success function here */
if (submittable) {
$("#myform").trigger('submit');
}
}
});
function validatePrices() {
var checks = [];
$(".productPrice").each(function(){
var $el = $(this);
checks.push($.ajax({
/* snip */
});
return $.when.apply(null, checks);
}

How to continue form submission after an AJAX call?

I want to validate user entries on a WordPress post upon hitting the submit button, display an error message is there are problems, and submit the form if everything is OK. I have a PHP function that does the checking, returning true if data in form_data is OK, some error code otherwise. The following JavaScript issues the AJAX request, and was supposed to continue submitting the form upon successful checking, but it doesn't:
jQuery(document).ready(function() {
jQuery('#post').submit(function() {
var form_data = jQuery('#post').serializeArray();
var data = {
action: 'ep_pre_submit_validation',
security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
form_data: jQuery.param(form_data),
};
var proceed = false;
jQuery.post(ajaxurl, data, function(response) {
if (response.indexOf('true') > -1 || response == true) {
proceed = true;
} else {
alert("Error: " + response);
proceed = false;
}
});
jQuery('#ajax-loading').hide();
jQuery('#publish').removeClass('button-primary-disabled');
return proceed; //breakpoint here makes the code run
});
});
The code is adapted from a WPSE question, which originally didn't work for me as the form didn't get submitted. I found out that if the jQuery function bound to .submit() returns true, the form should be submitted, so that's what I tried to implement. With the code above, it doesn't seem to work at first (form doesn't get submitted when there are no errors), but upon close inspection with Firebug proceed seems to get the right result if a breakpoint is inserted at the return proceed line. It works as intended with valid data only if I wait it out a bit upon hitting the breakpoint, and then continue execution. If there are errors, the alert is issued without a problem.
What is the best way to handle this?
EDIT
Based on #Linus answer below, the following code works with both valid and invalid data:
jQuery(document).ready(function() {
jQuery('#post').submit(function() {
if(jQuery(this).data("valid")) {
return true;
}
var form_data = jQuery('#post').serializeArray();
var data = {
action: 'ep_pre_submit_validation',
security: '<?php echo wp_create_nonce( 'pre_publish_validation' ); ?>',
form_data: jQuery.param(form_data),
};
jQuery.post(ajaxurl, data, function(response) {
if (response.indexOf('true') > -1 || response == true) {
jQuery("#post").data("valid", true).submit();
} else {
alert("Error: " + response);
jQuery("#post").data("valid", false);
}
//hide loading icon, return Publish button to normal
jQuery('#ajax-loading').hide();
jQuery('#publish').removeClass('button-primary-disabled');
});
return false;
});
});
Short answer: You can't - not in this manner.
Some background: The callbacks you supply as arguments to functions such as $.post are executed asynchronously. This means that you will return proceed before your success callback has been executed, and proceed will always be false. With your breakpoint, if you wait until the success callback has executed, proceed will be true and all will be well.
So, if you want to submit the form after your ajax request has finished, you must submit it using javascript. This is pretty easy with jQuery, just do a jQuery $.post with data: $("yourForm").serialize() and url: yourForm.action.
This is basically what you already are doing, you just have to repeat that call to the URL to which you actually want to post the data.
EDIT:
Another way would be to set an attribute on your form, say valid, and in your submit handler check that:
jQuery("#post").submit(function() {
if($(this).data("valid")) {
return true;
}
// Rest of your code
});
And in the success callback for your validation ajax request you would set/clear that attribute, and then submit:
$("#post").data("valid", true).submit();
EDIT:
You also want to do your "ajax-loading"/button enabling inside the callback for $.post for the same reasons stated above - as it is, they will happen immediately, before your ajax call returns.
Bind your button to a validation function instead of submit. If it passes validation, call submit().
Wordpress has its own mechanism to process Ajax requests, using wp-admin/wp-ajax.php. This allows you to run arbitrary code on either side of the Ajax boundary without having to write the back and forth status-checking code and all that. Set up your callbacks and go....
The real question is - why are you doing validation server-side? Why can't you load in the validation criteria before - as the post is being written? Then your validation can happen real-time and not on-submit.
jquery.post is performed asynchronously, which means the JS will continue before it gets the reply. You're stuck with Diodeus's answer - bind the button to validtion which then submits the form (which makes it not degrade well), or change your $.post to ajax and turn off async, which will force it to wait for response before proceeding...possibly locking up JS on your page until it times out.
$.ajax({
type: 'POST',
url: ajaxurl,
async:false,
data: data,
timeout:3000,
success: function(){
}
});

Using return true or return false on a link with target blank in jQuery

I have a form that has target="_blank"on submit.
I want to validate the form however, prior to it launching the new window. I could use window.open instead, but then it can be blocked by popup blockers.
The problem I'm having is the validation uses ajax and the time it takes to get the response for return false, is too long and it opens the new window.
$('.submit').click(function(){
$.post("/ajax/save/", { state: $('.state_field').val() },
function(data) {
if(data == 'false'){
alert('invalid state');
return false;
}else{
return true;
}
}
);
});
Would anyone have suggestions as how I can workaround this?
Thank you!
(You should probably use $("form").submit(function() {}) because that also catches when somebody presses Enter in a textfield.)
What you could do is
Don't include the target="_blank" in the form
catch the submission and block it (preferably using event.preventDefault();)
do the ajax call for validation
from within the callback: add the target="_blank" and submit the form again (you could use a check like $("form[target]").length == 1 to see if the form is being submitted for the second time.
While this all can make it work, you should think about validating the form right after the user enters data in each field, this will also improve the user experience a lot.
Use the preventDefault method of the event at the beginning of your click.
$('.submit').click(function(event){
event.preventDefault();
[...]
This will stop your form from submitting and is a better solution than using return false;.
If you need to do a redirect after the ajax call you can do that the standard way:
window.location.replace([url to redirect to]);
Popup blockers block the new window if they are opened in script execution context. If the window is opened through user action then it is allowed. You can try to use jQuery ajax in synchronous mode this will solve your other part of the question because the function will not wait untill ajax response comes and you return true/false conditionally.
$('.submit').click(function(){
$.ajax({
url: "/ajax/save/",
type: "POST",
async: false,
data: { state: $('.state_field').val() },
success: function(data) {
if(data == 'false'){
alert('invalid state');
return false;
}else{
return true;
}
}
);
});

Categories