Reputation: 163
Let's say i have a class Person which has
public string Name {get;set;}
public List<string> ListOfStrings {get;set;}
and i'm trying to bind List<Person>
to DropDownListFor so it would look like that
Dropdown:
- First person
- First string of the listOfStrings of first person
- Second string of the listOfStrings of first person
- Second Person
- First string of the listOfStrings of second person
- Second string of the listOfStrings of second person
- third string of the listOfStrings of second person
etc
Is there a way to make it like that? only the strings in list should be selectable and not name of the person. I'm fine with anything
Upvotes: 0
Views: 100
Reputation: 239460
This is relatively straight-forward. The only tricky part is selecting all the string values into one big list, while still keyed to a particular person. Thankfully SelectMany
takes a resultSelector
param that lets you do exactly that. Then, you just select everything into a list of SelectListItem
s and specify the Group
property for each. Razor will then happily take care of generating the appropriate optgroups in the HTML. One thing of note: I think the ability to specify groups didn't come about until MVC 5, though.
ViewBag.DropDownOptions = db.People
.SelectMany(m => m.ListOfStrings, (m, str) => new { Name = m.Name, String = str })
.Select(m => new SelectListItem
{
Value = m.String,
Text = m.String,
Group = new SelectListGroup { Name = m.Name }
});
Then, in your view:
@Html.DropDownListFor(m => m.Foo, (IEnumerable<SelectListItem>)ViewBag.DropDownOptions)
Upvotes: 2
Reputation: 599
I don't know if there is a Razor way of doing this other than a model and a foreach loop, but the HTML you are looking for will be something like this
<select>
<optgroup label="Person1">
<option value="ListOfStrings1">ListOfStrings1</option>
<option value="ListOfStrings2">ListOfStrings2</option>
</optgroup>
<optgroup label="Person2">
<option value="ListOfStrings3">ListOfStrings3</option>
<option value="ListOfStrings4">ListOfStrings4</option>
</optgroup>
</select>
Edit: as of MVC 5.2 there actually is a way to do this. You can find detailed instructions on how to create this HTML with Razor a little more elegantly than with a foreach loop here.
Upvotes: 1