
The Problem
A client asked for help with invoking a jQuery ajax function during the submit of a Formidable Pro form. The client had written an elaborate jQuery routine that was triggered in $(document).on('submit'). The goal for the ajax call was to retrieve a confirmation number from a database. The ajax function needed to pass the values from the form's data entry fields to the processing script on the server. This is why the developer chose to use document on submit. When the confirmation number is returned from the server to the client, the value is written to a hidden field on the form as well as a display element on the form's success page. When saved, a PDF version of the form was created with the FormidablePro2PDF plugin and made available for download through a link on the form's success page.
This is a complex process and the results were very inconsistent. The confirmation always displayed on the success page, but almost never got written to the form entry in the database nor would it display on the PDF version of the form. We were tasked to figure out what was happening.
Had we been contracted to write the code in the first place, we probably would have opted to use Formidable Pro's built-in hooks, such as frm_pre_create_entry or something else that fires before the data is written to the database. But since, jQuery/Ajax was chosen as the vehicle to complete this process, we needed to fix it so it worked consistently.
The Analysis
To analyze this problem, it is critical to understand two important concepts:
First, the JavaScript interpreter is a synchronous engine. Synchronous means that the JavaScript interpreter executes only one line of code at a time in succession. It continues to execute one line at a time until the script is finished. It is not capable of asynchronous execution, meaning that it cannot execute multiple lines of code at a time. By now you're probably thinking, "Whoa! What about ajax? Doesn't the 'A' in ajax mean asynchronous?" Yes it does, but it doesn't mean asynchronous in the way you may be thinking.
This brings us to our second key concept. When we think of a browser, we may think of it in terms of the browser engine such as Blink, EdgeHTML, Gecko, or Webkit, but browsers are actually composed of multiple engines. Take a look at the reference architecture diagram from Reference Architecture for Web Browsers by Alan A. Grosskurth and Michael W. Godfrey from the School of Computer Science, University of Waterloo in Canada:

Some of the browser's components are:
- The user interface—this includes the address bar, back/forward button, bookmarking menu etc. Every part of the browser display except the main window where you see the requested page.
- The browser engine—the interface for querying and manipulating the rendering engine.
- The rendering engine—responsible for displaying the requested content. For example, if the requested content is HTML, it is responsible for parsing the HTML and CSS and displaying the parsed content on the screen.
- Networking—used for network calls, like HTTP requests. It has a platform independent interface and substructure implementations for each platform.
- UI backend—used for drawing basic widgets like combo boxes and windows. It exposes a generic interface that is not platform specific. Underneath it uses the operating system user interface methods.
- JavaScript interpreter—Used to parse and execute the JavaScript code.
- Data storage—This is a persistence layer. The browser needs to save all sorts of data on the hard disk, like cookies for example. The HTML5 specification defines this as a 'web database', which is a complete (although light) database in the browser.
So what happens when a synchronously executing jQuery script invokes an ajax function? The JavaScript interpreter hands the request over to the Networking engine to execute the HTTP GET request asynchronously, meaning the HTTP GET request executes while the JavaScript interpreter finishes processing its script. After the hand off to the Networking engine, the jQuery Script doesn't wait for a result to return. It continues processing synchronously, one line of code at a time, until it finishes the script. In this case, the analysis revealed that the form's submit handler was executing and writing the data to the database before the ajax function returned its result. It is all a matter of timing.
The Solution
The key to solving this timing issue is to prevent the form.submit() from firing until the networking engine has completed executing the HTTP GET request initiated by the ajax function. To do this we changed the trigger event from $(document).on('submit') to $("#btnSubmit").on( "click"). In the attached function, we immediately invoke e.preventDefault(), which stops the form.submit() from firing. We also needed to create a couple of callback functions for the done() and always() methods of the ajax object. The following code is a brief representation of the solution. We hope it helps with your own ajax related issues.
Thank’s for this article. I think you have to make video tutorial :D
I’ve been planning new videos for awhile. Thank you for encouraging me to make them again.