Betard Fooser
Betard Fooser

Reputation: 526

C# MVC 2 HtmlHelper to generate Table Columns with Model Binding

I'm after an MVC2 custom htmlHelper that will allow me to dynamically create X amount of columns given the data.

Say for instance I have a Zoo class which contains a list of Animals (which also contains a sub class). Ex:

public class Zoo
{
  public List<Animals> myAnimals;
}

public class Animals 
{
  public string year;

  public WarmClimate warm;

  public class WarmClimate {
    public string hippo;
    public string zebra;
    public string elephant;
    etc...
  }
}

and I want to create a table similar to the following. Essentially creating a column for every list of Animals I have. Could be 4 columns worth of data or could be 30.

   |             | 2011 | 2012 | 2013 | 2014 |
   | hypo        | 6    | 1    | 7    |  0   |
   | zebra       | 1    | 1    | 2    |  1   |
   | elephant    | 1    | 1    | 3    |  0   |

I currently have something like this; which is quite basic. Simply a for loop that iterates over the list grabbing the defined property value. If there were 100 animals in my class, a page with 100 for loops like this is a nightmare.

<tr>
    <td>Zebras: </td>
    <% 
        for (int i = 0; i < Model.myAnimals.Count; i++)
        {
    %>
        <td><%= Html.EditorFor(x => x.myAnimals[i].warm.zebra) %></td>
    <%
        }
    %>
</tr>

I Would like to replace that with a custom htmlhelper that would allow me to do something like:

<tr>
  <td>Zebras: </td>
  <%= Html.MyCustHelper( property?? , list??, expression??) %>
</tr>

MyCustHelper would return the appropriate html with NAME attribute populated correctly for model binding, much like it does when I use Html.EditorFor() helper, ex:

<td><input name="myAnimals[2].warm.zebra" id="myAnimals_2__warm_zebra" type="text" value="1"></td> etc.... etc...

Maybe I'm going about this all wrong, but I assume there would be a simple way to output repeatable columns worth of data.

Can anyone help out with an efficient way of doing this?

Upvotes: 1

Views: 1476

Answers (1)

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93494

I don't see why you need a custom helper when an EditorTemplate should do what you want. You would still use EditorFor, but use a template with it.

Basically, you just specify the template name with your EditorFor:

<tr>
    <td>Zebras: </td>
    <%= Html.EditorFor(x => x.MyAnimals, "Zebras") %>
</tr>

I have long forgotten the WebForms syntax for this, but it would be something like this. Create an EditorTemplates folder and in that create a file called Zebras.ascx and add the appropriate WebForms @directives for strongly typed model.

<td><%= Html.EditorFor(x => x.warm.zebra) %></td>

Editor Templates automatically iterate over the collection, so you don't need the index, and it automatically generates the correct naming convention.

Read the 5 part series here:

http://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-1-introduction.html

Unfortunately, I stopped being able to think in WebForms code quite some time ago, so I can't give you a real example.

Upvotes: 2

Related Questions