An easy approach to adding user notifications to ASP web applications

We all have to do it – inform the user of some status such as whether their edit saved properly and/or if a form submission was successful.  The work here is based on something I picked up on the this blog: http://blog.idleworx.com/2010/11/friendly-css-error-messages-for-java.html. I changed things slightly to take advantage of the .NET environment.

Have you ever wanted user notifications that faded out over a certain time interval? Perhaps you want the user to be able to click a message to make it disappear. Increasingly, we see these sorts of UI elements and if they have not done so already, your clients will ask for these UI elements for their sites as well. Fortunately, adding this feature is quite simple.

The keys to this project are jQuery and CSS. jQuery allows us to easily add fade out to UI elements. Most often, a DIV will fade away over some period of time. The core jQuery library has a fadeOut method. With CSS, we can easily styles.

To demonstrate these concepts, I have created a simple ASP MVC 2.0 project that has one page. The following video demonstrates how things work:

User Notification Example One

Optionally, you can close a message with a mouse click. If you set the Fade Out to 0, the message does not disappear. The setting is in milliseconds (setting the fade out to 1000 = 1 second).

User Notification Two

So…how does this all work? Here is the source code link . There’s not much going on here. The problem I was working to resolve was one of organization. The other thing I wanted to avoid was having to worry about adding specific css and javascript references to support this feature.

To help with organization, I created an alerts folder that holds my css and image file resources. As an aside, I could have approached this with embedded resources. It is certainly a viable way to go. It would mean that all you would have to worry about is distributing a dll. Perhaps I’ll tackle that in a subsequent post. 

image

There are two primary code artifacts: AlertMetaData and Alerts. AlertMetaData is a flattened out structure that for purposes of this example, serves as the view model.

AlertMetaData.cs
  1. public class AlertMetaData
  2.  {
  3.      public string ErrorMessage { get; set; }
  4.      public string WarningMessage { get; set; }
  5.      public string InfoMessage { get; set; }
  6.      public string OKMessage { get; set; }
  7.  
  8.      public int ErrorFadeOut { get; set; }
  9.      public int WarningFadeOut { get; set; }
  10.      public int InfoFadeOut { get; set; }
  11.      public int OKFadeOut { get; set; }
  12.  
  13.      public bool ErrorClickToClose { get; set; }
  14.      public bool WarningClickToClose { get; set; }
  15.      public bool InfoClickToClose { get; set; }
  16.      public bool OKClickToClose { get; set; }
  17.  
  18.  }

All of the work occurs in the Alerts.cs file which contains several classes: Alert and Alerts.

Alert Class
  1. public class Alert
  2. {
  3.     private  AlertType _alerttype = AlertType.msgOK;
  4.     private bool _enableclicktoclose = false;
  5.     private int _fadeout = 4000;
  6.  
  7.     public int FadeOut
  8.     {
  9.         get
  10.         {
  11.             return _fadeout;
  12.         }
  13.         set
  14.         {
  15.             _fadeout = value;
  16.         }
  17.     }
  18.  
  19.     public bool EnabledClickToClose
  20.     {
  21.         get
  22.         {
  23.             return _enableclicktoclose;
  24.         }
  25.         set
  26.         {
  27.             _enableclicktoclose = value;
  28.         }
  29.     }
  30.  
  31.     public AlertType AlertType
  32.     {
  33.         get
  34.         {
  35.             return _alerttype;
  36.         }
  37.  
  38.         set
  39.         {
  40.             _alerttype = value;
  41.         }
  42.  
  43.     }
  44.  
  45.     public string Message
  46.     {
  47.         get;
  48.         set;
  49.     }
  50. }

The Alert Class has 4 properties, 2 of which have default values. The AlertType is a simple enum:

AlertType Enum
  1. public enum AlertType
  2. {
  3.     msgInfo,
  4.     msgWarn,
  5.     msgError,
  6.     msgOK
  7. }

The Alerts Collection

