Wednesday, July 08, 2009

ASP.NET MVC & jQuery Part 3: MvcContrib Grid & jQuery Plugins

This is the 3rd blog post in a series taken from a recent ASP.NET MVC & jQuery presentation I gave at CodeStock. The previous blog posts are available here...

  1. Part 1: Adding jQuery Intellisense to VS 2008
  2. Part 2: Zebra Striping

MVC Contrib Grid Component

The ASP.NET MVC 1.0 Release has a lot of great things included in it, but there is another open source project called MVC Contrib that fills many gaps and compliments the core functionality.

In this blog post I want to demonstrate how you can use the MVC Contrib Grid Component in conjunction with two different jQuery plugins to provide rich functionality inside a simple and clean View.

First lets review why you might want to use the MVC Contrib Grid Component.

  • Provides a Fluent Interface
  • Discourages Logic in your View
  • Provides Reusable Grid Models
  • Customizes Grid Rendering
  • Includes a Separate Pagination Component

If the above bullet items interest you, then check out the 5 part blog series on the MVC Contrib Grid Html Helper by Jeremy Skinner.

Enough of describing the component, lets start using the MVC Contrib Grid. After adding a reference to the MvcContrib assembly to your project you can proceed adding the Grid to your View…

<% Html.Grid(Model).Columns( column => {   
   column.For(x => Html.ActionLink("ID", "Details", new { id = x.Id })).Named("View").DoNotEncode();   
   column.For(x => x.Name).Named("Pet Name");   
   column.For(x => x.Description).Named("Description");   
   column.For(x => x.Price).Format("{0:C}"); 
})
.Attributes(style => "width: 75%;")
.Empty("There are no pets.")
.Render(); %>

As you can see in the code above, the syntax is easy to ready and it utilizes the tightly bound model passed to the View. The output of the Grid isn’t anything spectacular (see the following grid).

  <table id="dataTable">
        <thead>
            <tr>
                <th>View</th>
                <th>Pet Name</th>
                <th>Description</th>
                <th>Price</th>
            </tr>
        </thead>
        <tr class="gridrow">
            <td><a href="/MvcContrib/Details/1">ID</a></td>
            <td>Ralph Fits</td>
            <td>A lonely ragged pup that licks himself and isn't house trained</td>
            <td>$12.99</td>
        </tr>
        <tr class="gridrow_alternate">
            <td><a href="/MvcContrib/Details/2">ID</a></td>
            <td>Fluffy Florentine</td>
            <td>A sweet little kitten that is ready to have a home</td>
            <td>$277.00</td>
        </tr>
        <!-- Additional Rows -->
        <tr class="gridrow_alternate">
            <td><a href="/MvcContrib/Details/14">ID</a></td>
            <td>Alien Abbott</td>
            <td>You never hear this dog bark because it only barks in the future.</td>
            <td>$777.99</td>
        </tr>
        <tr class="gridrow">
            <td><a href="/MvcContrib/Details/15">ID</a></td>
            <td>Crazy Calico</td>
            <td>If you like cats, don't get this one because it's pure crazy on a stick!</td>
            <td>$2.99</td>
        </tr>
    </tab

We can now transform the output of the MVC Contrib Grid into a rich featured table with the help of a little jQuery.

jQuery TableSorter Plugin

First, lets use the jQuery TableSorter Plugin to add some simple inline sorting capabilities to the Grid. Only the following one line of jQuery is necessary to transform this Grid. See the follow table for the results.

Note: TableSorter has additional widgets you can add for extra functionality. I am using the zebra widget to provide the alternate row coloring.

$("table").addClass('tableSorter').tablesorter({ sortList: [[1, 0]], widgets: ['zebra'] });  

ViewPet NameDescriptionPrice
IDRalph FitsA lonely ragged pup that licks himself and isn't house trained$12.99
IDFluffy FlorentineA sweet little kitten that is ready to have a home$277.00
IDBubba GumpA very stupid dog that can't even find his way to his dog house$999.99
IDCharlie StrangoThis weird looking puppy scares most adults, but has a strange interest to children$23.44
IDBlacky the BeautifulThis beautiful cat is as kind as can be. Who says that a dog is man's best friend?$45.65
IDSnot Nose NellyIf you want to get wet, then this is the pet for you. Talk about snot everywhere!$44.78
IDDarcy ScoopA wonderful black lab with human-like intelligence; however, it does poop a lot.$234.55
IDSupsrirooantsumA very rare cat straight from it's homeland of India.$432.67
IDClark KentA self-employed kitten making and selling fur balls for all to enjoy.$44.66
IDRed Headed BullThis dog is unlike any other that you have seen. You can even braid it's flowing red hair.$78.99
IDRex the TerribleA half german shepard / half wolf aggresive dog that will tear the flesh out of anyone you wish.$346.99
IDSkittish SteveYou will never see this dog once you buy it. It'll be like you never had a pet to begin with.$33.00
IDDart MouthA dart gun was surgically grafted into this dog's mouth. He is great for parties.$55.00
IDAlien AbbottYou never hear this dog bark because it only barks in the future.$777.99
IDCrazy CalicoIf you like cats, don't get this one because it's pure crazy on a stick!$2.99

