MVC Editor Templates Using LINQ Group By?

I'm currently replacing a View containing a useless foreach/foreach style code. I need to edit the page now, so changes must be made. I have part of the solution (thanks to EE and much hair pulling), and now the Group-by-date is needed.

Notes:
   1. the Action doesn't have a Group By yet.
   2. the View has some code as comment-out


Here is the current view return displaying two budget months in the same year:

10/2013
October
Category       Limit
Auto             50       
Clothing       40       
College       100       
Credit             100       
Food             200       
     Save Changes

11/2013
November
Category       Limit
Auto             50       
Clothing       40       
College       100       
Credit             100       
Food             200       
     Save Changes

[View]
@model BudgetProjectUI.BudgetViewModelTest

@*@foreach (var group in Model)
{
    *@<div style="float: left;">

@*        @Model.Date.ToString("MM/yyyy")*@

        @using (Html.BeginForm("_Edit", "Budget", FormMethod.Post))
        {
            @Html.ValidationSummary(false)

            <fieldset>
                <legend>Month/Year </legend>
                <table>
                    <thead>
                        <tr>
                            <td><b>Category</b></td>
                            <td></td>
                            <td><b>Limit</b></td>
                        </tr>
                    </thead>
                    <tbody>

                        @Html.EditorFor(model => model.budgetList)

                    </tbody>
                </table>
            </fieldset>  
                                               
            <input type="submit" value="Save Changes" />                                
        }
    </div>
@*}*@

[New Editor Template to return the 'Category' and 'Limit' columns]
@model BudgetProjectUI.BudgetList

<table>
    <tr>
        <td style="width:150px">@Model.Name</td>
        <td></td>
        <td></td>
        <td><div style="width:50px">@Html.EditorFor(x => x.Limit)</div></td>
    </tr>
</table>

Open in new window


[Models]
public class BudgetViewModelTest
    {
        public System.DateTime Date { get; set; } //moved Date here for group by?
        public List<BudgetList> budgetList { get; set; }       
    }

    public class BudgetList
    {
        public string Name { get; set; }
        public System.Guid BudgetID { get; set; }
        public System.Guid BudgetItemID { get; set; }
        public System.Guid CategoryID { get; set; }
        public decimal Limit { get; set; }
        //public System.DateTime Date { get; set; }
        public System.DateTime Posted { get; set; }
    }

Open in new window


[Action]
       public ActionResult BudgetEditorTesting()
       {
            BudgetViewModelTest model = new BudgetViewModelTest
            { 
                budgetList = (from b in context.Budgets
                              join r in context.CategoryRefs on b.CategoryID equals r.CategoryID
                              select new BudgetList() { Name =  r.Name, Limit = b.Limit }).ToList()
            };

            return View(model);          
        }

Open in new window

WorknHardrAsked:
Who is Participating?
 
Bob LearnedConnect With a Mentor Commented:
I use MvcSiteMapProvider from here:

http://www.nuget.org/packages/MvcSiteMapProvider/

Here are a couple of the included display templates for breadcrumbs:

SiteMapNodeModelList

@model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModelList
@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models

<ul>
    @foreach (var node in Model) { 
        <li>@Html.DisplayFor(m => node) 
            @if (node.Children.Any()) {
                @Html.DisplayFor(m => node.Children)
            }
        </li>
    }
</ul>

Open in new window


SiteMapNodeModel

@model MvcSiteMapProvider.Web.Html.Models.SiteMapNodeModel

@using System.Web.Mvc.Html
@using MvcSiteMapProvider.Web.Html.Models

@if (Model.IsCurrentNode && Model.SourceMetadata["HtmlHelper"].ToString() != "MvcSiteMapProvider.Web.Html.MenuHelper")  { 
    <li><a>@Model.Title</a></li>
}
else if (Model.IsClickable)
{ 
    <li><a href="@Model.Url ">@Model.Title</a></li>
} else { 
    <li>@Model.Title</li>
}

Open in new window


Note the @Html.DisplayFor(m => node), which binds the SiteMapNodeModel for each entry in the list.
0
 
Bob LearnedCommented:
I am not sure that I understand what you are looking for...

Did you want to do a group by in the LINQ query?
0
 
WorknHardrAuthor Commented:
I should backup a bit and show my current working code which needs both 'foreach' statements replaced with Editor Templates.

Q. Can I use my current LINQ to load new Editor Templates?
Q. If not, how do I do it?
Q. I'm assuming I need 'nested' Editor Templates (many parents to many children)?

[LINQ]
 var model = (from b in context.Budgets
                           join r in context.CategoryRefs on b.CategoryID equals r.CategoryID
                           let j = new BudgetViewModel { categoryRef = r, budget = b }
                           group j by j.budget.Date into g
                           select new Group<DateTime, BudgetViewModel> { Key = g.Key, Values = g.OrderBy(s => s.categoryRef.Name) }).ToList();

Open in new window


[View]
@using BudgetProjectUI
@model List<Group<DateTime, BudgetViewModel>>

 @foreach (var group in Model)
{
     <div  style="float: left;">

     @group.Key.ToString("MM/yyyy")

    @using (Html.BeginForm("_Edit", "Budget", FormMethod.Post))
   {
       <fieldset>
         <legend> @group.Key.ToString("MMMM") </legend>
            <table>
              <thead>
                 <tr>
                   <td><b>Category</b></td>
                   <td></td>
                   <td><b>Limit</b></td>                                        
                 </tr>
               </thead>
          <tbody>
            @foreach (var item in group.Values)
            {
            <tr>
              <td>           
                @Html.Hidden("BudgetID", item.budget.BudgetID)
                @Html.Hidden("CategoryID", item.categoryRef.CategoryID)
                @Html.Hidden("Posted", item.budget.Posted)
                @Html.Label(item.categoryRef.Name)
             </td> 
             <td>@Html.Label(item.budget.Limit.ToString("c")</td>                                            
           </tr>             
           }
          </tbody>
        </table>
     </fieldset>                                                  
                        <input type="submit" value="Save Changes" />
                </div>
            }

Open in new window

0
Cloud Class® Course: Ruby Fundamentals

This course will introduce you to Ruby, as well as teach you about classes, methods, variables, data structures, loops, enumerable methods, and finishing touches.

 
Bob LearnedCommented:
Hmmm...

ASP.NET MVC 3 – How to use EditorTemplates
http://coding-in.net/asp-net-mvc-3-how-to-use-editortemplates/

I Love the syntax. There is no loop in the view. The EditorTemplate does all the job for us. Thanks ASP.NET MVC !

@Html.EditorFor(model => model.Addresses)

Open in new window

0
 
WorknHardrAuthor Commented:
I've read multiple posts and articles which in my opinion are incomplete teasers. I posted all my code and don't know what else to do.

Yeah, I  read that one too, here's what it lacks:
    1. No LINQ query for EF
        - only hard-coded data
    2. Only has Addresses list
        - I need multiple parents list and children lists

I've built simple Editor Templates, but never this complex. I think maybe two Templates are needed, one for the Parent which calls the children list.
0
 
WorknHardrAuthor Commented:
Thx
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.