0

I will try my best to explain what I am looking for.

Let's say for argument's sake that I have a table in my database that has the properties ID, Item, Category...

the table is populated as so:

================================
|ID|    |Item       | Category |
================================
|  1    |  Batman   |   DC     |
|  2    |  Superman |   DC     |
|  3    |  Aquaman  |   DC     |
|  4    |  Spiderman|   Marvel |
|  5    |  Ironman  |   Marvel |
|  6    |  Thor     |   Marvel |
================================

Now, I want to create a dropdownlist with this information... but seperated by the category..

So it would look like this:

  1. DC
    • -Batman
    • -Superman
    • -Aquaman
  2. Marvel
    • -Spiderman
    • -Ironman
    • -Thor

Now it doesn't need to be as formatted as shown above but just a simple nested list with the emphasis on the Category

How would I iterate through the table and each time the Category changes to print that Category text once then print the Item's that correspond with that Category underneath it?

Grizzly
  • 5,873
  • 8
  • 56
  • 109
  • 1
    http://stackoverflow.com/questions/607188/support-for-optgroup-in-dropdownlist-net-mvc – Shyju Apr 04 '16 at 19:52
  • How about something like this: http://weblogs.asp.net/raduenuca/asp-net-mvc-extending-the-dropdownlist-to-show-the-items-grouped-by-a-category – David Oesterreich Apr 04 '16 at 19:56
  • Are you using asp.net-mvc? And if so which version? –  Apr 04 '16 at 22:55
  • @StephenMuecke Yes i am, version 5.2.3.0 – Grizzly Apr 05 '16 at 12:01
  • Then you can just use one of the [overloads](https://msdn.microsoft.com/en-us/library/system.web.mvc.selectlist.selectlist(v=vs.118).aspx#M:System.Web.Mvc.SelectList.) of `SelectList` that add the `dataGroupField` (or set the `Group` property of `SelectListItem`) and use `@HtmlDropDownListFor()` in your view –  Apr 05 '16 at 12:06
  • @StephenMuecke thank you so much! I used the dataGroupField for SelectList. I didn't even see that overload. If you leave an answer I will mark it! – Grizzly Apr 05 '16 at 12:19
  • @StephenMuecke sounds good – Grizzly Apr 05 '16 at 12:24

2 Answers2

2

If you wanted to output your results as you initially provided, you could accomplish this by using a GroupBy call and then simply iterating through those groups (and subsequently the items within each group):

@foreach(var group in Model.GroupBy(g => g.Category))
{
     <ol>
        <li><b>@group.Key</b></li>
        <ul>
        @foreach(var item in group)
        {
            <li>- @item</li>
        }
        </ul>
     </ol>
}

This assumes that you already have the objects from your database within your Controller and are simply passing the collection of them into your View. Additionally, this example is performed within the View, which isn't ideal (you preferably want to handle this logic within the actual model itself).

As far as creating a DropDownList goes, you could really do the same if you wanted to preface each entry with its appropriate category :

<select id='Hero' name='Hero'>
@foreach(var hero in Model)
{
     <option value='hero.ID'>@hero.Category - @hero.Item</option>
}
</select>
Rion Williams
  • 74,820
  • 37
  • 200
  • 327
  • You're also presuming he is using MVC and I don't see anything in the question to indicate that. Not saying he isn't, just saying it isn't really indicated by the question. The question doesn't even indicate a web application. – Kevin Apr 04 '16 at 19:54
  • I only assumed this from the `model-view-controller` tag that was attached to the question. – Rion Williams Apr 04 '16 at 19:55
  • Ok, good catch, I didn't even look at the tags, just read the question. – Kevin Apr 04 '16 at 19:56
  • @Kevin yes i am using MVC – Grizzly Apr 04 '16 at 19:57
  • 1
    why not use optgroup and nest the grouped options inside... – Mike Apr 04 '16 at 19:59
  • `` is a totally viable option for this. I just posted this to indicate a general idea that it wasn't limited to lists or anything else. – Rion Williams Apr 04 '16 at 20:01
  • @Mike I need it to be dynamic to when something changes in the database – Grizzly Apr 04 '16 at 20:01
  • @RionWilliams Could you post an example of doing this in the model itself and not in the cshtml view? – Grizzly Apr 04 '16 at 20:01
  • @BviLLe_Kid HTML structure shouldn't have an impact on what you do to generate the DDL. Optgroups will be dynamic if you setup your code to generate it as so. – Mike Apr 04 '16 at 20:03
2

In MVC-5.2, you can use one of the overloads of SelectList that accepts string dataGroupField to group your options. For example, in the controller

model.OptionList = new SelectList(db.MyTable, "ID", "Item", "Category", null);
return View(model);

and in the view

@Html.DropDownListFor(m => m.MyProperty, Model.OptionList)

Alternatively you can build an IEnumerable<SelectListItem> and set the Group property, for example

List<SelectListItem> optionList = new List<SelectListItem>
var groups = db.MyTable.GroupBy(x => x.Category);
foreach(var group in groups)
{
    var optionGroup = new SelectListGroup() {Name = group.Key};
    foreach (var item in group)
    {
        optionList.Add(new SelectListItem { Value = item.ID.ToString(), Text = item.Item, Group = optionGroup });
    }
}