Sending form data without interrupting the user interface by using asynchronous submission

Using jQuery version 1.7.2, I am currently using the submit() method to send a form via POST. This triggers a Python cgi-bin script that performs some tasks which may take around ten seconds to finish. Upon completion of the task, the Python script instructs the browser to download data, for example:

print "Content-Type: text/plain"
print "Content-Disposition: attachment; filename=" + some_filename
print "Content-Description: File to download\n"
print some_stuff

Although the script works well, it causes the user interface of the browser to freeze while waiting for the Python script to complete its job, restricting any actions by the end user.

I am looking for a way to submit the form asynchronously so that the user can continue interacting with the UI while the Python script carries out its tasks.

If that is not possible, I would like to know how to set up an activity indicator during form submission and upon completion of the process.

For example, I attempted to override the submit() function handler, but my approach was unsuccessful:

$('#my_form').submit(function(e) {
    $.ajax({
        type: 'POST',
        url: $(this).attr("action"),
        data: $(this).serializeArray(),
        beforeSend: function() {
            /* show an activity indicator div on the browser window */
        },
        complete: function() {
            /* hide the activity indicator div */
        }
    });
});

Upon submitting the form, the beforeSend and complete functions are executed immediately, rendering this method ineffective in providing visual cues indicating that the browser is busy. Are there alternative methods that can achieve this?

Answer №1

If you forget to include e.preventDefault();, your form will submit to the server without using $.ajax().

Here's how you can fix it:

$(function() {
  $('#my_form').submit(function(e) {
    $.ajax({
      type: 'POST',
      url: $(this).attr("action"),
      data: $(this).serializeArray(),
      dataType: "json",
      beforeSend: function() {
        $("#indicator").show();
      },
      success: function() {
        $("#indicator").hide();
      }
    });
    e.preventDefault(); // Prevents default form submission
  });
});

Python response:

print "Content-Type: text/plain"
print "Content-Disposition: attachment; filename=" + some_filename
print "Content-Description: File to download\n"
print some_stuff

If you're trying to download a file based on the server response, using $.ajax() may not work effectively. In such cases, consider using a hidden iframe.

Updated:

Possible Solution Using Hidden Iframe and jQuery:

To achieve similar functionality as with $.ajax(), use a hidden iframe by setting the target property of the form like this:

<form target="iframeName"></form>
.

Add the following within the form:

<iframe id="ifrHidden" hidden="hidden" name="ifrHidden"></iframe>

Using the hidden iframe eliminates the need for $.ajax();

To mimic the beforeSend function of $.ajax(), try this:

$("#my_form").on("submit", function () {
    $("#indicator").removeClass("hide"); // Remove 'hide' class to show indicator.
});

When the hidden iframe loads (simulating the success function of $.ajax()):

$("#ifrHidden").on("load", function () {
   $("#indicator").addClass("hide"); // Hide the indicator again.
   $("#info").fadeIn(); // Display additional information after request.
});

Implementing the above would look something like this:

Demo

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Stop an item from being included based on a boolean value

I need to iterate through an array of IDs called "world". The idea is that if the ID value in world exists in myArray[n].id, then I want to remove the entire element from myArray. If it doesn't exist, then I want to add it to myArray. world = ["124241 ...

Managing numerous inquiries from a single customer within a succession of brief intervals

After creating a web application with a dashboard to showcase different reports and graphs based on user selections, I encountered an issue. Users can interact with the reports using checkboxes and radio buttons. Every time a checkbox or radio button is s ...

Issues relating to the total count of pages in the uib-pagination component of AngularJS

While there is a previous thread discussing a similar topic Calculating total items in AngularJs Pagination (ui.bootstrap) doesn't work correctly, it does not address my specific issue and I am unsure how to contribute to it. We are using a complex s ...

Exploring Options for Enabling HTML in AngularUI Accordion-Group Content

I want to showcase content in an accordion-group that might contain HTML markup. This content is fetched from external sources. How can I achieve this? You can check out an example at Plnkr (content hard-coded for testing) Currently, the items are displa ...

What steps should be followed to execute this moment.js code in an Angular.js controller using Node.js?

