Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Foreach inside of Foreach Razor

I am trying to write a foreach loop that will find each distinct category type, and then list each Title that has that category assignment.

For example:

@model IEnumerable<CMESurvey.Models.SurveyProgramModel>

@{
    ViewBag.Title = "Home";
}

@foreach (var item in Model) {
    <h2>@Html.DisplayFor(modelItem => item.ProgramType.ProgramType)</h2>
    foreach (var listing in Model)
    {
        <ul>
            <li>@Html.DisplayFor(modelItem => listing.ProgramTitle)</li>
        </ul>
    }
}

Survey Response Model:

  public class SurveyProgramModel
{

    [Key]
    public int ProgramId { get; set; }

    public int ProgramYear { get; set; }

    public int ProgramStatusId { get; set; }

    public string ProgramTitle { get; set; }



public virtual SurveyProgramModel SurveyProgramModel { get; set; }

public virtual PersonModel PersonModel { get; set; }

}

I am running into 2 issues.

1.) I need it to only display each category once, rather than listing the category for each item instance.

2.) It is displaying all ProgramTitle, rather than just the the the ProgramTitle for that loop.

Not sure what the syntax I should be using is.

like image 680
user547794 Avatar asked Jul 03 '12 18:07

user547794


2 Answers

If I understand correctly then it should be like

@foreach (var item in Model) { 
  <h2>@Html.DisplayFor(modelItem => item.ProgramType.ProgramType)</h2> 
  foreach (var listing in item.SurveyResponseModels) 
  { 
     <ul> 
       <li>@Html.DisplayFor(modelItem => listing.ProgramTitle)</li> 
     </ul> 
  } 
} 
like image 102
Kunal Ranglani Avatar answered Sep 21 '22 07:09

Kunal Ranglani


It looks like you need to group your enumeration by ProgramType in your controller. This will keep the view nice and clean.

IEnumerable<CMESurvey.Models.SurveyProgramModel> models = Foo(); //however you got them...
var grouped = models.GroupBy(s => s.ProgramType.ProgramType);
return View(grouped);

Then, your view is much simpler. (After you fix the type of your model).

@for(int i = 0; i < Model.Count; i++)
{
    <h2>@Html.DisplayFor(model => model[i].Key)</h2>
    <ul> 
    for(int j = 0; j < Model[i].Count; j++)
    {
        <li>@Html.DisplayFor(model => model[i][j].ProgramTitle)</li>
    }
    </ul>
}

Alternative:

Or, you make a list of lists:

var models = Foo();
var grouped = models.GroupBy(s => s.ProgramType.ProgramType)
                    .Select(x => x.Select(y => y))
                    .ToList();
return View(grouped);

Then your view is slightly changed:

@for(int i = 0; i < Model.Count; i++)
{
    <h2>@Html.DisplayFor(model => model[i].First().ProgramType.ProgramType)</h2>
    <ul> 
    for(int j = 0; j < Model[i].Count; j++)
    {
        <li>@Html.DisplayFor(model => model[i][j].ProgramTitle)</li>
    }
    </ul>
}
like image 35
Andy_Vulhop Avatar answered Sep 20 '22 07:09

Andy_Vulhop