jQuery DataTable Plugin

Now, lets try adding a s lightly more feature rich jQuery Plugin to our Grid. The jQuery DataTable Plugin allows not only sorting of columns, but provides an elegant searching mechanism and also paging functionality. Yet again, with only one jQuery statement we can transform this table into something much more usable.

$('dataTable').addClass('dataTable').dataTable({
   "iDisplayLength": 10,
   "aaSorting": [[1, "asc"]],
   "aoColumns": [{ "bSortable": false }, null, null, null]
}); 

ViewPet NameDescriptionPrice
IDRalph FitsA lonely ragged pup that licks himself and isn't house trained$12.99
IDFluffy FlorentineA sweet little kitten that is ready to have a home$277.00
IDBubba GumpA very stupid dog that can't even find his way to his dog house$999.99
IDCharlie StrangoThis weird looking puppy scares most adults, but has a strange interest to children$23.44
IDBlacky the BeautifulThis beautiful cat is as kind as can be. Who says that a dog is man's best friend?$45.65
IDSnot Nose NellyIf you want to get wet, then this is the pet for you. Talk about snot everywhere!$44.78
IDDarcy ScoopA wonderful black lab with human-like intelligence; however, it does poop a lot.$234.55
IDSupsrirooantsumA very rare cat straight from it's homeland of India.$432.67
IDClark KentA self-employed kitten making and selling fur balls for all to enjoy.$44.66
IDRed Headed BullThis dog is unlike any other that you have seen. You can even braid it's flowing red hair.$78.99
IDRex the TerribleA half german shepard / half wolf aggresive dog that will tear the flesh out of anyone you wish.$346.99
IDSkittish SteveYou will never see this dog once you buy it. It'll be like you never had a pet to begin with.$33.00
IDDart MouthA dart gun was surgically grafted into this dog's mouth. He is great for parties.$55.00
IDAlien AbbottYou never hear this dog bark because it only barks in the future.$777.99
IDCrazy CalicoIf you like cats, don't get this one because it's pure crazy on a stick!$2.99



Now, there are definitely some pros and cons in using the above two jQuery plugins.

Pros

  • The TableSorter Plugin & DataTable Plugin are very easy to implement. Only one jQuery statement is needed.
  • The user is presented with a richer interface providing sorting, paging, and simple searching.

Cons

  • Despite the pros listed above, the biggest con is that the jQuery Plugins are not scalable. All the records are returned in the View and the plugins hide and show the necessary data depending upon the user’s actions.

In light of the cons, I personally wouldn’t use any of the above jQuery plugins for my tables unless it was for a trivial non-production web page with a known number of static records.

Normally, I lead towards using either the Flexigrid Plugin or jqGrid Plugin that I will be reviewing in the next blog post in this series.

Submit this story to DotNetKicks Shout it

Tuesday, June 30, 2009

ASP.NET MVC & jQuery Part 2: Zebra Striping

This is the 2nd blog post in a series taken from a recent presentation I gave at CodeStock. The previous blog posts are available here...

  1. ASP.NET MVC & jQuery Part 1: Adding jQuery Intellisense to VS 2008

Probably one of the coolest things you learn (if you haven’t already) after picking up jQuery is realizing how easy it is to add zebra striping to your tables (alternating row color shading) as demonstrated in the following picture.

FireShot capture #1 - 'Scriptlet' - localhost_8080_Zebra_Scriptlet

Before I knew jQuery I used to write code the like the following in order to get the zebra striping appearance for my tables… which stinks to high heaven!

     <table class="styled">
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Description</th>
            <th>Price</th>
        </tr>

    <% for (var i = 0; i < Model.Count(); ++i ) {
        var item = Model.ElementAt(i);    
    %>
    <% if (i % 2 == 0) { %>
        <tr>
    <% } else { %>
        <tr class="alt">
    <% } %>
            <td>
                <%= Html.Encode(item.Id)%>
            </td>
            <td>
                <%= Html.Encode(item.Name)%>
            </td>
            <td>
                <%= Html.Encode(item.Description)%>
            </td>
            <td>
                <%= Html.Encode(String.Format("{0:F}", item.Price))%>
            </td>
        </tr>
    <% } %>
    </table>
 

