top button
Flag Notify
    Connect to us
      Site Registration

Site Registration

Displaying File Upload Progress Using JQuery UI Progressbar Widget

+4 votes
578 views

While uploading large files you may need to display the progress of the file upload operation to the end user. This can be done using HTML5 and jQuery UI's Progressbar widget. While HTML5 also has <progress> element that can be used to render a progress bar, jQuery UI's Progressbar widget offers more configuration and theming options. In this post you will use XMLHttpRequest (Level 2) object to upload files to the server. The XMLHttpRequest object now supports file upload related events such as progress that can be used to track file upload progress.

The following figure shows a sample Web Form that shows how the progress bar looks like:

image

The Web Form has a FileUpload server control that allows you to select one or more files. Clicking on the Upload button uploads the files on the server. To upload the files on the server you use XMLHttpRequest object instead of traditional postback. The files are uploaded in the background and the progress of the upload operation is displayed in the Progressbar widget. The progress bar also has a label that indicates the progress in percentages.

The Web Form consists of the following markup:

<form id="form1" runat="server">
        <asp:Label ID="Label1" runat="server" Text="Select File(s) to Upload :"></asp:Label>
        <br />
        <br />
        <asp:FileUpload ID="FileUpload1" runat="server" AllowMultiple="true" />
        <br />
        <br />
        <asp:Button ID="Button1" runat="server" Text="Upload" />
        <br />
        <br />
        <div id="progressbar" class="progressbar">
            <div id="progresslabel" class="progressbarlabel"></div>
        </div>
    </form>

As you can see the form primarily consists of a FileUpload server control, a Button and couple of <div> elements at the bottom. The outer <div> represents the Progressbar whereas the inner <div> represents the label of the progress bar.

Then add the following CSS classes for the outer <div> and the inner <div> respectively.

 .progressbar {
  width:300px;
  height:21px;
}
.progressbarlabel {
  width:300px;
  height:21px;
  position:absolute;
  text-align:center;
  font-size:small;
}

Now add the <script> sections to the head section as shown below:

 <script src="Scripts/jquery-2.0.0.js"></script>
<script src="Scripts/jquery-ui.js"></script>

As you can see the first <script> tag points to the jQuery library and the second <script> tag points to the jQuery UI library. Also add a reference to the CSS file needed by jQuery UI:

 <link href="jquery-ui.css" rel="stylesheet" />

Then add a new <script> block in the head section and write the following jQuery code in it:

 $(document).ready(function () {
  $("#Button1").click(function (evt) {
    var xhr = new XMLHttpRequest();
    var data = new FormData();
    var files = $("#FileUpload1").get(0).files;
    for (var i = 0; i < files.length; i++) {
      data.append(files[i].name, files[i]);
    }
    xhr.upload.addEventListener("progress", function (evt) {
    if (evt.lengthComputable) {
      var progress = Math.round(evt.loaded * 100 / evt.total);
      $("#progressbar").progressbar("value", progress);
    }
    }, false);
    xhr.open("POST", "UploadHandler.ashx");
    xhr.send(data);

    $("#progressbar").progressbar({
      max: 100,
      change: function (evt, ui) {
        $("#progresslabel").text($("#progressbar").progressbar("value") + "%");
      },
      complete: function (evt, ui) {
        $("#progresslabel").text("File upload successful!");
      }
    });
    evt.preventDefault();
  });
});

The above code consists of click event handler of Button1. Inside, the code creates an instance of XMLHttpRequest object (xhr) and a FormData object (data). It then obtains a list of files selected in the FileUpload control using files property of the DOM element. A for loop iterates through the files collection and with each iteration the file is added to the FormData object using its append() method. The first parameter of append() is the name of the file and the second parameter is the file itself.

Then progress event handler is wired to the upload object of the XMLHttpRequest object. This event is raised periodically during the file upload operation. The progress event handler uses event object properties such as lengthComputable, loaded and total to calculate the progress in percentages. The jQuery UI Progressbar is updated with this progress value. This is done by setting the value option of the progressbar widget to the progress value just calculated.

Then the open() method of XMLHttpRequest is called and the URL to an ASP.NET generic handler (UploadHandler.ashx) is specified. Then send() method is called to actually make the request and send the files to the server. The FormData object is passed as a parameter to the send() method.

Finally, the Progressbar widget is initialized on the progressbar <div> element. The configuration options namely max, change and complete are passed to the progressbar widget. The max option indicates the maximum value that can be displayed in the progress bar. the change options wires an event handler to the change event of the progressbar widget. The change event is raised whenever the value of the progressbar widget changes. The change event handler sets the text of the progressbarlabel <div> element to the value of the progressbar. The complete options wires an event handler for the complete event. The complete event is raised when the value reaches the max value of the progressbar widget. The complete event handler sets the text of the progressbarlabel <div> to "File upload successfully!".

