How to use MvcContrib Html.Grid() with a cell that has a colspan of 2

clock February 17, 2010 10:34 by author Shane Sievers

In a recent project, I was working on an MVC View that displayed a list of records with Edit and Delete buttons on them.  This project was using the Blueprint CSS framework as well as Jquery-UI.  Having both of my Edit and Delete buttons in the same cell was forcing one of them onto the next line, like so:

Here is the Html.Grid code I was using:

Html.Grid(Model.Items).Columns(column => {
  column.For(x => Html.ActionLink(x.RecordNumber, "Edit", new {id = x.Id})).DoNotEncode().Named("Record Number");
  column.For(x => x.Author);
  column.For(x => "<div class='option-button ui-corner-all ui-state-default'><a href='Records/Edit/" + x.Id + "' class='ui-icon ui-icon-wrench'></a></div><div class='option-button ui-corner-all ui-state-default'><a class='ui-icon ui-icon-trash'></a></div>")
    .DoNotEncode().Named("Options").HeaderAttributes(new Hash(@class => "{sorter: false} span-1"));
  }).Render();

The problem here is evident, who wants buttons stacked like that?  Now a simple fix may have been to just apply some new CSS properties to better control default width, margin, or padding of these elements.  But that solution doesn't look as pretty in code and adds unneeded weight to the page.  The Blueprint span classes do not go smaller than "span-1", so controlling the content through Blueprint was also out of the question.  I wanted to give my 'Options' table header cell the attribute colspan a value of 2.  At first I wasn't sure of the best way to do this and after a few searches through Google and Stackoverflow I still didn't know the best route.  A coworker pointed out that I should probably start with the Attributes method, and a solution was born:

Html.Grid(Model.Items).Columns(column => {
 column.For(x => Html.ActionLink(x.RecordNumber, "Edit", new {id = x.Id})).DoNotEncode().Named("Record Number");
 column.For(x => x.Author);
 column.For(x => "<div class='option-button ui-corner-all ui-state-default'><a href='Records/Edit/" + x.Id + "' class='ui-icon ui-icon-wrench'></a></div>")
   .Attributes(@width => "20px")
   .DoNotEncode().Named("Options").HeaderAttributes(new Hash(@class => "{sorter: false} span-1", @colspan => "2"));
 column.For(x => "<div class='option-button ui-corner-all ui-state-default'><a class='ui-icon ui-icon-trash'></a></div>")
   .Attributes(@width => "20px").DoNotEncode().Header("");
}).Render();

The solution was to set the HeaderAttribute with a colspan of 2 and then on the next column, override the Header() method with an empty string.  Usually you would place a <th> tag in the Header string, leaving it empty keeps it from rendering that column header.  Voila!  You'll notice I did still have to add width attributes to the content cells, that was unfortunate however I still feel good about the solution.



A .Net class library for Pivotal Tracker API

clock February 1, 2010 09:24 by author Shane Sievers
A few weeks ago our team started using Pivotal Tracker to manager our user stories, bugs, and features.  As taken from their website, 
Tracker is a free, award winning, agile project management tool that enables real time collaboration around a shared, prioritized backlog.
- http://www.pivotaltracker.com/ 

On top of that, its a refreshing break from our previous project management tool,  Target Process.  While Target Process is no doubt a powerful, robust, agile project management solution; it was a bit much sometimes.  Pivotal Tracker is more asthetically pleasing as well as easy to use. 

Unfortunately, there wasn't a lot of help out there for integrating our .Net websites with their API.  The Pivotal Tracker API integration page does feature an exmple by Michael McKerlie here.  This was a decent start, so I've added to it and in turn answered some of the questions posted in his comments.  Behold, my first contribution to Google's Open Source project hosting - http://code.google.com/p/pivotal-tracker-api/.  Here you will find some great wiki pages on how to integrate Pivotal Tracker API for .Net into your solution as well as planned features.  

We currently use the API to integrate our user Feedback form with our Pivotal project.  This way, when a user submits feedback, it enters our project queue as a bug so that we have to take action on it.  It seems to work good in our enviornment, but thats probably because we have closed channel of users - I'm not sure I would recommend giving a public site this functionality.  Opening your Project Management queue to spam-bots would probably be a bad thing.

Two things I look forward to adding in the near future include examples for using with Asp.Net MVC and the ability to Export project stories during a build (NUnit) for backup.  Check back here or the project site often for updates.