Display a progress bar showing the progress of the form submission

This question is not fully answered, please feel free to contribute!


I am trying to display a simple progress bar while a large form is submitting.


The form contains a dozen fields, as well as fields for downloading files, where the user can select an image. Then, when he clicks the Create button, a form with data and images is submitted, and the object is created in the database. (just one click to send the form and photos).
Everything is working fine, but I want to display a progress bar during the sending process.


I found many tutorials explaining how to display a progress bar, but I do not find anyone to explain how to display a progress bar showing the percentage of work completed by a method , i.e. d like to see 10%, 25%, etc. during the shipping process.

So basically, this is what I did: (this is an ASP.NET MVC3 project)

 @model MyModel @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "target-form", enctype = "multipart/form-data" })) { //some Html.TextBoxFor() and other @Html.DropDownListFor @Html.TextBoxFor(m => m.File, new { type = "file"}) <input type="submit" value="Create" class="submitButton" /> <div id="progressBar"></div> } 

And the base controller

 [HttpPost] public ActionResult Create(MyModel model) { if (ModelState.IsValid) { DALLayer dal = new DALLayer() dal.AddEntity(model); return RedirectToAction("Index", "Home"); } return null; } 

Is it possible to convert my last <div> to a progressBar displaying the status of the loading progressBar ?


Here are my requirements:

  • There is no plugin (this is an individual project, I want to understand how to do it myself).
  • Cross compatible, IE8 + (if possible)
  • jQuery is fine but no flash.


Many thanks!

UPDATE 1 Here is JSFIDDLE where I am trying to adapt this link , but to no avail ... If you think you can help, please!



UPDATE 2 Well, I used acarlon's answer to submit my form using XMLHttpRequest , and the data was sent correctly to the controller. However, the ProgressBar still does not appear!
I will simply replace the data passed to the controller:

 formData = new FormData(document.getElementById("target-form") ); xhr.open("POST", "@Url.Action("MyMethod", "MyController")", true ); 

and try a few different headers, for example:

 xhr.setRequestHeader("X-File-Name", $('#Files_0__File')[0].files[0].name); xhr.setRequestHeader("X-File-Size", $('#Files_0__File')[0].files[0].size); xhr.setRequestHeader("X-File-Type", $('#Files_0__File')[0].files[0].type); //Also tried with "Content-Length" but it doesn't care about it. 

(He was hard-coded here to be sure that it has good values. I will do this in a loop when it will be easier with him.)

And when I submit my form, XMLHttpRequest send has the following fields:

readyState: 4
status: 0 <= should be 200, right?

And in the error handler , I have the following values:

uploaded: 0 | total: 883526
type: "error"

So, the data is being transferred to my controller, but I can’t display this damn progress indicator ...

+7
javascript jquery progress-bar asp.net-mvc-3 progress
source share
3 answers

You can use XMLHttpRequest to get updates when downloading files. To achieve the same quality, there are various jquery wrappers. I will describe the solution using XMLHttpRequest . First intercept the submit form.

 $("#target-form").submit(function () { 

Then create an XHR request:

  xhr = new XMLHttpRequest(); 

Then register to receive notifications of progress events:

 xhr.upload.addEventListener( "progress", function ( evt ) { if( evt.lengthComputable ) { var progressPercent = ( evt.loaded / evt.total ) * 100; showProgress( value );//your function. } }, false ); //Some other events you will probably want to subscribe to xhr.addEventListener( "load", function () { fileUploadComplete( this.responseText ); }, false ); xhr.addEventListener( "error", function ( first, second, third ) { fileUploadComplete( "Error: Image format not supported." ); }, false ); xhr.addEventListener( "abort", function () { fileUploadComplete( "Error: Upload was cancelled. Please try again." ); }, false ); 

Open XHR, passing any arguments ( id shown as an example)

 xhr.open( "post", '@Html.Raw( @Url.Action( "UploadImage", new { someId = id } ) )', true ); // Set appropriate headers xhr.setRequestHeader( "Content-Type", "multipart/form-data" ); xhr.setRequestHeader( "X-File-Name", name ); // Send the file xhr.send( file ); 

Then in the controller:

 public ActionResult UploadImage( int someId, HttpPostedFileBase userFile ) { ... } 

You will receive updates in the update handler.

Extension for long-term server task

If the server has some kind of long-running task (for example, writing data to the database), you need to perform operations (so that you can give updates at the end of each fragment) on the server and implement code to handle the long-term service, which you can request from javascript. See here . The main idea is to run the task on the server side and periodically check the progress of work with Javascript. You can have two separate progress bars, one for loading and one for working on the server side. This gives more information to the user - they will know that the file download is completed, and now there is some kind of operation on the server side.

+4
source share

Add an ajax timer control that checks the progress with the server and sets the time interval (say every 2 seconds).

Performing a server task in a new thread. This will cause your post to return immediately, completing its long task in the background. Start the ajax timer.

Since working with long tasks allows you to update the session variable containing the completed job%.

When the timer sends back to the server, select% work done from the session variable.

You can create a progress bar by having an inner div and an outer div. Set the width of the inner div for the job done%: $ ('# progressBarWorkDone'). Css ('width', WorkDone + '%');

 <div id="progressBar" style="width:400px;"> <div id="progressBarWorkDone" style="width:0px;height:10px;background-color:red;"><div/> <div/> 

Please note: if you do not know how to use timer control, you can also make AJAX calls from javascript using setInterval (function () {AJAX CALLBACK GOES HERE}, 1000);

However, saying all that the easiest way is to simply add an animated gif to your progress bar div. Hide the div and then display the div when the submit button is pressed.

 <input type="submit" onclick="$('#progressBar').show();" value="Create" class="submitButton" /> <div id="progressBar" style="display:none;"><img src="myProgressBar.gif" /></div> 
+2
source share

I used the SWF loader with the backl file of the perl file (at a time when PHP did not support loading programs), but it looks like it is not in active development.

I have not used Plupload , but it looks very suitable for you. It looks like you can use asp backend .

Good luck and keep it dry;)

-2
source share

All Articles