Using jQuery Plugins with ASP.NET

The controls found in the AjaxControlToolkit fit perfectly into the ASP.NET programming model (as to be expected).  You can configure the controls properties through the markup which in turn affects how the control's display and behavior on the client.  Many of the control's properties support databinding so using the controls within a databound control like a ListView or a GridView is no big deal.  Take for example the ProgressBar Toolkit control I blogged about (here and here).  One of the places that I use this control is in a GridView's TemplateField.  Instead of displaying the percentage as a text value, I use the ProgressBar to display the percentage in a more visual manner.  It looks something like this ...

Live Demo | Download

image

With the Toolkit, setting this up is really simple.  Just use a databinding expression to set the Value property of the ProgressBar control to the value of the PercentComplete property of the databound item.  Done.

   1: <mb:ProgressControl 
   2:     ID="ProgressControl17" runat="server" 
   3:     Value='<%# Eval("PercentComplete") %>' 
   4:     Animate="true" Mode="Manual" ShowStatusText="false" 
   5: />

 

And if I start using and building jQuery plugins I am thinking there will be cases where I am going to miss how simple this is.  So after learning about jQuery's metadata plugin, I thought it would be interesting to see explore it a bit more to see if it could be used to enable some of the common scenarios.  There are 2 things the metadata plugin has going for it that I think will help it fit into the ASP.NET programming model ...

  • If a jQuery plugin supports the metadata plugin in, you can specify the plugin options on a per element basis by using some JSON within the elements class attribute to specify the option properties you would like to use.  To me this really doesn't feel too different than pointing a Toolkit control (using TargetControlID) at an existing web control.
  • It can all be done via markup - no need to emit any extra javascript

 

Creating the Plugin

