Reputation: 6203
So the beginning of my View is
@foreach ( var G in ViewBag.GroupedBySec )
{
<div class="row">
<div class="col-xs-12 col-sm-12 col-md-12 col-lg-12">
<table class="table table-striped assessment-table">
<tbody>
<tr>
<td class="black-n-white" colspan="4">@G.Key</td>
</tr>
<tr>
<td>Section</td><td>Component</td><td>Completeness Level (0-100%)</td><td>Readines</td>
</tr>
@var GroupedBySubsection = G.GroupBy(x => x.SubsectionTitle);
@foreach ( var g in GroupedBySubsection )
{
@foreach ( var qa in g )
{
and I'm getting errors on the
@var GroupedBySubsection = G.GroupBy(x => x.SubsectionTitle);
@foreach ( var g in GroupedBySubsection )
lines which say
The name 'var' does not exist in the current context
and
The name 'GroupedBySection' does not exist in the current context
Any idea what I'm doing wrong?
Alternatively, any suggestions for how I can get a C# object that has the entire groupings and subgroupings so that I don't have to write all this crap in my View?
My Controller method for this page is like
[HttpGet]
public ActionResult Peek ( Guid pid )
{
ViewBag.PartnerId = pid;
List<AnswerInfo> AllAnswers = this._Db.GetAnswersByPartner(pid);
ViewBag.GroupedBySec = AllAnswers.GroupBy(A => A.SectionTitle);
return View();
}
Upvotes: 1
Views: 110
Reputation:
Your error occurs because you're missing the braces around your var
statement. It should be:
@{ var GroupedBySubsection = G.GroupBy(x => x.SubsectionTitle); }
This will then throw a different error because you referring an item in ViewBag
which is dynamic
so you need to cast it as follows
@{ var GroupedBySubsection = ((IEnumerable<yourModel>)G).GroupBy(x => x.SubsectionTitle); }
making your view even uglier.
how I can get a C# object that has the entire groupings and subgroupings so that I don't have to write all this crap in my View?
Use a view model. Based on some of your previous question, you have a data model which (abbreviated) is:
public class Answer
{
public string Section { get; set; }
public string SubSection { get; set; }
public int QuestionID { get; set; }
public string QuestionText { get; set; }
....
}
And you want to group it in the view by Section
and then SubSection
. Your view models would then be:
public class SectionVM
{
public string Title{ get; set; }
public List<SubSectionVM> SubSections { get; set; }
}
public class SubSectionVM
{
public string Title { get; set; }
public List<QuestionVM> Questions { get; set; }
}
public class QuestionVM
{
public int QuestionID { get; set; }
public string QuestionText { get; set; }
....
}
Your controller code would then be:
var answers = db.Answers..... // your previous query
List<SectionVM> model = answers.GroupBy(x => x.Section).Select(x => new SectionVM
{
Title = x.Key,
SubSections = x.GroupBy(y => y.SubSection).Select(y => new SubSectionVM
{
Title = y.Key,
Questions = y.Select(z => new QuestionVM
{
QuestionID = z.QuestionID,
QuestionText = z.QuestionText,
....
}).ToList()
}).ToList()
}).ToList();
return View(model);
and in the view
@model List<SectionVM>
@foreach(var section in Model)
{
<h2>@section.Title</h2>
foreach(var subSection in section.SubSections)
{
<h3>@subSection.Title</h3>
foreach(var question in subSection.Questions)
{
<p>@question.QuestionText</p>
....
}
}
}
Side note: I have made the collection properties List<T>
assuming that you might want to also generate a form for editing the Questions/Answers and to do so you will need a for
loop which required the collection to implement IList
. Alternatively you could save the extra overhead of .ToList(), keep them as
IEnumerableand use a custom
EditorTemplate` for each view model type.
For an example of how an edit view might look (using the for
loop option), refer to this answer.
Upvotes: 3