I am trying to adapt the following node.js code that uses moment.js into an AngularJS controller: var myDate = new Date("2008-01-01"); myDate.setMonth(myDate.getMonth() + 13); var answer = moment(myDate).format('YYYY-MM-DD'); To achieve this, I ...

Use jQuery to apply a class to some input elements when certain events like keyup or

If I type something in the input field, it should add a border to the li tag containing the text. The current script works fine, but is there a way to make this jQuery script shorter? Thank you for your help! .add_border{ border: 2px solid #000 !impor ...

Why does Vue 3 refuse to refresh an <img> element, while it successfully refreshes all other components within the same component?

In my current Vue project, I have set up multiple link cards (<a class='card'></a>) inside a "deck" container (<div class='deck'></div>). The implementation for these elements is relatively straightforward: <s ...

Vue: Order Conflict. A new module has been incorporated into the system

Whenever I try to run my program, something unexpected happens; How can I resolve this issue? I don't want to overlook it; I searched online and found suggestions to change the component order, but after checking my code, it didn't work; Any i ...

Is there a way to dynamically enable ui-sref through element.append in Angular?

I am in the process of developing a pagination directive. Once the total_for_pagination data is filled, the appropriate HTML for the pagination gets generated. Here's my current HTML structure with a maximum of 50 per page: <pagination data-numbe ...

What is the best way to retrieve past data using RTK Query?

When working with data retrieval using a hook, my approach is as follows: const { data, isLoading } = useGetSomeDataQuery() The retrieved data is an array of items that each have their own unique id. To ensure the most up-to-date information, I implement ...

Image not showing up when using drawImage() from canvas rendering context 2D

Need help with drawImage() method in JavaScript <head> </head> <body> <script type = "text/javascript"> var body, canvas, img, cxt; body = document.getElementsByTagName("body" ...

Implementation of async operations using while loop in Node.js

I'm facing an issue with my code snippet. Here's what it looks like: Rating.find({user: b}, function(err,rating) { var covariance=0; var standardU=0; var standardV=0; while (rating.length>0){ conso ...

Create a visual representation using a push button

Hey there, I'm attempting to create an image using a button on canvas. However, I'm facing an issue where I can't draw on the clear canvas. Here's my code: <!doctype html> <html> <head> <meta charset="utf-8"> ...

Looking for reliable resources on establishing a connection between a Google account and my application

I am currently working on creating a react native app that aims to simplify the user login process by allowing them to link their Google account with just one click. This way, users won't have to constantly log in every time they use the app. While I ...

Show Text When Clicking Within Separate DIVs

I have a set of three divs. One contains a Twitter icon, another holds a LinkedIn icon, and the last one is designated for displaying text upon clicking. My goal is to click on the Twitter icon and have corresponding text appear in the third div. Then, if ...

What is the equivalent of $.fn in AngularJS when using angular.element()?

Currently, I am conducting a directive unit test using jasmine. The test is now functional, but I need to find an alternative for $.fn in angularjs since the use of $ is prohibited in my workplace. Code: (function scrollTopEventDirective(application) ...

When Django comments go wrong: Issues with Ajax and CSRF verification

Having an issue here that seems a bit different from what others have encountered. I've gone through various answers but still no luck. Appreciate any assistance: I've got a list of News items resembling a Facebook feed, and each one has a comme ...

Limit the 'contenteditable' attribute in table data to accept only integers

I have a question regarding editing table data row. Is there a way to restrict it to only integers? Thank you for your assistance! <td contenteditable="true" class="product_rate"></td> ...

Tips for attaching a "progress" and refresh event to an ajax call while sending a file

I am currently using the FormData API and AJAX to upload files to a server in PHP-CodeIgniter. The file upload works perfectly when triggered by the file select event. However, I would like to display a progress bar next to each file being uploaded with th ...

Access another page by clicking on a link within an HTML document

Is it possible to include an anchor tag in demo1.html that, when clicked, will take the user to the demo2.html page and automatically select a data filter on that page? Here is the code snippet for demo1.html: <li> <div><a href="urunli ...