How to: Use Ajax to submit forms with default actions after submit

This code allows you to use your own Ajax form actions instaed of webflow default actions.
This code shows webflow Success and Fail Blocks after action. Also provides custom callbacks for Success response and Error response.

makeWebflowFormAjax = function( forms, successCallback, errorCallback ) {
	forms.each(function(){
		var form = $(this);
		form.on("submit", function(){
			var container = 	form.parent();
			var doneBlock  =	$(".w-form-done", container);
			var failBlock  =	$(".w-form-fail", container);
		
			var action = 		form.attr("action");
			var method = 		form.attr("method");
			var data = 			form.serialize();
			
			// call via ajax
			$.ajax({
				type: method,
				url: action,
				data: data,
				success: function (resultData) {
					if (typeof successCallback === 'function') {
						// call custom callback
						result = successCallback(resultData);
						if ( ! result ) {
							// show error (fail) block
							form.show();
							doneBlock.hide();
							failBlock.show();
							console.log(e);
							
							return;
						}
					}
					
					// show success (done) block
					form.hide();
					doneBlock.show();
					failBlock.hide();
				},

				error: function (e) {
					// call custom callback
					if (typeof errorCallback === 'function') {
						errorCallback(e)
					}
					
					// show error (fail) block
					form.show();
					doneBlock.hide();
					failBlock.show();
					console.log(e);
				}
			});
			
			// prevent default webdlow action
			return false;
		});
	});
}

To use this ajax action on all forms on the page:

	makeWebflowFormAjax( $("forms") );

To use this ajax action on specific form with id formID:

	makeWebflowFormAjax( $("#formID") );

URL should me set in Form “Action” parameter in Webdlow page editor.

9 Likes

This is great, @victornikitin!

Where would I need to place the following to use this ajax action on all forms?:

makeWebflowFormAjax( $("forms") );

Main code (with function declare) can be place anywhere on the page. If you plan to use this code on all pages the best way is to put it in Embed element and include this block into symbol that is part of all pages (like header or footer). If you plan to use it on specific page you can put it into “Before tag” on page settings panel.

Second code (call of makeWebdflowFormAjax() function) should be anywhere too. But, it uses jQuery library which is loaded after all page content. This code should be after that, but it is imposible in Webflow. So the best way is to include it into “Before tag” on page setting panel. But if you plan to use this code for all pages (for example for contact form) you can place this code into Embed object too with a trick: call function in setTimeout. So this code will work even it is placed before jQuery declaration.

<script type="text/javascript">
setTimeout(function(){
	makeWebflowFormAjax( $("#formID") );
 }, 1000);
</script>

Don’t forget to include both codes into tag like in last example.

2 Likes

Oh, this worked so perfectly, @victornikitin!

I cannot thank you enough. PERFECT PERFECT!

Thank you :blush:

I tried this code here – the form successfully pushes data to external system, but always returns error state.

What is wrong? How can I fix that?

@DGDG Looks ok to me

Screenshot_2018-01-19_090116

Thanks @victornikitin. The code works great. I do have one follow-up question.

After the ajax post, is there a way to call the “normal/default” Webflow action for a form so that the form is also inserted into the “Forms” section of the Editor? We are posting our form to our own external API but would like for the form submission and fields to also flow into the normal Webflow forms section so the end user can see the form submissions.

Thanks in advance!

Hi @manrysj, that is not yet possible if you are using POST as the form method with a custom Action URL.

It is possible to save forms in Webflow and a third party service if you use Zapier: Zapier Integration | Webflow University, however I am not sure how that will work with your custom code.

I hope this helps

This is really cool! I’ve always just created my own form elements to get around the Webflow form success and error blocks because I don’t like how they persist and the form doesn’t reset.

It had never really occurred to me to target those success and failure elements by class name and manipulate them to do what I want. I’m all inspired to give this a go now. Great post!

1 Like

Hi @victornikitin,

Thanks for this great post!
After trying to get the forms working (and looking good) on exported sites I think this thread is the closest to the solution I am looking for.

So I placed this code in head code (under custom code for whole project):

<script type="text/javascript">
makeWebflowFormAjax = function( forms, successCallback, errorCallback ) {
	forms.each(function(){
		var form = $(this);
		form.on("submit", function(){
			var container = 	form.parent();
			var doneBlock  =	$(".w-form-done", container);
			var failBlock  =	$(".w-form-fail", container);
		
			var action = 		form.attr("action");
			var method = 		form.attr("method");
			var data = 			form.serialize();
			
			// call via ajax
			$.ajax({
				type: method,
				url: action,
				data: data,
				success: function (resultData) {
					if (typeof successCallback === 'function') {
						// call custom callback
						//result = successCallback(resultData);
						if ( ! result ) {
							// show error (fail) block
							form.show();
							doneBlock.hide();
							failBlock.show();
							console.log(e);
							
							return;
						}
					}
					
					// show success (done) block
					form.hide();
					doneBlock.show();
					failBlock.hide();
				},

				error: function (e) {
					// call custom callback
					if (typeof errorCallback === 'function') {
						errorCallback(e)
					}
					
					// show error (fail) block
					form.show();
					doneBlock.hide();
					failBlock.show();
					console.log(e);
				}
			});
			
			// prevent default webdlow action
			return false;
		});
	});
}
</script>

