I have a web application where all the data is in a single table and is therefore contained within a single class object. The structure of the table is something like:
GoalId
Goal1Comments
Goal1Results
Goal1Weight
Goal1Rating
Goal2Comments
Goal2Results
Goal2Weight
Goal2Rating
Goal3Comments
Goal3Results
Goal3Weight
Goal3Rating
Goal4Comments
Goal4Results
Goal4Weight
Goal4Rating
As you can see from the repetition, there are four goals, but each one will be displayed the same. I've tried the approach of making a single goal object and creating a list of objects based on this class, but that convoluted my application to and through.
What I'm trying to figure out is how to make a single partial view that will take 4 values from this goal record-the specific 4 values I want it to display, but give the resulting controls a specific name value. In other words, I want to pass data to this partial view, and have it render it's html elements in a manner like:
<input type="text" name="goal1comments" />
<input type="text" name="goal1results" />
<input type="text" name="goal1Weight" />
<input type="text" name="goal1Rating" />
<input type="text" name="goal2comments" />
<input type="text" name="goal2results" />
<input type="text" name="goal2Weight" />
<input type="text" name="goal2Rating" />
<input type="text" name="goal1comments" />
<input type="text" name="goal1results" />
<input type="text" name="goal1Weight" />
<input type="text" name="goal1Rating" />
<input type="text" name="goal2comments" />
<input type="text" name="goal2results" />
<input type="text" name="goal2Weight" />
<input type="text" name="goal2Rating" />
Yet my parent view will simply have four calls to the partial view with the necessary data being passed. Example:
<% Html.RenderPartial("Goal",
Model.Goal1Comments , Model.Goal1Results,
Model.Goal1Weight, Goal1Rating); %>
<% Html.RenderPartial("Goal",
Model.Goal2Comments , Model.Goal2Results,
Model.Goal2Weight, Goal2Rating); %>
<% Html.RenderPartial("Goal",
Model.Goal3Comments , Model.Goal3Results,
Model.Goal3Weight, Goal3Rating); %>
<% Html.RenderPartial("Goal",
Model.Goal4Comments , Model.Goal4Results,
Model.Goal4Weight, Goal4Rating); %>
I don't even know if what I'm asking is possible, but is there a way for the partial control to name the html controls it creates based on the name of the field passed into them? So, the first time the partial is rendered, it knows that Goal1Comments, Goal1Results, Goal1Weight, and Goal4Rating were the properties used to provide the values to the control as it's model?
I have a terrible knack for doing things the hard way and I don't mean to, but when I tried simply breaking this into a List of Goal objects and having that list as a property on the main record's class, it just seemed like my entire application had to bend itself around this awkwardness. The application became a jumbled confused mess all for the sake of having a simple view layer.
EDIT 1
I've tried your suggestion(s). It seems the Html.TextBoxFor helper is ever stubborn (I've run into this in the past) and won't name elements as I'm instructing. Here is what I've done.
My partial view looks like this:
<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<PartialControlTesting.Models.IndividualGoal>" %>
<fieldset>
<legend>Fields</legend>
<div class="display-label">HtmlName: <%= Html.Encode(Model.HtmlName) %></div>
<div class="display-label">GoalRating</div>
<div class="display-field"><%= Html.TextBoxFor(x=>x.GoalComments, new { name = Model.HtmlName + "Comments"} ) %></div>
<div class="display-label">GoalWeight</div>
<div class="display-field"><%= Html.TextBoxFor(x=>x.GoalWeight, new { name = Model.HtmlName + "Weight"} ) %></div>
<div class="display-label">GoalComments</div>
<div class="display-field"><%= Html.TextBoxFor(x=>x.GoalRating, new { name = Model.HtmlName + "Rating"} ) %></div>
</fieldset>
My parent view looks like this:
<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<PartialControlTesting.Models.GoalData>" %>
<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
Home Page
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
<h2><%= Html.Encode(ViewData["Message"]) %></h2>
<p>
To learn more about ASP.NET MVC visit <a href="http://asp.net/mvc" title="ASP.NET MVC Website">http://asp.net/mvc</a>.
</p>
<br />
<% using (Html.BeginForm())
{%>
<% Html.RenderPartial("Goal",
new PartialControlTesting.Models.IndividualGoal(
Model.Goal1Rating, Model.Goal1Weight,
Model.Goal1Comments, "Goal1")); %>
<% Html.RenderPartial("Goal",
new PartialControlTesting.Models.IndividualGoal(
Model.Goal2Rating, Model.Goal2Weight,
Model.Goal2Comments, "Goal2")); %>
<p>
<input type="submit" id="submit" value="Submit" />
</p>
<% } %>
</asp:Content>
The HtmlName value is being correctly passed into the partial view, yet the controls render using the name of the properties they are made and ignores my additional html attribute name parameter. The source of the rendered page looks like:
<fieldset>
<legend>Fields</legend>
<div class="display-label">HtmlName: Goal1</div>
<div class="display-label">GoalRating</div>
<div class="display-field"><input id="GoalComments" name="GoalComments" type="text" value="g1 comments" /></div>
<div class="display-label">GoalWeight</div>
<div class="display-field"><input id="GoalWeight" name="GoalWeight" type="text" value="20" /></div>
<div class="display-label">GoalComments</div>
<div class="display-field"><input id="GoalRating" name="GoalRating" type="text" value="1" /></div>
</fieldset>
I could build the html controls manually as has been suggested, but this isn't the first time I've seen the "..For" helpers do this. I would like to know why and how to fix it. Thoughts?