Elisabeth
Elisabeth

Reputation: 21206

Put razor for-loop with indexed property into html partial

Is it possible to put this razor html view into a partial view or render with html.partial("partial") Or how can I do it if possible, without breaking the indexing of each field that the default model binder can still do its job correctly?

@for (int i = 0; i < Model.People.Count; i++)
{
  <tr>
    @Html.HiddenFor(m => m.People[i].ProductId)
    @Html.HiddenFor(m => m.People[i].Name)
    @Html.HiddenFor(m => m.People[i].Description)                       
    <td>
      @if (hasMoreThanOnePeople)
      {
        @Html.CheckBoxFor(m => m.People[i].IsSelected)
      }
      else
      {
        @Html.HiddenFor(m => m.People[i].IsSelected, new { Value = "true" })
      }
    </td>
    <td>
      @Html.DisplayFor(m => m.People[i].Name)
    </td>
    <td>
      @Html.DisplayFor(m => m.People[i].Description)
    </td>                       
  </tr>
}

Upvotes: 1

Views: 301

Answers (2)

user3559349
user3559349

Reputation:

The correct usage is to use an custom EditorTemplate for your type. Assuming your class is named Person, then

In Views/Shared/EditorTemplates/Person.cshtml (note the file name must match the class name)

@model YourAssembly.Person
<tr>
  <td>
    @Html.HiddenFor(m => m.ProductId)
    @Html.HiddenFor(m => m.Name)
    @Html.HiddenFor(m => m.Description)
    @Html.CheckBoxFor(m => m.IsSelected)
  </td>
  <td>
    @Html.DisplayFor(m => m.People[i].Name)
  </td>
  <td>
    @Html.DisplayFor(m => m.People[i].Description)
  </td>
<tr>

Then in the main view

@model YourModel
@using(Html.BeginForm())
{
  <table>
    @Html.EditorFor(m => m.People)
  </table>
  ...
}

The EditorFor() method is smart enough to render a collection with indexers

Side notes:

  1. To make the EditorTemplate specific to a controller, you can create the file in Views/YourControllerName/EditorTemplates/Person.cshtml
  2. An input is not a valid child of a <tr> element. Place the inputs inside a <td> tag.
  3. Do not attempt to set the value attribute in a helper. Html helpers are designed to bind to your model. Instead, if your collection only contains one Person object, set the value of its IsSelected property to true in the controller before you pass the model to the view.

Upvotes: 0

Mir Gulam Sarwar
Mir Gulam Sarwar

Reputation: 2648

Yes. May be you are looking for something like

In the Main View

@Html.Partial("ViewName",Model.People)

Then in the partial View u can use foeach/for whatever u want

@foreach(var item in Model)
{
}

Upvotes: 1

Related Questions