I have the following code defined below, what I am trying to do is get the total of the following properties (ItemsRequireingAttention, NumberOfUrgentItems).
Although Model.Count tells me how many view models I have in my view model, I want to be able to get the total count of the 2 aforementioned properties.
I've tried using Model.TotalCountFor and Model.Where but don't seem to be able to get them to work. My current code below, will only tell me the totals for the subset that is currently in view. Is this possible or am I going to have to look into using partials
PortalViewModel
public class PortalViewModel
{
public Vehicle Vehicle { get; set; }
public bool MotExpired { get; set; }
public bool TaxExpired { get; set; }
public bool MotWithin7Days { get; set; }
public bool TaxWithin7Days { get; set; }
public bool MotWithin30Days { get; set; }
public bool TaxWithin30Days { get; set; }
public bool MotNotRecorded { get; set; }
public bool TaxNotRecorded { get; set; }
public int NumberOfUrgentItems { get; set; }
public int ItemsRequireingAttention { get; set; }
}
PortalController
public class PortalController : Controller
{
public ActionResult Index(int? page)
{
var cookie = new HttpCookie("view", "admin");
var portalViewModel = new List<PortalViewModel>();
var vehicles = db.Vehicles.ToList();
foreach (var vehicle in vehicles)
{
var vm = new PortalViewModel { Vehicle = vehicle };
if (vehicle.MotDate == null)
{
vm.MotNotRecorded = true;
vm.NumberOfUrgentItems++;
}
if (vehicle.TaxDate == null)
{
vm.TaxNotRecorded = true;
vm.NumberOfUrgentItems++;
}
if (vehicle.MotDate <= DateTime.Now.AddYears(-1))
{
vm.MotExpired = true;
vm.NumberOfUrgentItems++;
}
if (vehicle.TaxDate != null && DateTime.Now.Subtract((DateTime)vehicle.TaxDate).Days >= 7)
{
vm.TaxWithin7Days = true;
}
else if (vehicle.TaxDate != null && DateTime.Now.Subtract((DateTime)vehicle.TaxDate).Days >= 30)
{
vm.TaxWithin30Days = true;
}
portalViewModel.Add(vm);
}
}
}
View
@using Microsoft.Ajax.Utilities
@using PagedList
@using PagedList.Mvc;
@using WebApplication1.ViewModels
@model IPagedList<PortalViewModel>
@{
ViewBag.Title = "Dashboard";
var pagedList = (IPagedList)Model;
var urgentItems = Model.Count(i => i.NumberOfUrgentItems >= 1); //(item => item.NumberOfUrgentItems >= 1);
int flaggedItems = Model.Count(i => i.ItemsRequireingAttention >= 1);
int vehicles = Model.Count();
}
<h2>Dashboard</h2>
<hr />
<div class="row">
@if (urgentItems != 0)
{
<div class="col-md-3 col-sm-6 col-xs-6">
<div class="panel panel-back noti-box">
<span class="icon-box bg-color-red set-icon">
<i class="fa fa-warning"></i>
</span>
<div class="text-box">
<p class="main-text">@urgentItems Items</p>
<p class="text-muted">Requiring immediate action</p>
</div>
</div>
</div>
}
@if (flaggedItems != 0)
{
<div class="col-md-3 col-sm-6 col-xs-6">
<div class="panel panel-back noti-box">
<span class="icon-box bg-color-green set-icon">
<i class="fa fa-exclamation"></i>
</span>
<div class="text-box">
<p class="main-text">@flaggedItems Items</p>
<p class="text-muted"><br />Require attention</p>
</div>
</div>
</div>
}
<div class="col-md-3 col-sm-6 col-xs-6">
<div class="panel panel-back noti-box">
<span class="icon-box bg-color-blue set-icon">
<i class="fa fa-truck"></i>
</span>
<div class="text-box">
<p class="main-text">@vehicles</p>
<p class="text-muted"><br />Vehicles in fleet</p>
</div>
</div>
</div>
</div>
<hr />
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="panel panel-default">
<div class="panel-heading text-center">
<strong>Current Fleet Details</strong>
</div>
<div class="panel-body">
<div class="table-responsive">
<div class="panel panel-primary">
<div class="panel-heading">
<h3 class="panel-title text-center">
<span class=" ">
Click on the reference number to edit vehicle details
</span>
<span class="pull-left"><i class="fa fa-info-circle"></i></span>
<span class="pull-right"><i class="fa fa-info-circle"></i></span>
</h3>
</div>
</div>
<table class="table table-striped table-bordered table-hover">
<thead>
<tr>
<th>@Html.DisplayNameFor(m => m.First().Vehicle.RefNumber)</th>
<th>@Html.DisplayNameFor(m => m.First().Vehicle.Make)</th>
<th>@Html.DisplayNameFor(m => m.First().Vehicle.Model)</th>
<th>@Html.DisplayNameFor(m => m.First().Vehicle.Registration)</th>
<th>@Html.DisplayName("Dates")</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr class='@if (item.MotNotRecorded || item.MotExpired || item.TaxNotRecorded || item.TaxExpired)
{
@Html.Raw("danger")
} else if (item.MotWithin30Days || item.MotWithin7Days || item.TaxWithin30Days || item.TaxWithin7Days)
{
@Html.Raw("warning")
}
else
{
@Html.Raw("success")
}'>
<td>
@if (!item.Vehicle.RefNumber.IsNullOrWhiteSpace() || !string.IsNullOrEmpty(item.Vehicle.RefNumber))
{
@Html.ActionLink(item.Vehicle.RefNumber, "Edit", "Portal", new { @ref = item.Vehicle.RefNumber }, null)
}
else
{
@item.Vehicle.RefNumber
}
</td>
<td>
@item.Vehicle.Make
</td>
<td>
@item.Vehicle.Model
</td>
<td>
@item.Vehicle.Registration
</td>
<td>
@Html.LabelFor(modelItem => item.Vehicle.MotDate):
@{
if (item.MotNotRecorded)
{
<span class="pull-right text-warning text-uppercase">
<i class="glyphicon glyphicon-warning-sign"></i>
@string.Format("Not yet recorded")
</span>
}
else
{
<span class="pull-right text-success">
@string.Format("{0:dd/MM/yyyy}", item.Vehicle.MotDate) <i class="glyphicon glyphicon-ok"></i>
</span>
}
}
<br />
@Html.LabelFor(modelItem => item.Vehicle.TaxDate)
@{
if (item.TaxNotRecorded)
{
<span class="pull-right text-warning text-uppercase">
<i class="glyphicon glyphicon-warning-sign"></i>
@string.Format("Not yet recorded")
</span>
}
else
{
<span class="pull-right text-success">
@string.Format("{0:dd/MM/yyyy}", item.Vehicle.TaxDate) <i class="glyphicon glyphicon-ok"></i>
</span>
}
}
</td>
</tr>
}
</tbody>
</table>
Page @(Model.PageCount < Model.PageNumber ? 0 : Model.PageNumber) of @Model.PageCount
@Html.PagedListPager(Model, page => Url.Action("Index", new { page }))
</div>
</div>
</div>
</div>
</div>
Your controller method is missing a return
statement, but I'm assuming that you are returning your portalViewModel
list.
I would recommend creating a ViewModel which has an IPagedList
of PortalViewModel
's and place the values you need in the containing ViewModel. Then you could use display templates in the view for each item.
However, you could also create two int
variables and increment them in your foreach
loop over the vehicles list, then put them into the ViewBag.
public ActionResult Index(int? page)
{
var cookie = new HttpCookie("view", "admin");
var portalViewModel = new List<PortalViewModel>();
var vehicles = db.Vehicles.ToList();
var totalNumberOfUrgentItems = 0; // first total
var totalNumberOfItemsRequireingAttention = 0; // second total
foreach (var vehicle in vehicles)
{
var vm = new PortalViewModel { Vehicle = vehicle };
if (vehicle.MotDate == null)
{
vm.MotNotRecorded = true;
vm.NumberOfUrgentItems++;
}
if (vehicle.TaxDate == null)
{
vm.TaxNotRecorded = true;
vm.NumberOfUrgentItems++;
}
if (vehicle.MotDate <= DateTime.Now.AddYears(-1))
{
vm.MotExpired = true;
vm.NumberOfUrgentItems++;
}
if (vehicle.TaxDate != null && DateTime.Now.Subtract((DateTime)vehicle.TaxDate).Days >= 7)
{
vm.TaxWithin7Days = true;
}
else if (vehicle.TaxDate != null && DateTime.Now.Subtract((DateTime)vehicle.TaxDate).Days >= 30)
{
vm.TaxWithin30Days = true;
}
totalNumberOfUrgentItems += vehicle.NumberOfUrgentItems;
totalNumberOfItemsRequireingAttention += vehicle.ItemsRequireingAttention;
portalViewModel.Add(vm);
}
ViewBag["TotalNumberOfUrgentItems"] = totalNumberOfUrgentItems;
ViewBag["TotalNumberOfItemsRequireingAttention"] = totalNumberOfItemsRequireingAttention;
// presumably your return statement is here
}