BlueBird
BlueBird

Reputation: 1466

Group by Month in a MVC Razor view

I have a mvc razor view that has a model populated like so:

public class HomeController : Controller
    {

        private IDataSource _db;

        public HomeController (IDataSource db)
        {
            _db = db;
        }


        public ActionResult Events()
        {
            var allevents = _db.Events;
            ViewBag.Title = "Events";
            return View(allevents);
        }


    }

The event model looks like this:

 public class Event
    {
        public virtual int Id { get; set; }
        public virtual string Title { get; set; }
        public virtual string Description { get; set; }
        public virtual Location Location {get;set;}
        public virtual DateTime StartDate {get;set;}
        public virtual DateTime EndDate { get; set; }
    }

I would like to display the items in my view so that they are grouped by the month name. For example:

October

EventA Title, EventA Description etc.

EventB Title, EventA Description etc.

November

EventC Title, EventC Description etc.

If possible you could take it a step further to break it out by year, then month however not entirely necessary as I don't see a situation where events would be entered more than a year in advance.

I have tried this in my razor view but seem to be slightly off...

@{var monthList = from e in Model
group e by e.StartDate.Month into g
orderby g.Key
select g;

foreach(var monthGroup in monthList)
{

    string month = monthGroup.Key.ToString();
<h2 class="h4 pi-weight-700 pi-uppercase pi-has-bg pi-margin-bottom-25">
    @month
</h2>
    foreach (Model e in monthGroup)
    {
        // do something with the events
    }
}}

Upvotes: 1

Views: 8054

Answers (1)

rashleighp
rashleighp

Reputation: 1226

Assuming start date and end date are in the same month I would do something like (in controller):

var groupedEvents = _db.Events.ToList().GroupBy(k => new DateTime(k.StartDate.Year, k.StartDate.Month, 1)).OrderBy(k => k.Key).ToDictionary(k => k.Key, v => v.ToList());
return View(groupedEvents);

Then in the view foreach through the dictionary. You can get the month name by:

@model IDictionary<DateTime, List<Event>>
@foreach(var item in Model)
{
     //Display month name
     <h1>@item.Key.ToString("MMM", CultureInfo.InvariantCulture);</h1>
     foreach(var ev in item.Value)
     {
         //Row specific code
     }
}

Upvotes: 4

Related Questions