Problem
I would like to represent the overall progress of a process that my users are walking through. I would like to use a progress bar but don't want to have to re-invent the wheel or deal with cross-browser display and rendering problems. How can I achieve this?
Solution
Save some space in your design for the jQuery UI progress bar. It's one of the simplest controls in the library to understand and implement, and your users will appreciate the feedback!
Rendering a Simple Progress Bar
Like many of the other jQuery UI components, there's not much you need to do to get the default functionality out of
progressbar. The semantic requirements are simply that you need a container control that will become the progress bar in the DOM once you've made a call to
progressbar. Here's the required HTML:
<div id="progress-sample"></div>
And the corresponding javascript:
$("#progress-sample").progressbar({ value: 82 });
And the result:

This works fine for one or many containers on a page as the progress bar is applied to anything that meets the selector criteria. In fact, if you had a set of
DIVs that all had the CSS class of
my-progress-bars, you could make the following call to convert them all to progress bars:
$(".my-progress-bars").progressbar();
But, if we want to apply different values to them we're going to need a different approach.
Using Multiple Progress Bars - Using Our MVC Model Data
While we can use jQuery's CSS class selectors directly against the
DIV elements themselves, we could instead use a wrapper
DIV where we contain not only the element we would like to become a progress bar, but also the data we need to set the value.

Assume we have a simple class that parlays the state of completion for various properties in our client's construction company:
public class PropertyProgress
{
public string Title { get; set; }
public int PercentComplete { get; set; }
}
Our controller action simply returns the in-progress properties as data from our repository:
public ActionResult MultipleBars()
{
PropertyProgressRepository repository = new PropertyProgressRepository();
return View(repository.GetPropertyStatuses());
}
In our view we'll loop through the set of data and build a container with the data and the placeholder. It is important to use a common class for the container as we'll use this to identify the elements in our client-side code. The hidden input is where we put the model's value representing percent complete.
<% foreach (var item in Model) { %>
<div class="property-container">
<input class="progress-value" type="hidden" value="<%: item.PercentComplete %>" />
<div class="property-title"><%: item.Title %></div>
<div class="property-progress"></div>
</div>
<% } %>
Finally, the javascript code that iterates through the containers, identifies the current value of the progress bar and sets the respective progress bar for each property with that value.
$(function () {
// loop through each 'container'
$(".property-container").each(function () {
// get the value that was rendered from the model
var progress = parseInt($(this).children(".progress-value").val());
// create the progress bar with the value
$(this).children(".property-progress").progressbar({ value: progress });
});
});
Here we're using the
.children() jQuery function and filtering the set of elements by a class selector. This lets us extract the value that was rendered by the ASP.NET MVC Framework from the data in the model; it also lets us identify the element to be used as the progress bar.
Try Me!
Using Progressbar in Multi-step Processes
Another common use of the progress bar is to show the user how far they've come in survey, wizard, signup process or configuration workflow. Perhaps at each step there is a pause while some long-running process is executed.
I'm going to go through some of the pieces we need to make this work. If you're following along, here's what we're going to discuss:
- A main view with the placeholders for progress messages and the progress bar itself
- A reusable partial view that displays feedback to the user as they progress
- A class used to store the feedback and current progress
- Controller actions that move the process along for the user and return the updated partial view
- Some javascript to leverage the jQuery UI elements and handle the Ajax operations
A Do-nothing Wizard
What we'll walk through here is the creation of a wizard with four steps, each taking a few seconds to complete. The user advances the progress by simply clicking a button once the view's been updated from the last step. We display an animated indicator while the Ajax operations are executing.

We'll create a view that sets up the framework for our wizard and gives the user feedback while we're waiting for the Ajax calls to the next steps to complete.
<div style="margin-left:50px;">
<div id="ajax-indicator">
<img src="<%= Url.Content("~/areas/progressbar/Content/ajax-loader.gif") %>" />
</div>
<div id="progress-percent" style="width: 400px; height:0.8em; margin:15px;"></div>
<div id="progress-message">
<% Html.RenderAction("StartSteps"); %>
</div>
</div>
The
DIV with the ID of
progress-message is what we'll use to drive the wizard. You can see here that I'm calling
Html.RenderAction, which is injecting a partial view into the document.
progress-message will be updated each step when the Ajax content is loaded.
Before we look at the controller action that generates that partial view, let's fist look at the class and partial view used to store and display the current state of the process. The class will store a text message and the percent complete as well as the name of the next step to be executed. We'll use that name in our client-side script to make the subsequent call to the controller.
public class ProgressInformation
{
public int PercentComplete { get; set; }
public string Message { get; set; }
public string NextAction { get; set; }
}
We'll call the partial view "StepUpdate" and give it a simple block of HTML with a little bit of model data injected into it:
<p id="progress-message">
<p><%: Model.Message %></p>
<input type="hidden" id="next-action" value="<%: Model.NextAction %>" />
<button class="advance-progress">Next</button>
</p>
We'll also add a touch of jQuery script to give the button the look-and-feel we like as well as to update the value of the progress bar on the main view:
$(function () {
$(".advance-progress").button();
$("#progress-percent").progressbar({ value: <%: Model.PercentComplete %> });
});
With these two bits in place (which is really all we need) we can use the partial view for all steps in the process. Here's what a controller action representing one of those steps might look like:
public PartialViewResult StepOne()
{
// do some interesting processing as part of the step...
ProgressInformation info = new ProgressInformation
{
Message = "Step one is complete. You can continue by clicking the button below.",
PercentComplete = 12,
NextAction = "StepTwo"
};
return PartialView("StepUpdate", info);
}
All steps follow the same recipe: do some work, store a message and the current overall progress, and declare the next step to take in the wizard. We then call
PartialView to build the result and pass the
ProgressInformation to the view engine.
The only other interesting thing left is the script in our main view. In this script, we're going to set up a click handler using
jQuery.live(), which creates an event handler that works for matched elements now and any matched elements as they are added to the DOM.
$(".advance-progress").live("click", function () {
$(this).button({ disabled: true });
$("#ajax-indicator").toggle();
var nextAction = $("#next-action").val();
$.ajax({
url: nextAction,
success: function (data) {
$("#progress-message").html(data);
$("#ajax-indicator").toggle();
}
});
});
As each partial view is loaded, along with it's new button element, the click handler above is re-bound to the button as it is attributed with the same class.
We do two things when the button is clicked: disable the button and display our loading indicator. We also extract the next action that was stored in our partial view and initiate our Ajax call. Our
success event handler allows us to update the view and hide the loading indicator.
Try Me!
Wrapping Up
The progress bar is a versitile and simple jQuery UI control that presents status to users in a way that has been around for as long as graphical user interfaces. While it is great on it's own, it can be easily mashed up with the ASP.NET MVC Framework to become a powerful tool in your belt.
About the Author
James Chambers is a Senior Software Developer in the prairies of Canada where, in spite of seasonal temperatures reaching -40 degrees, he believes there is no such thing as bad weather; only bad clothing choices. His development passions are fueled by new tech, new tools and mentoring others. Follow his coding adventures at
Mister James.