MvcContrib Grid Part 5 – The Action Syntax
March 1, 2009 – 14:33
This is part 5 of a series about the new MvcContrib grid.
- Part 1 – Introduction
- Part 2 – New Syntax
- Part 3 – GridModels and GridRenderes
- Part 4 – Limitations of the WebFormsViewEngine
- Part 5 – The Action Syntax
The rewritten MvcContrib grid now has an alternative syntax thanks to the work of Will Shaver. This syntax is called the ‘Action’ syntax as it makes heavy use of the System.Action delegate.
Enabling the ActionSyntax
By default, the methods associated with the Action Syntax will not show up as they are extension methods that live in a different namespace to the rest of the grid. Out of the box only the default syntax will work. To enable the Action Syntax you’ll need to either import the MvcContrib.UI.Grid.ActionSyntax namespace either in your .aspx view…
<%@ Import Namespace="MvcContrib.UI.Grid.ActionSyntax" %>
…or in your web.config’s namespace import section:
<system.web> <pages> <namespaces> <add namespace="MvcContrib.UI.Grid.ActionSyntax" /> </namespaces> </pages> </system.web>
Comparing the two syntaxes
There are several differences between the two syntaxes. Here is a grid definition using the default syntax:
<%= Html.Grid(Model) .Columns(column => { column.For(x => x.Id).Named("Person ID"); column.For(x => x.Name); column.For(x => x.Gender); column.For(x => x.DateOfBirth).Format("{0:d}"); column.For("View Person").Named("").Partial("ViewPersonPartial"); //Example of using a Partial view for complex cells }).RowStart(row => string.Format("<tr{0}>", row.IsAlternate ? "style=\"background-color:#CCDDCC\"" : "")) %>
Here we’re specifying that the View Person column is a custom column that should be rendered using a Partial View, and the start of every alternate row has a background colour**.
Here is the same grid defined using the ActionSyntax:
<% Html.Grid(Model).Columns(column => { column.For(x => x.Id).Named("Person ID"); column.For(x => x.Name); column.For(x => x.Gender); column.For(x => x.DateOfBirth); column.For("View Person").Named("").Action(p => { %> <td style="font-weight:bold"> <%= Html.ActionLink("View Person", "Show", new { id = p.Id })%> </td> <% }); }).RowStart((p,row) => { if (row.IsAlternate) { %> <tr style="background-color:#CCDDCC"> <% } else { %> <tr> <% } }).Render(); %>
Note the following differences:
- The ActionSyntax requires the use of <% %> tags rather than <%= %> tags.
- The ActionSyntax requires that you end your grid definition with a call to the Render method or the grid will not show up if you do not call Render.
- You must terminate the call to Render with a semicolon
- You can directly embed HTML in the grid definition rather than using strings or partial views
Both syntaxes have their advantages and disadvantages but the end result is the same. You’re free to use whichever one you prefer.
**Both the partial view/actionsyntax approach are designed only for complex column definitions. This example was quite contrived and you could achieve the same result with a far simpler approach:
<style type="text/css">
.gridrow_alternate { background-color:#CCDDCC; }
</style>
<%= Html.Grid(Model)
.Columns(column => {
column.For(x => x.Id).Named("Person ID");
column.For(x => x.Name);
column.For(x => x.Gender);
column.For(x => x.DateOfBirth).Format("{0:d}");
column.For(x => Html.ActionLink("View Person", "Show", new { id = p.Id }))
.Attributes(x => new Hash(style => "font-weight:bold"));
}) %>
27 Responses
I should have read this post before commenting on the last one
Jeremy,
Thanks for the Column Attribute enhancement. It works great for me. I would, however, like to complain about your responsiveness. I took you at least 4 hrs to post the change to google code following my suggestion.
I made a post about the ordering the columns.
http://fknet.wordpress.com/2009/03/06/ordering-in-the-mvccontrib-grid/
Another post about using T4 templates used to generate the views.
Here is the link:
http://fknet.wordpress.com/2009/03/11/tt-template-for-mvc-grid-with-ordering-and-paging/
I’ve just tried implementing this syntax
column.For(wp => Html.ActionLink(“Remove Page”, “RemovePage”, new { id = wp.Id }));
for one of my columns as per your example, but whilst it works it html encodes the action link so I get the following as out put
Remove Page
in the table rather than as a seperate column.
What am I doing wrong?
Ta
That last comment should have the Remove Page link as actual html, sorry
Hi Anthony,
All columns are HTML-encoded by default. You need to explicitly disable encoding by using DoNotEncode:
column.For(wp => Html.ActionLink(”Remove Page”, “RemovePage”, new { id = wp.Id })).DoNotEncode();
Nice one thanks, btw I had trouble getting things to work as document doesnt really talk about if you are new to the Grid control.
I had to add the
to the top of my views to make it work, or did I miss something?
<%@ Import Namespace=”MvcContrib.UI.Grid” %>
Sorry for got that bit in previous comment, need to fix that on your blog for us idiots
Yes, that is correct – you need to import the namespace (either in the page or via the web.config). I’m planning on writing some documentation for the mvccontrib wiki but haven’t had an opportunity to do so.
I’ll take a look at the HTML-parsing settings for comments.
Just tried adding an onclick attribute to the link and got a strange result. The actual confirm message works fine but the url gets screwed.
My Code:
column.For(l => Html.ActionLink(“Delete”, “DeleteLocation”, new RouteValueDictionary(new { id = l.LocationId }), new { onclick = “return confirm(‘Are you sure?’);” })).DoNotEncode();
The rendered output:
Delete
Anthony,
You’re using the wrong overload of ActionLink. Change it to:
Html.ActionLink(“Delete”, “DeleteLocation”, new { id = l.LocationId }, new { onclick = “return confirm(‘Are you sure?’);” })
Thanks
Jeremy,
Is it possible to add a footer row using the MVCContrib Grid? And if so, how?
Regards,
Roberto.-
Hi Roberto,
Out of the box there’s no built in way to do this, but there are some extensibility points you can hook into if you want to add this functionality.
If you create a custom GridRenderer that inherits from HtmlTableGridRender then you could override the RenderGridEnd method and generate the appropriate HTML in there.
Is there anyway to hide a column? I have an ID field that I don’t want displaying but I want as a hidden field for every row
Thanks
Dave
Hi Dave,
Yes – just set the appropriate attributes on the cell and the header to hide the column:
Html.Grid(model).Columns(col => {
col.For(x =>x.Id).Attributes(style => “display:none”).HeaderAttributes(style => “display:none”);
});
Fantastic, grid / pagination works great BTW
How can I alter cellpadding/cellspacing on the table?
Sorry I had double .Attributes(), that’s why it wasn’t working — gah!!
Technical Jargon » MvcContrib Grid Part 5 – The Action Syntax…
Thank you for submitting this cool story – Trackback from YOUR-TITLE…
Hi Jeremy,
How can I put an url link such as “www.myweb.com/accounts/add” in header of a column? Thanks!
Thanks Jeremy Skinner
In MVC contrib, we have a nice Html.InputForm() method, that outputs all model fields in a form. Would be nice to have this functionality in the grid, without adding the columns explicitly. You could use certain attributes of the model (e.g. LabelAttribute) for controlling the output. This way, if we add a new property, we don’t need to add the corresponding column.
One problem is that you might want to use the same model with the grid as well as details, and don’t show some fields in the grid. However, this can be easily controlled with attributes as well.
Using The MVC Contrib Grid
On Submit How can I get all the values of the grid in Action of the Controller
Funso,
The grid is just a normal HTML table. You need to add the appropriate form elements if you need to send data back to the server.