And this I placed in the before section of the specific page with the form (index.html):

makeWebflowFormAjax( $(“forms”) );

Tried both with and without - both don’t work (it should be in right?)

In the form setting I do a post request to a webhook on Zapier. The request works and I get the reply from Zapier.

This reply is what I wish to avoid with this solution you suggested. Meaning I send the stuff to Zapier and then change the state of the form to Successful.

This is the site http://a7n.webflow.io

Would really appreciate your help to understand what’s not working right here :slight_smile:

The selector is wrong, should be $(“form”) not $(“forms”)

Working! Thanks @Colin_Gu

Just in case anyone is also having the same case - the makeWebflowFormAjax( $(“form”) ); must be wrapped with

One issue I am still troubleshooting is the Recaptcha and the script.
Whether recaptcha is selected or not - the script will switch to Thank you message.

If anyone has a solution for this - please share :slight_smile:

1 Like

Hi
I have been trying to achieve the same thing. I’m using the same tektite method as you have used from another post and the posting works to a success page. Now I am trying to achieve the same without the redirection to the success page as you have in this post. However I still just get sent the success page!
I have pasted the main code into the head of the page via settings:

<script type="text/javascript">
makeWebflowFormAjax = function( forms, successCallback, errorCallback ) {
	forms.each(function(){
		var form = $(this);
		form.on("submit", function(){
			var container = 	form.parent();
			var doneBlock  =	$(".w-form-done", container);
			var failBlock  =	$(".w-form-fail", container);
		
			var action = 		form.attr("action");
			var method = 		form.attr("method");
			var data = 			form.serialize();
			
			// call via ajax
			$.ajax({
				type: method,
				url: action,
				data: data,
				success: function (resultData) {
					if (typeof successCallback === 'function') {
						// call custom callback
						//result = successCallback(resultData);
						if ( ! result ) {
							// show error (fail) block
							form.show();
							doneBlock.hide();
							failBlock.show();
							console.log(e);
							
							return;
						}
					}
					
					// show success (done) block
					form.hide();
					doneBlock.show();
					failBlock.hide();
				},

				error: function (e) {
					// call custom callback
					if (typeof errorCallback === 'function') {
						errorCallback(e)
					}
					
					// show error (fail) block
					form.show();
					doneBlock.hide();
					failBlock.show();
					console.log(e);
				}
			});
			
			// prevent default webdlow action
			return false;
		});
	});
}
</script>

and then pasted the rest into the before body tag via settings:

<script type="text/javascript">
makeWebflowFormAjax( $(“forms”) );
</script>

Still not working though. I have tried the second code with and without the script tag wrap but makes no difference.

Do you have any tips???

Blockquote

1 Like

This is a great tip - really useful. It should be categorised in Tips & Tricks - I’m not sure who can update that - maybe @PixelGeek @cyberdave

Hello!

So I added this script to my forms and it worked great! I went in and added Google’s invisible recaptcha v2 and the ajax inline message doesn’t work anymore. Forms are located here and here (at the end of the page).

i have the same issue here.

Did you succeed solving this??

Hello All,
I have handled form data submission to REST api that built on aws api gateway and lambda.
So just sharing with community.

	<script type="text/javascript">

		// id of your form, with prefix # for jquery
		var formId = "#wf-form-contact";

		makeWebflowFormAjax = function( forms, successCallback, errorCallback ) {
			forms.each(function(){
				var form = $(this);
				form.on("submit", function(event){
					var container = 	form.parent();
					var doneBlock  =	$(".w-form-done", container);
					var failBlock  =	$(".w-form-fail", container);
					var action = 		form.attr("action");
					var method = 		form.attr("method");

					// collect data from form inputs, you need to change according to you form input and it's ids.
					var data = {
						'email': $(formId+" #email").val(), 
						'zipcode': $(formId + " #zipcode").val()
					};

					// call via ajax
					$.ajax({
						type: method,
						url: action,
						cors: true,
						contentType:'application/json',
						dataType: 'json',
						headers: {
							'Accept': 'application/json',
							'Content-Type': 'application/json'
						},
						data: JSON.stringify(data),
						success: function (resultData) {
							if (typeof successCallback === 'function') {
								// call custom callback
								result = successCallback(resultData);
								if ( ! result ) {
									// show error (fail) block
									form.show();
									doneBlock.hide();
									failBlock.show();
									console.log(e);
									return;
								}
							}
							// show success (done) block
							form.hide();
							doneBlock.show();
							failBlock.hide();
						},
						error: function (e) {
							// call custom callback
							if (typeof errorCallback === 'function') {
								errorCallback(e)
							}
							// show error (fail) block
							form.show();
							doneBlock.hide();
							failBlock.show();
							console.log(e);
						}
					});
					// prevent default webdlow action
					event.preventDefault();
					return false;
				});
			});
		}

		makeWebflowFormAjax( $(formId) );
	</script>
5 Likes

Wow this looks great - is it possible to combine this functionality (sending data to aws lambda api) and this example of depicting data returned from a third party? Meaning - I’d love to post data to my api on aws, and return the data to webflow, styled using the technique like the one in the link?

I tried to follow this but the posted form is empty? I’m new to Javascript so not sure what might be going on. The form works fine if I don’t use this script and stick to the default Webflow behaviour.

1 Like