Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to order a list by property and group the elements in HTML Razor?

Maybe the question is hard to explain all but here is the problem I'm facing, I have a list of properties of a model

public class ViewModel
{
    public int PropertyID {get;set;}
    public DateTime Datefield {get;set}
    public string OtherProperty {get;set;}
}

Then I fill the list with some values:

List<ViewModel> listOfValues = new List<ViewModel>();
listOfValues.Add(new ViewModel{
    PropertyID = 1,
    Datefield = new DateTime(2010, 5,25, 12,00,00),
    OtherProperty = "Name1"
});

Imagine the Datefield has this values:

0: 25/05/2010 12:00:00
1: 25/05/2010 12:00:00
2: 26/05/2010 13:00:00
3: 26/05/2010 13:00:00
4: 26/05/2010 14:00:00
5: 27/05/2010 12:00:00

After that I order the list with simple listOfElements.OrderBy(o => o.Datefield).ThenBy(o => o.Datefield.Hour); to order the list first by date, and after the date the hour most recent.

Everything works fine but then one requirement is to "group" the elements by date and hour, but not with a GroupBy of LINQ, but with RAZOR in this way:

    <div>
        @Model.listOfElements[i].Datefield //0: 25/05/2010 12:00:00
        @Model.listOfElements[i].Datefield //1: 25/05/2010 12:00:00
    </div>

    <div>
        @Model.listOfElements[i].Datefield //2: 26/05/2010 13:00:00
        @Model.listOfElements[i].Datefield //3: 26/05/2010 13:00:00
    </div>

    <div>
        @Model.listOfElements[i].Datefield //4: 26/05/2010 14:00:00
    </div>

    <div>
        @Model.listOfElements[i].Datefield //5: 27/05/2010 12:00:00
    </div>

I wanted to group them by date and hour in the html so the ones that matches are, for example, in a div so I can give them style that they are kind of a group. I tried with some ugly razor-html syntax but I don't think it's the best way.

Hope the question is understandable.

like image 910
Jorge F Avatar asked May 28 '15 04:05

Jorge F


1 Answers

Assuming as per your code that Model.listOfElements contains the IEnumerable<ViewModel> given, what you can do is use Linq to Group the dates, and then each grouping will itself contain a list of items in that date group. In order to obtain the Date+Hour only grouping, use an anonymous projection in the Grouping to just consider the Date and Hour in the Grouping

@foreach (var grp in Model.listOfElements 
    .OrderBy(m => m.PropertyID)
    .GroupBy(m => string.Format("{0:yyyyMMddHH}", m.Datefield)))
{
    <div>
        @foreach (var itm in grp)
        {
            <p>@itm.PropertyID - @itm.Datefield</p>
        }
    </div>
}

The pre-ordering on PropertyID will pull through to the Groupings to give the order you've listed. I've added the PropertyId to the output just for demonstration - you can remove it once the ordering is confirmed.

like image 191
StuartLC Avatar answered Sep 23 '22 16:09

StuartLC