Client Side Progress Bar in ASP.NET MVC using jQuery UI, WebAPI and JsRender

Editorial note: This article has been modified to incorporate (to an extent) the comments by an avid reader Parag. Thanks Parag!
In a recent discussion, I was asked about progress bars to visually depict ongoing activity on the web page. The scenario was that a page makes an Ajax call to an external service, receives JSON data and then displays this data in a tabular fashion. However the requirement here is that the end-user must be notified via an indicator when records gets loaded.

Note: To show a deterministic progress bar with ‘nearly’ accurate progress one must know the minimum, maximum and the current value of the work done. This makes progress bars on the web slightly tricky. The server while doing a long running task must periodically update the client or the client must continuously poll server to get the status. In this examples we ‘simulate’ such a scenario where server first tells the client the maximum number of rows to be returned and then the client pulls a certain amount of data and updates the progress bar accordingly.
jQuery UI provides a nice progress bar plugin that simply take the current value of progress assuming minimum is 0 and maximum is 100%. In Visual Studio you can install jQueryUI from Nuget using the command

In this sample, we are retrieving a table of data. Traditionally this translates to a UI Markup with a <table> and several <tr> and <td>.

However we will use templates to simply this activity. In this article, I have used a new Templating engine called JsRender. This is a JavaScript library which allows developer to define a boilerplate structure for UI requirement and then this structure can be reused to generate dynamic HTML. You can obtain JsRender.js from https://github.com/BorisMoore/jsrender . The Free DNC Magazine has a nice article on how to use JsRender.

Implementation

Let’s jump into the implementation now.

Step 1: Open Visual Studio 2012 and create a blank MVC project, name it as ‘MVC_JQuery_UI’. In this project, create a ‘Scripts’ folder and add the following jQuery files:
Jsrender.js : The JavaScript Library for JsRender.

Step 2: To define a Model layer, we will use the SQL Server Northwind database and its Order table. (Note you can download Northwind database from Nuget too using the command install-package Northwind.db).

Step 3: In the model folder, using the ADO.NET EF wizard, add the EF design as shown below:

Step 4: Right-click on the controller folder and add the WEB API Controller as shown below (Note: This is new in ASP.NET MVC 4)

Step 5: In the same controller, add a new Empty controller of the name ‘OrderListController’. You will get a class with an empty Index method. Here we are using an Empty controller because all the business logic will be implemented using jQuery.

Step 6: Add a new Empty Scaffolded Index View in the project by right-clicking on the Index method created in the Step 5. You will get the OrderList sub folder under View folder.

Step 7: Open Index.cshtml and add the following JavaScript and css references:

In the above code we are doing the following on the jQuery document ready event:

1. Initializing the counters.
2. Assigning the click handler to the ‘Get Data’ button.
3. In the click handler, we first do an AJAX call to get the total number of orders.
4. Based on the value returned, we calculate how many records we can fetch per query to server. (Here we have used a simple mechanism by diving the total by 100 for easy association with the Progress Bar value. However if you have a much larger dataset then the 100% calculation might be a little more involved).
5. We then call the getDataAtOffSet method. This uses the offset and fetches size counters to retrieve data from the server. The API Controller method to retrieve data is as follows

6. To accommodate the input parameters to the GET method we define a route in the WebApiConfig.cs as follows

config.Routes.MapHttpRoute(
name: "OrdersWithOffset",
routeTemplate: "api/{controller}/{offset}/{fetchRecords}",
defaults: new { offset = RouteParameter.Optional,
fetchRecords = RouteParameter.Optional }
);
7. As we can see the getDataAtOffset method pulls only a part of the data. It thereafter uses JsRender to render the n records returned.
8. Once the rendering is complete, it updates the progress bar
9. Finally if checks if the offset has reached the count of the records. If not, it calls itself with the updated offset. This continues till all records have been retrieved.
10. The updateProgress method take care of updating the current record label too.

This wraps up the changes required.

Step 11: Now if we run the application and in the address bar type the below URL (which may differ on your machine): hxxp://localhost:51914/ordersList The result will be as shown below:

Click on the ‘GetData’ button and now each row gets added with a progress indicator as shown below:

Disclaimer: This is not even close to a well-designed table, but with the use of simple CSS, you can beautify it further. You can also apply various CSS effects to the ProgressBar as per your requirements.

Conclusion

ProgressBar is a handy widget from the jQuery UI. It helps provide a more ‘live’ User Experience for the end-user. Download the source code from Github (click on the ZIP to download as .zip)

Will you give this article a +1 ? Thanks in advance

About The Author

Mahesh Sabnis is a Microsoft MVP having over 18 years of experience in IT education and development. He is a Microsoft Certified Trainer (MCT) since 2005 and has conducted various Corporate Training programs for .NET Technologies (all versions). He also blogs regularly at DotNetCurry.com. Follow him on twitter @maheshdotnet

8 comments:

Sorry to say Mahesh but the HTML your example is going to render is symantically wrong and for each tr, you are going to render a div so I am not sure how its going to show up on different browsers. Moreover, the progress bar is not really a progress bar here since its going to start showing a progress only after your ajax call has completed successfully. The progress bar is going from 0% to 100% in exactly 20000 milliseconds and most importantly if you have more than 100 orders to display it wont render anything beyond 100 rows. Last but not the least the word Responsive UI is misleading as i thought the term Responsive Web designing had to do more with the way things render on different devices and browsers. The one thing you have got right is use of WebAPI (which in turn points to a different article). These are just my observation. Though the article had information about How to use Stuff, it does not seem have been used Properly.