4

I have a View with a foreach loop for a list property of the model. Now, I want to be able to let the user set the value of each of the items in the list using a dropdownlist. But I'm not sure how to do that. I've used something like this when it is not in a foreach loop:

@Html.DropDownListFor(model => model.Level, new SelectList(new[] { 1, 2, 3, 4, 5 }, Model.Level))

But how do I do this when I need to reference item.Level in the loop instead? Here's my View code:

<div id="formDiv">
    @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
    {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>Ny arbetserfarenhet</legend>
            <table>
                <tr>
                    @*<th></th>*@
                    <th>
                        Program
                    </th>
                    <th>
                        Nivå
                    </th>
                </tr>
                @foreach (var item in Model) {
                    <tr>
                        <td>
                            @item.Program.Name
                        </td>
                        <td>

                            @item.Level
                        </td>
                    </tr>
}
            </table>
        </fieldset>
    }
</div>

4 Answers 4

8

I have a View with a foreach loop for a list property of the mode

I would recommend you to avoid writing loops in your views in favor of editor templates. So:

@model IEnumerable<AppName.Models.ModelName>
<div id="formDiv">
    @using (Html.BeginForm(null, null, FormMethod.Post, new { id = "myForm" }))
    {
        @Html.ValidationSummary(true)
        <fieldset>
            <legend>Ny arbetserfarenhet</legend>
            <table>
                <tr>
                    <th>
                        Program
                    </th>
                    <th>
                        Nivå
                    </th>
                </tr>
                @Html.EditorForModel()
            </table>
        </fieldset>
    }
</div>

and in the corresponding editor template (~/Views/Shared/EditorTemplate/ModelName.cshtml):

@model AppName.Models.ModelName
<tr>
    <td>@Model.Program.Name</td>
    <td>
        @Html.DropDownListFor(
            model => model.Level, 
            new SelectList(
                Enumerable.Range(1, 5).Select(x => new { Value = x, Text = x }), 
                "Value", 
                "Text"
            )
        )
    </td>
</tr>

So the editor template will be rendered for each element in your model (which is a collection of some type). The important part is that the editor template must be located in ~/Views/Shared/EditorTemplates and named XXX.cshtml where XXX is the type name used in your main view model collection.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the tip! Is the reason for not using for loops that it is just more elegant like this, or some other reason? I could use it, but had to change the selectlist to the same syntax I had before, I got something strange out in the list as value and text, otherwise it worked fine!
@Anders Svensson, many reasons: cleaner views, less code, strongly typed helpers, no need to worry about generating proper id and names for binding back, ...
Ok, thanks! In any case, I realized I had to categorize items as well... which makes this a little more complicated. If you feel up to it, you're welcome to take a look at my follow-up question: stackoverflow.com/questions/5433710/…
Also, using a DropDownListFor currently does not work well within a loop. There's an open issue for this: link. This problem does not exist with editor templates.
5

Have you tried:

@Html.DropDownListFor(m => item.Level, new SelectList(new[] { 1, 2, 3, 4, 5 }, item.Level))

Comments

0

use this syntax:

  @Html.DropDownListFor(model => model.Level, new SelectList(Model.level as System.Collections.IEnumerable, "VALUE_FIELD", "TEXT_FIELD", YOUR PROPERTY NAME)

1 Comment

It's not the selectlist that's the problem, it's the fact that the dropdownlist is in a foreach loop, so I can't use the model => model.Level syntax...
0

MVC will create the loop. Just use an editor template, partial view in special folder, and the rest works like magic.

Editor Template

@model Models.AdditionalAccountingLine
@Html.HiddenFor(m => m.IsRequired)
@Html.DropDownListFor(m => m.FieldValue, new SelectList(@Model.FieldValueOptions, "Key", "Value"), "")

View

@Html.EditorFor(m => m.AdditionalAccountingLines);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.