Although not used in this example, you can also handle the load event of the XMLHttpRequest object to notify the user of the completion of the request.

Now add a generic handler (UploadHandler.ashx) to the project and add the following code to it:

public void ProcessRequest(HttpContext context)
{
  HttpFileCollection files = context.Request.Files;
  foreach (string key in files)
  {
    HttpPostedFile file = files[key];
    string fileName = file.FileName;
    fileName = context.Server.MapPath("~/uploads/" + fileName);
    file.SaveAs(fileName);
  }
  context.Response.ContentType = "text/plain";
  context.Response.Write("File(s) uploaded successfully!");
}

The generic handler receives the uploaded files in the Request.Files collection. Each file in the collection is an instance of HttpPostedFile class. A foreach loop iterates through the files collection and saves each PostedFile using the SaveAs() method. The files are saved in Uploads folder under the root folder of the web application. Once all the files are uploaded the generic handler sends a success message to the client.

That's it! Run the Web Form, select a few large files and click on the Upload button to see the progressbar widget in action.

posted Nov 10, 2016 by Shivaranjini

  Promote This Article
Facebook Share Button Twitter Share Button LinkedIn Share Button


Related Articles

Unlike traditional full page postback, where a user can easily understand that the page is being processed, Ajax based communication doesn't give any clue to the user about the processing being done in the background. This is especially important when the Ajax calls involve lengthy server side processing. It would be nice if you show some progress indicator or wait message to the end user while making Ajax calls. To that end this article shows one simple way of displaying such a progress indicator.

Have a look at the following figure:

image

The figure shows an ASP.NET Web Form that contains a Button control. Upon clicking the button an Ajax request is made to an ASP.NET Generic Handler (.ashx). At the same time an animated GIF is displayed as a progress indicator. The generic handler performs some processing and returns a success message to the Web Form. Once the Ajax request completes the animated GIF is hidden from the end user.

The markup of the Web Form looks like this:

<form id="form1" runat="server">
  <asp:Button ID="Button1" runat="server" Text="Make Ajax Call" />
  <div id="progress">
    <asp:Image ID="Image1" runat="server" ImageUrl="~/Progress.gif" />
  </div>
</form>

As you can see the Image control points to Progress.gif and is enclosed inside a <div> element whose ID is progress.

The generic handler (AjaxHandler.ashx) simply mimics a length operation by calling Sleep() method of Thread class. The following code shows how the AjaxHandler.ashx looks like:

public class AjaxHandler : IHttpHandler
{
  public void ProcessRequest(HttpContext context)
  {
    System.Threading.Thread.Sleep(10000);
    context.Response.ContentType = "text/plain";
    context.Response.Write("Data processed successfully!");
  }
  public bool IsReusable
  {
    get
    {
      return false;
    }
  }
}

The ProcessRequest() method makes the current thread sleep for 10 seconds. It then writes a success message onto the response stream.

The jQuery code that makes an Ajax call on the click of the button is shown below:

$(document).ready(function () {
  $("#progress").hide();

  $("#Button1").click(function (evt) {
    var options = {};
    options.url = "ajaxhandler.ashx";
    options.type = "GET";
    options.beforeSend = function () {
      $("#progress").show();
    };
    options.success = function (result) {
      alert(result);
    };
    options.error = function (xhr,status,err) {
      alert(err);
    };
    options.complete = function () {
      $("#progress").hide();
    };
    $.ajax(options);
    evt.preventDefault();
  });
});

The ready() handler hides the progress <div> element as soon as the page loads using hide() method. This way initially the animated GIF is kept hidden. The code then wires an event handler for the click event of Button1. The click event handler creates an options object. The url property of the options object points to the generic handler - AjaxHandler.ashx. The type property is set to GET indicating that a GET request is to be made. The important part is the beforeSend and complete handler functions. The beforeSend callback is called just before making an Ajax request. This is where you need to show the progress indicator (animated GIF in this case) to the end user. Inside the beforeSend function the progress <div> is shown to the user using show() method. The complete callback is called when the Ajax request completes (either successfully or with error). Inside the complete callback you hide the progress <div> using hide() method. The success callback simply shows the message returned from the server in an alert dialog. Similarly, the error handler shows the error message in an alert dialog. Finally, an Ajax call is made using jQuery $.ajax() method.

That's it! Run the web form and test whether the progress indicator is displayed as expected.

READ MORE
...