tags:

views:

35

answers:

2

Hello

I have a loop creating a form in my view code. Within the form each item has its own drop down list which they all share from the view data:

    <%foreach(Foo i in Model){ %>
    <tr>
        <td><%=i.title%></td>
        <td><%=Html.DropDownList("order"+i.id.ToString(), ViewData["SequenceDropDown"] as SelectList)%></td>
    </tr>
    <%} %>

I need to make it so the selected item is based on a property of Foo (i.Sequence). I cant seem to find a way to do this?

I can do it in the controller, but I want to be able to share the select list amongst all the items and pick the selected one accordingly.

+1  A: 

I think you'll have to create an array of SelectItem lists in your action which correctly identify the selected item for each instance. You can then create your dropdowns from that array.

It'll be a cleaner implementation than doing this in the View as the View is supposed to be as dumb as possible.

Lazarus
Yeah but then the view would have to then select the correct items in view data based on what the item is. Which to me would make the code even more awkward and certainly doesnt make the view dumb
qui
When you create the SelectList in the Action you would define the selected item as in http://msdn.microsoft.com/en-us/library/dd492553.aspx, all the View then has to do is iterate across the ViewData array of select lists (in synch with your Model iterator) and instantiate the dropdowns. Ideally you'd extend your Foo object to include the SelectList objects, or have an intermediate object that's used for displaying Foo in this context.
Lazarus
You certainly don't have to do this, but it definitely makes the view easier to read.
Jess
A: 

I wrote up a quick fluent extension method to do this:

    public static IEnumerable<SelectListItem> WithSelected( this IEnumerable<SelectListItem> selectListItems, object selectedvalue )
    {
        var newItems = new List<SelectListItem>(selectListItems);

        foreach( var item in newItems )
            item.Selected = item.Value == selectedvalue.ToString();

        return newItems;
    }

    public static IEnumerable<CheckBoxItem> WithSelected(this IEnumerable<CheckBoxItem> selectListItems, int selectedvalue)
    {
        var newItems = new List<CheckBoxItem>(selectListItems);

        foreach (var item in newItems)
            item.Checked = item.Id == selectedvalue;

        return newItems;
    }

    public static IEnumerable<CheckBoxItem> WithSelected(this IEnumerable<CheckBoxItem> selectListItems, IEnumerable<int> selectedvalues)
    {
        var newItems = new List<CheckBoxItem>(selectListItems);

        foreach (var item in newItems)
            item.Checked = selectedvalues.Contains(item.Id);

        return newItems;
    }

Could by dryer I guess, but it works fine. Usage would be something like:

<%foreach(Foo i in Model){ %>
<tr>
    <td><%=i.title%></td>
    <td><%=Html.DropDownList("order"+i.id.ToString(), (ViewData["SequenceDropDown"] as SelectList)).WithSelected(i.Sequence) %></td>
</tr>
<%} %>
jfar