Code Snippet
  1.    public class Alerts
  2.     {
  3.  
  4.         private string _css = @”../../alerts/css/alerts.css”;
  5.  
  6.         public Alerts()
  7.         { }
  8.         
  9.         public Alerts(AlertMetaData data)
  10.         {
  11.             GetAlerts(data);
  12.         }
  13.         
  14.         private IList<Alert> _alertcollection = new List<Alert>();
  15.  
  16.         public Alerts(IList<Alert> alerts)
  17.         {
  18.             _alertcollection = alerts;
  19.         }
  20.  
  21.         public IList<Alert> AlertCollection
  22.         {
  23.             get {
  24.                 return _alertcollection;
  25.             }
  26.         }
  27.  
  28.         public string RenderHTML()
  29.         {
  30.             
  31.             if (_alertcollection.Count == 0)
  32.                 return “”;
  33.  
  34.             var html = new StringBuilder();
  35.  
  36.             html.AppendLine(string.Format(@”<link href=””{0}”” rel=””stylesheet”” type=””text/css””/>”,_css));
  37.             
  38.             html.AppendLine(@”<div class=””messages””>”);
  39.             
  40.             html.AppendLine(@”<script type=””text/javascript””>”);
  41.             html.AppendLine(@”$(document).ready(function () {“);
  42.             foreach (var alert in _alertcollection)
  43.             {
  44.                 if (alert.FadeOut > 0)
  45.                     html.AppendLine(string.Format(@”$(“”.{0}””).fadeOut({1});”, alert.AlertType, alert.FadeOut));
  46.  
  47.                 if (alert.EnabledClickToClose)
  48.                 {
  49.                     html.AppendLine(string.Format(@”$(“”.{0}””).click(function(){1}$(this).hide();{2});”, alert.AlertType, “{“, “}”));
  50.                     html.AppendLine(string.Format(@”$(“”.{0}””).css(“”cursor””,””hand””);”, alert.AlertType));
  51.  
  52.                     //Could also specify a different background graphic.
  53.  
  54.                 }
  55.             }
  56.             html.AppendLine(@”});”);
  57.             html.AppendLine(@”</script>”);
  58.  
  59.             foreach (var alert in _alertcollection)
  60.             {
  61.                 html.AppendLine(string.Format(@”<div class=””{0}”””,alert.AlertType));
  62.  
  63.                 if (alert.EnabledClickToClose)
  64.                     html.Append(@” title = “”Click to close”””);
  65.                     
  66.                 
  67.                 html.Append(@”>”);
  68.  
  69.                 html.AppendLine(alert.Message);
  70.                 html.AppendLine(@”</div>”);
  71.             }
  72.             html.AppendLine(@”</div>”);
  73.  
  74.             return html.ToString();
  75.         }
  76.  
  77.         public string css { get { return _css; } set { _css = value; } }
  78.         
  79.         private void GetAlerts(AlertMetaData alertMetaData)
  80.         {
  81.  
  82.             _alertcollection.Add(
  83.                 new Alert()
  84.                 {
  85.                     AlertType = AlertType.msgError,
  86.                     Message = alertMetaData.ErrorMessage,
  87.                     EnabledClickToClose = alertMetaData.ErrorClickToClose,
  88.                     FadeOut = alertMetaData.ErrorFadeOut
  89.                 }
  90.             );
  91.  
  92.             _alertcollection.Add(
  93.                 new Alert()
  94.                 {
  95.                     AlertType = AlertType.msgInfo,
  96.                     Message = alertMetaData.InfoMessage,
  97.                     EnabledClickToClose = alertMetaData.InfoClickToClose,
  98.                     FadeOut = alertMetaData.InfoFadeOut
  99.                 }
  100.             );
  101.  
  102.             _alertcollection.Add(
  103.                 new Alert()
  104.                 {
  105.                     AlertType = AlertType.msgOK,
  106.                     Message = alertMetaData.OKMessage,
  107.                     EnabledClickToClose = alertMetaData.OKClickToClose,
  108.                     FadeOut = alertMetaData.OKFadeOut
  109.                 }
  110.             );
  111.  
  112.             _alertcollection.Add(
  113.     new Alert()
  114.     {
  115.         AlertType = AlertType.msgWarn,
  116.         Message = alertMetaData.WarningMessage,
  117.         EnabledClickToClose = alertMetaData.WarningClickToClose,
  118.         FadeOut = alertMetaData.WarningFadeOut
  119.     }
  120. );
  121.             
  122.         }
  123.     }

The process is simple: the RenderHTML() method cycles through through the alert colllection and renders the appropriate html and css references – and also includes the necessary jQuery calls to support the fade out effect. The result makes for a cleaner view:

RenderHTML() Call
  1. <%=new UserNotifications.alerts.Alerts(Model).RenderHTML() %>

In this case, the view model conforms to the AlertMetaData class. I wrote the sample that way to make it easy to hydrate the object via the html form:

