I am creating a model which is intended to hold a table. The table will hold an arbitrary number of rows defined at run-time. I am wondering if there’s an easy way to define this in MVC?
Currently all I have is:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CableSolve.Web.Models.Orders.ActivityDetailsModel>" %>
<div id="ActivityDisplay">
<table id="ActivitiesGrid">
</table>
<div id="ActivitiesGridPager"></div>
</div>
In a different model, I create a table which had a static number of rows. This was pretty easy:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CableSolve.Web.Models.Orders.OrderDetailsModel>" %>
<fieldset class="collapsible">
<legend>
<%= Html.DisplayFor(model => model.OrderDetailsLegendName)%>
</legend>
<table id="OrderDetailsContentTable" class="ContentTable">
<tr>
<td><%= Html.DisplayFor(model => model.OrderID.Name)%></td>
<td><%= Html.DisplayFor(model => model.OrderID.Value)%></td>
<td><%= Html.DisplayFor(model => model.Comment.Name)%></td>
<td><%= Html.DisplayFor(model => model.Comment.Value)%></td>
</tr>
...
So, any ideas on how I could go about having an arbitrary number of rows in ActivitiesGrid?
Basically, my controller is going to get some information at run-time and I want to display the retrieved information in a table, but I do not know how many rows of information I am going to receive.
As a light-weight solution without introducing third-party stuff (for now, if it proves necessary I will):
public class ActivityDetailsModel
{
public List<ActivityRow> ActivityRows = new List<ActivityRow>();
public struct ActivityRow
{
public DateTime? Date;
public string Person;
public string OrderOrTaskID;
public string Activity;
public ActivityRow(DateTime? date, string person, string orderOrTaskID, string activity)
{
Date = date;
Person = person;
OrderOrTaskID = orderOrTaskID;
Activity = activity;
}
}
public ActivityDetailsModel(IEnumerable<Activity> activities)
{
foreach(Activity activity in activities)
{
string orderOrTaskID = activity.TaskID != 0
? activity.OrderID + "-" + activity.TaskID
: activity.OrderID.ToString();
string activityDescription = string.Format("OldValue: {0}, NewValue: {1}", activity.OldValue,
activity.NewValue);
ActivityRows.Add(new ActivityRow(activity.UpdateDateTime, activity.UpdateUsername, orderOrTaskID, activityDescription));
}
}
}
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<CableSolve.Web.Models.Orders.ActivityDetailsModel>" %>
<div id="ActivityDisplay">
<table id="ActivitiesGrid">
<%foreach (var activityRow in Model.ActivityRows)
{%>
<tr>
<td><%= Html.DisplayForModel(activityRow.Date)%></td>
<td><%= Html.DisplayForModel(activityRow.Person)%></td>
<td><%= Html.DisplayForModel(activityRow.OrderOrTaskID)%></td>
<td><%= Html.DisplayForModel(activityRow.Activity)%></td>
</tr>
<%}%>
</table>
<div id="ActivitiesGridPager"></div>
</div>
Is this relatively understandable? I hate the mark-up with all the angle-brackets and percent signs, but the project hasn’t been developer with the alternative syntax.
Since you’re after something dynamic, you can take advantage of existing helpers like MVC WebGrid helper or even MvcContrib Grid. These helpers will take care of generating a table containing the columns you want. There’s no need to write the table by hand since it’ll be dynamically generated during runtime according to the number of objects present in your datasource.