Obviously, we want to keep our Views in MVC as simple as possible and even though modular logic isn’t overly complicated, we still should keep it out of the View if at all possible.

It would be optimal to keep out the modular logic and keep the View simple like the following…

      <table class="styled">
        <tr>
            <th>Id</th>
            <th>Name</th>
            <th>Description</th>
            <th>Price</th>
        </tr>

    <% foreach (var item in Model) { %>
        <tr>
            <td>
                <%= Html.Encode(item.Id) %>
            </td>
            <td>
                <%= Html.Encode(item.Name) %>
            </td>
            <td>
                <%= Html.Encode(item.Description) %>
            </td>
            <td>
                <%= Html.Encode(String.Format("{0:F}", item.Price)) %>
            </td>
        </tr>
    <% } %>
    </table>
 

This is where jQuery comes in handy! With the following line of code we can add zebra striping…

<script type="text/javascript">
    $(document).ready(function() {
        $(".styled tr:even").addClass("alt");  
    });
</script>

That was easy :) The jQuery line selects all the even rows from the table with the “styled” class attribute and adds the “alt” to all the class attributes which provides the alternating row shading.

Another common usability feature that users tend to like is row hover highlighting. Well, this turns out to be another easy thing to do with jQuery. The following code selects all the rows in the table with the “styled” class and attaches a mouseover and mouseout event to all of them. When those events get fired jQuery will either add or remove the “over” CSS definition to/from the class attribute.

<script type="text/javascript">
    $(document).ready(function() {
        $(".styled tr").bind("mouseover mouseout", function() {
            $(this).toggleClass("over");
        });
    });
</script>

So, after all is said and done our basic table looks like the following with two jQuery function calls :)

Id Name Description Price
1 Ralph Fits A lonely ragged pup that licks himself and isn't house trained 12.99
2 Fluffy Florentine A sweet little kitten that is ready to have a home 277.00
3 Bubba Gump A very stupid dog that can't even find his way to his dog house 999.99
4 Charlie Strango This weird looking puppy scares most adults, but has a strange interest to children 23.44
5 Blacky the Beautiful This beautiful cat is as kind as can be. Who says that a dog is man's best friend? 45.65
6 Snot Nose Nelly If you want to get wet, then this is the pet for you. Talk about snot everywhere! 44.78
7 Darcy Scoop A wonderful black lab with human-like intelligence; however, it does poop a lot. 234.55
8 Supsrirooantsum A very rare cat straight from it's homeland of India. 432.67
9 Clark Kent A self-employed kitten making and selling fur balls for all to enjoy. 44.66
10 Red Headed Bull This dog is unlike any other that you have seen. You can even braid it's flowing red hair. 78.99
11 Rex the Terrible A half german shepard / half wolf aggresive dog that will tear the flesh out of anyone you wish. 346.99
12 Skittish Steve You will never see this dog once you buy it. It'll be like you never had a pet to begin with. 33.00
13 Dart Mouth A dart gun was surgically grafted into this dog's mouth. He is great for parties. 55.00
14 Alien Abbott You never hear this dog bark because it only barks in the future. 777.99
15 Crazy Calico If you like cats, don't get this one because it's pure crazy on a stick! 2.99

Submit this story to DotNetKicks Shout it

Monday, June 29, 2009

ASP.NET MVC & jQuery Part 1: Adding jQuery Intellisense to VS 2008

As I mentioned in my previous post, I am starting a series of detailed blog entries that focus on each topic from a recent CodeStock presentation I gave entitled, “Useful jQuery tips, tricks, and plugins with ASP.NET MVC”

I’ve done several talks about jQuery over the last several months and a common question I get is how to get jQuery Intellisense into Visual Studio.

The steps to include Intellisense are actually quite straight forward and are actually easier than they were several months ago.

  1. Install Visual Studio 2008 SP1
  2. Install Visual Studio 2008 SP1 Hotfix to Support "-vsdoc.js" IntelliSense Doc Files
  3. Download jquery-1.3.2-vsdoc.js from jQuery.com
    • Note: The vsdoc.js is also included when you do a New->Project... ASP.NET MVC Web Application
  4. Include jQuery into your MasterPage

If all goes well, then you should be able to see jQuery Intellisense like this…

Intellisense

If the steps don’t give you the above results, then you might try checking out some frequently asked questions hosted on Jeff King’s (a program manager at Microsoft) website. He has a great list of gotchas that might help you getting past your particular situation.

Also, you can check out Scott Gu’s or Rick Strahl’s posts for further details of the above instructions.

Submit this story to DotNetKicks Shout it