Form to hydrate alertmetadata
  1. <%using (Html.BeginForm(“Index”))
  2.   { %>
  3. <table>
  4.     <tr>
  5.        <th>Type</th>
  6.        <th>Message</th>
  7.        <th>Fade Out Time</th>
  8.        <th>Click to Close</th>
  9.     </tr>
  10.     <tr>
  11.        <td>Error</td>
  12.        <td><%=Html.TextBox(“ErrorMessage”, Model.ErrorMessage)%></td>
  13.        <td><%=Html.TextBox(“ErrorFadeOut”, Model.ErrorFadeOut, new { style = “width: 50px;” })%></td>
  14.        <td><%=Html.CheckBox(“ErrorClickToClose”, Model.ErrorClickToClose)%></td>
  15.     </tr>
  16.  
  17.     <tr>
  18.       <td>Info</td>
  19.        <td><%=Html.TextBox(“InfoMessage”, Model.InfoMessage)%></td>
  20.        <td><%=Html.TextBox(“InfoFadeOut”, Model.InfoFadeOut, new { style = “width: 50px;” })%></td>
  21.        <td><%=Html.CheckBox(“InfoClickToClose”, Model.InfoClickToClose)%></td>
  22.     </tr>
  23.  
  24.     <tr>
  25.        <td>OK</td>
  26.        <td><%=Html.TextBox(“OKMessage”, Model.OKMessage)%></td>
  27.        <td><%=Html.TextBox(“OKFadeOut”, Model.OKFadeOut, new { style = “width: 50px;” })%></td>
  28.        <td><%=Html.CheckBox(“OKClickToClose”, Model.OKClickToClose)%></td>
  29.     </tr>
  30.  
  31.     <tr>
  32.       <td>Warning</td>
  33.        <td><%=Html.TextBox(“WarningMessage”, Model.WarningMessage)%></td>
  34.        <td><%=Html.TextBox(“WarningFadeOut”, Model.WarningFadeOut, new { style = “width: 50px;” })%></td>
  35.        <td><%=Html.CheckBox(“WarningClickToClose”, Model.WarningClickToClose)%></td>
  36.     </tr>
  37.  
  38. </table>
  39.  
  40. <input type=”submit” value= “Get User Notifications” />
  41.  
  42. <%} %>

Alternatively, if you can hydrate AlertMetaData in a controller method and then pass to the view – either in the ViewData hash or as an attribute to the view model.

Other points: The Alerts class exposes a css property. If you want to specify a different CSS file – go for it! The RenderHTML() method will query the property when it renders the css reference. This approach will seamlessly integrate with ASP MVC’s error notification scheme.

The big goal – make these sort of mundane tasks easy to implement and to be as least intrusive as possible. Handling user notifications is an essential part of any web application and I hope you find this approach useful. Thanks to the folks at idleworks.com for posting inspiration for this project. Note folks – the inspiration came from a Java Blog!! Smile with tongue out Enjoy!!

About johnvpetersen

I've been developing software for 20 years, starting with dBase, Clipper and FoxBase + thereafter, migrating to FoxPro and Visual FoxPro and Visual Basic. Other areas of concentration include Oracle and SQL Server - versions 6-2008. From 1995 to 2001, I was a Microsoft Visual FoxPro MVP. Today, my emphasis is on ASP MVC .NET applications. I am a current Microsoft ASP .NET MVP. Publishing In 1999, I wrote the definitive whitepaper on ADO for VFP Developers. In 2002, I wrote the Absolute Beginner’s Guide to Databases for Que Publishing. I was a co-author of Visual FoxPro Enterprise Development from Prima Publishing with Rod Paddock, Ron Talmadge and Eric Ranft. I was also a co-author of Visual Basic Web Development from Prima Publishing with Rod Paddock and Richard Campbell. Education - B.S Business Administration – Mansfield University - M.B.A. – Information Systems – Saint Joseph’s University - J.D. – Rutgers University School of Law (Camden) In 2004, I graduated from the Rutgers University School of Law with a Juris Doctor Degree. I passed the Pennsylvania and New Jersey Bar exams and was in private practice for several years – concentrating transactional and general business law (contracts, copyrights, trademarks, independent contractor agreements, NDA’s, intellectual property and mergers and acquisitions.).
This entry was posted in ASP MVC, CSS, jQuery. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • Coach Outlet Online

    Nod and smile, question and encourage. Coach Outlet Online.

  • http://www.mtgdeckbuilder.net David Corona

    Thanks for the post! This is a great method for user notifications. It is something I always found tedious and repetitive, and this puts it into a nice clean interface. I can also add my own custom messages and have as many as I want and just call upon them as needed. I think I will see about implementing something just like this into my website, which sorely needs more (and better) user notification. Thanks for the tip and code!