Before I show how this can be done using the ListView, I thought I would show what the jQuery plugin looks like (granted it doesn't have nearly as many features as the Toolkit version, but it still very useful for the data grid scenario).  Here is how the plugin works ...

  1. Coalesce the default options together with any options that are explicitly provided when the progressbar plugin is applied (Line #5)
  2. Inject the DIV elements that are used for styling the progress bar (Line #9)
  3. Check to see if the metedata plugin is available.  If it is override any of the element specific options (Line 12)
  4. Finally, use find to locate the progress_indicator DIV whose background image is set to the progress image (this is applied via the stylesheet).  Set the title attribute of this element and animate the width to the specified value. (Lines #16-#20)

Could it get any simpler?

   1: (function($) {
   2:  
   3:     $.fn.progressbar = function(options) {
   4:         // build main options before element iteration
   5:         var opts = $.extend({}, {value:0, tooltip:''}, options);
   6:  
   7:         return this.each(function() {
   8:             //  add the progress DOM structure
   9:             $(this).html('<div class="progress_outer"><div class="progress_inner"><div class="progress_indicator"></div></div></div>');
  10:             
  11:             //  if the metadata plug-in is installed, use it to build the options
  12:             var o = $.metadata ? $.extend({}, opts, $(this).metadata()) : opts;
  13:             
  14:             //  locate the DOM element that contains
  15:             //  the progress image        
  16:             $(this).find('.progress_indicator')
  17:                 //  add the tooltip
  18:                 .attr('title', o.tooltip)            
  19:                 //  and animate the width
  20:                 .animate({width: o.value + '%'}, 'slow');
  21:         });
  22:     };
  23:  
  24: })(jQuery);

 

Using the jQuery progressbar Plugin with the ListView

Then, I can use databinding expressions to encode the tooltip and value options using the databinding expression.  It isn't as pretty, but it defiantly works.  All of the magic happens in line #16.  And if you set the control to runat server, you could populate this value from the codebehind as well. 

   1: <asp:ListView ID="lvWorkItems" runat="server" DataSourceID="ldsWorkItems">
   2:     <LayoutTemplate>
   3:         <table class="yui-grid" cellspacing="0" cellpadding="0">
   4:             <tr class="hdr">
   5:                 <th><asp:LinkButton ID="btnIDSort" runat="server" Text="ID" CommandName="Sort" CommandArgument="ID" /></th>
   6:                 <th><asp:LinkButton ID="LinkButton1" runat="server" Text="Name" CommandName="Sort" CommandArgument="Name" /></th>
   7:                 <th><asp:LinkButton ID="LinkButton2" runat="server" Text="Percent Complete" CommandName="Sort" CommandArgument="PercentComplete" /></th>
   8:             </tr>
   9:             <tr id="itemPlaceholder" runat="server" />
  10:         </table>
  11:     </LayoutTemplate>
  12:     <ItemTemplate>
  13:         <tr class='<%# Container.DataItemIndex % 2 == 0 ? "row" : "altrow" %>'>
  14:             <td><%# Eval("ID") %></td>
  15:             <td><%# Eval("Name") %></td>
  16:             <td><div class='progressBar {value: "<%# Eval("PercentComplete") %>", tooltip:"<%# string.Format("Task {0} is {1}% complete!", Eval("ID"), Eval("PercentComplete")) %>"}'></div></td>
  17:         </tr>
  18:     </ItemTemplate>
  19: </asp:ListView> 

 

Applying the Plugin

And the only remaining bit of awkwardness is that the progressbar plugin needs to be applied twice.  Once when the page first loads.

   1: function pageLoad(sender, args){
   2:     if(!args.get_isPartialLoad()){ 
   3:         //  apply the 
   4:         $('.progressBar').progressbar();
   5:     }
   6: }

 

And then again just after an UpdatePanel is refreshed (I apply it to the panels new contents) ...

   1: Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(function(sender, args){
   2:     var updatedPanels = args.get_panelsUpdated();
   3:     if(updatedPanels && updatedPanels.length > 0){
   4:         for(var i = 0; i < updatedPanels.length; i++) {
   5:              $('.progressBar', updatedPanels[i]).progressbar();
   6:         }
   7:     }                    
   8: });

 

Footprint

And as promised, here is the JavaScript and CSS footprint for this example.  I am using ASP.NET AJAX's ScriptManager and UpdatePanel controls - so those are the axd JavaScript references.  The JavaScript for my plugin is ~1 KB unminified.

JavaScript: 113 KB

image

CSS: 2 KB

image

That's it.  Enjoy!


TrackBack

TrackBack URL for this entry:
http://mattberseth.com/blog-mt/mt-tb.fcgi/135

Comments


Posted by: Jorge on July 1, 2008 12:00 AM

Hi Matt.

What debug plugin do you use to show javascript and css footprint?

Thank you.

You like JQuery ? ^_^
I really like your articles. Thank you very much!

Posted by: vic on July 5, 2008 12:00 AM

great article again..

Matt, I LOVE your blog and have been a regular reader. I am in LOVE with jQuery too and have been using it for all my javascript and ajax and not looking back... I used it on yonkly.com and actually have an article coming out next month in asp.net pro on jQuery and MVC.

Godo job and keep those jQuery posts coming and I specially love your css/style/design postings.

Posted by: Mike H. on July 18, 2008 12:00 AM

Jorge,

I believe that is the "Firebug" plugin for Firefox. Search for it at the Mozilla plugin downloads site.

great stuff .. keep posting your articles.

Hi Matt,

Great post...

I am also a JQuery fan.

I have created a custom control which will help you to dock DIV tags with ease

http://code.google.com/p/weblayoutmanager/

If you have time please have a look at this and let me know your what you think about this


Post a comment

(If you haven't left a comment here before, you may need to be approved by the site owner before your comment will appear. Until then, it won't appear on the entry. Thanks for waiting.)

Consulting Services

Yep - I also offer consulting services. And heck, I'll do just about anything. If you enjoy my blog just drop me an email describing the work you need done.

Recent Comments

  • Rajeesh wrote: Hi Matt, Great post... I am also a JQuery fan. I have created a custom control which will help yo...
  • Anoj wrote: great stuff .. keep posting your articles....
  • Mike H. wrote: Jorge, I believe that is the "Firebug" plugin for Firefox. Search for it at the Mozilla plugin dow...
  • Emad Ibrahim wrote: Matt, I LOVE your blog and have been a regular reader. I am in LOVE with jQuery too and have been u...
  • vic wrote: great article again.. ...
  • Duc Phan wrote: You like JQuery ? ^_^ I really like your articles. Thank you very much! ...
  • Jorge wrote: Hi Matt. What debug plugin do you use to show javascript and css footprint? Thank you. ...