Display AJAX Progress in ASP.NET MVC
Yesterday I was finalizing one of the chapters of our book about AJAX development in ASP.NET MVC, and had to add exercises for the chapter. One of my exercises was about adding an AJAX progress to a sample project, and gave a hint to encourage the reader implement it. However, I think the simple solution is worth publishing here in a blog post.
It’s very common to display an animated GIF icon when an AJAX request is being executed in order to keep the user updated about the changes. ASP.NET AJAX offers an easy to use control that can be used in conjunction with UpdatePanel to display a text or image to users but AJAX with ASP.NET MVC has a different development process, so displaying such an image is also different here.
First of all, let state that all the discussion relies on one point, and that point is LoadingElementId property of AjaxOptions class that does the job for you. Now how?! When adding AJAX elements to your masters, views or user controls, you use some AJAX extension methods such as ActionLink, BegingForm, and RouteLink in which you pass a set of parameters to their different overloads. One of the common parameters is an AjaxOptions object that at least has a UpdateTargetId property. This class has also a LoadingElementId property that must be set to a string value which is the identifier of a HTML image element (or other element types) that keeps your animated icon or text.
The other step is to add this image element and use a style to hide it from public in the normal form. ASP.NET MVC displays this element when an AJAX progress is being executed. You can style the element with a simple CSS code that sets its display to none.
Having this background, here is a sample in which I create an ASP.NET MVC application that does nothing but displaying a single page. In this page I can click on a click to execute a process that lasts for a few seconds and shows the current time.
First I create my controller that doesn’t do anything special. It’s a simplified version of auto-generated HomeController by Visual Studio.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Threading;
namespace ProgressSample.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
}
}
Now I create a master that keeps my general layout and has references to Microsoft AJAX and ASP.NET AJAX JavaScript libraries.
<%@ Master Language="C#" AutoEventWireup="true" CodeBehind="Site.master.cs"
Inherits="ProgressSample.Views.Shared.Site" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>
<%= Html.Encode(ViewData["Title"]) %>
</title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<script src="<%= Url.Content("~/Scripts/MicrosoftAjax.debug.js") %>"
type="text/javascript"></script>
<script src="<%= Url.Content("~/Scripts/MicrosoftMvcAjax.debug.js") %>"
type="text/javascript"></script>
</head>
<body>
<div class="page">
<div id="header">
<div id="title">
<h1>
Display AJAX Progress in ASP.NET MVC</h1>
</div>
<div id="menucontainer">
<ul id="menu">
<li>
<%= Html.ActionLink("Home", "Index", "Home")%></li>
</ul>
</div>
</div>
<div id="main">
<asp:ContentPlaceHolder ID="MainContent" runat="server" />
<div id="footer">
Keyvan Nayyeri © Copyright 2008
</div>
</div>
</div>
</body>
</html>
The next step is, adding a view that contains my AJAX interaction elements. Here I use an ActionLink to display the current type in a span. There is also an image element that is concealed in the normal form, and my ActionLink applies its ID to display the AJAX progress.
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" AutoEventWireup="true"
CodeBehind="Index.aspx.cs" Inherits="ProgressSample.Views.Home.Index" %>
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">
<h2>
<%= Html.Encode(ViewData["Message"]) %></h2>
<span id="time"></span>
<br />
<img id="updating" src="/content/ajax-loader.gif" style="display: none;" alt="Updating ..." />
<br />
<%= Ajax.ActionLink("Get Time", "GetTime",
new AjaxOptions { UpdateTargetId = "time", LoadingElementId="updating" })%>
</asp:Content>
Going back and forth, I need to update my controller with a GetTime method that returns the string value of current time after a few minutes of suspension.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Ajax;
using System.Threading;
namespace ProgressSample.Controllers
{
[HandleError]
public class HomeController : Controller
{
public ActionResult Index()
{
ViewData["Title"] = "Home Page";
ViewData["Message"] = "Welcome to ASP.NET MVC!";
return View();
}
public string GetTime()
{
Thread.Sleep(5000);
return string.Format("Current time is {0}",
DateTime.Now.ToShortTimeString());
}
}
}
In the end, I can run my application to test it.
I uploaded the source code sample on my site, so you can download it as well.
[advertisement] Axosoft OnTime 2008 is four developer tools in one: bug tracking, project wiki, feature management, and help desk. It manages your development process so developers can focus on coding. Installed or Hosted – Free Single-user license -- Free 30-day team trial.
2 Comments : 10.20.08
Feedbacks
Pingback from ASP.NET MVC Archived Blog Posts, Page 1

#1
Dew Drop - October 21, 2008 | Alvin Ashcraft's Morning Dew
10.21.2008 @ 8:54 AM
Pingback from Dew Drop - October 21, 2008 | Alvin Ashcraft's Morning Dew