Add count/sub-count to mvc view - asp.net-mvc

I've got a view that is showing the breakdown of all fault categories reported and the area that they've been reported in. What I need to get is a total count of the number of faults of each category, and then a sub count of each area under that type. I've seen around that there are options to use Model.Count(), however whenever I try that it doesn't return the right number.
The view code that I'm using is below:
<table class="table table-responsive">
<tr>
#foreach (var catGroup in Model.GroupBy(item => item.job_category))
{
foreach (var itemCat in catGroup.Take(1))
{
if (itemCat.job_category != null)
{
<td>
<table id="Tbl_Total_#itemCat.job_category">
<tr>
<th>
#Html.DisplayFor(modelItem => itemCat.job_category)
</th>
</tr>
#foreach (var item in catGroup.GroupBy(item => item.job_area))
{
foreach (var itemArea in item.Take(1))
{
<tr>
<td>
#Html.DisplayFor(modelItem => itemArea.job_area)
</td>
</tr>
}
}
</table>
</td>
}
}
}
</tr>
</table>
Can someone point me in the right direction to get a count per category, and per area under the categories?
Thanks

You can get the number of element per group calling Count extension method. eg, for the category groups you can do this:
catGroup.Count()
And you can do the same for the areas:
item.Count()

Related

How do I change Table view of products into Side By Side View, like online shopping products list with HTML5 and CSS3 in MVC Razor page?

I am trying to create a list of movies where the data is coming from the database table. So I need to create the Side By Side view of products using #foreach(){ .... }. Please someone review my code below and help me get through this step.
I want my products as (using #foreach item):
Product 1 Product 2 Product 3
Product 4 Product 5 Product 6
I tried to do
#foreach(var i=0; i< Model.Count; i+=2)
{
}
but didn't work maybe because of my images, which are coming from db as Imagepath.
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.MoviesName)
</th>
<th>
#Html.DisplayNameFor(model => model.ImgPath)
</th>
<th>
#Html.DisplayNameFor(model => model.ReYear)
</th>
<th>
#Html.DisplayNameFor(model => model.UnitPrice)
</th>
</tr>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.MoviesName)
</td>
<td>
<img src="#Url.Content("~/Image/" +
System.IO.Path.GetFileName(item.ImgPath))" alt=""
width="75" , height="100" />
</td>
<td>
#Html.DisplayFor(modelItem => item.ReYear)
</td>
<td>
#String.Format("{0:c}", item.UnitPrice)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id = item.MovieID
}) |
#Html.ActionLink("Details", "Details", new { id =
item.MovieID
}) |
#Html.ActionLink("Delete", "Delete", new { id =
item.MovieID
})
</td>
</tr>
}
</table>
To build a side-by-side layout, you'll need to choose either a <div> based or a <table> based layout.
<div> based is easiest as you can use a #foreach loop to build a <div>-based, side-by-side layout easily. For example, here's a super simple way of doing it using Bootstrap 4:
<div class="row">
#foreach (var item in Model)
{
<div class="col-4">...Build your product in here...</div>
}
</div>
Or...you can make your layout using a <table>, but this is more complex; you'll need to use nested loops and a bit of math to get the rows and columns right. Here's one way to achieve this:
First, figure out how many rows there'll be based on Model.Count products:
#{
int columns = 3;
int rows = (int)Math.Ceiling(Model.Count / (float)columns);
}
Next, setup nested loops similar to this:
<table>
#for (int row = 0; row < rows; ++row)
{
<tr>
#for (int column = 1; column <= columns; ++column)
{
#if ((row * columns) + column <= Model.Count)
{
<td>...Build your product in here...</td>
}
else
{
break;
}
}
</tr>
}
</table>

MVC View change specified row bgcolor

In my MVC view, I am displaying list of data from my model in a table as shown below. How to make a specified row to change color when one of the field satisfy certain condition within my if-else statement? It does not seems like I can add a jquery inside my if-else there for the purpose...
My View:
...
<table>
...
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.field1)
</td>
<td>
#Html.DisplayFor(modelItem => item.field2)
</td>
<td>
#if(item.field3== 0){
//change this row to grey color
}
else {
#Html.DisplayFor(modelItem => item.field3)
}
</td>
....
</table>
You just need to do it up where you are outputting the row. One way would be:
<table>
...
#foreach (var item in Model) {
<tr style='background-color: #(item.field3 == 0 ? "gray" : "white");'>
<td>
#Html.DisplayFor(modelItem => item.field1)
</td>
<td>
#Html.DisplayFor(modelItem => item.field2)
</td>
<td>
#Html.DisplayFor(modelItem => item.field3)
</td>
}
....
</table>
There are all sorts of ways to construct that conditional, just depends on your scenario. But the key is that you can access the field3 property of the item object anywhere in that foreach loop, just like a normal C# foreach

How to handle errors in Razor view engine?

How to handle errors in Razor (i.e. Null Exception)other than (try/catch)?
I do not want to insert (try/catch) block in every razor block.
Example (The (Model.ListofEntity) or (Item.Values) may be null and an exception might occur):
<table class="table">
<tr>
<th>
<div id="chkCheckAll" class="divCheckbox">
</div>
</th>
#foreach (var column in Model.ListofEntity.Columns)
{
int t = Convert.ToInt32(" ");
<th>
#column
</th>
}
</tr>
#foreach (CVMEntities.Item Item in Model.ListofEntity.Items)
{
<tr>
<td>
<div id=#Item.ID class="divCheckbox">
</div>
</td>
#foreach (var Value in Item.Values)
{
<td>
#Value
</td>
}
</tr>
}
</table>

Slow view building

I am in the process of converting an old asp.net forms application to MVC. I have run into a snag where I am displaying results of a search.
I have an entity framework model of Classes, Class Details, Rosters and Class instructors.
I have a search page where I wish to display all of the class details by class selected.
View:
#using System.Diagnostics
#model IEnumerable<SafetyReports.Models.DataModel.ClassDetails>
<div>
<table>
<tr>
<th>
Class Date
</th>
<th>
Location
</th>
<th>
Region
</th>
<th>
# of Attendees
</th>
</tr>
#foreach (var c in Model)
{
Debug.WriteLine(c.ClassDetailID);
<tr>
<td>
#c.ClassDate
</td>
<td>
#c.Location
</td>
<td>
#c.Region
</td>
<td>
#c.ClassRosters.Count
</td>
<td>
<input type="button" value="Detail" onclick="alert(#c.ClassDetailID)"/>
</td>
</tr>
}
</table>
</div>
controller:
public PartialViewResult SelectCourse(string id)
{
var e = new Entities();
var i = e.ClassDetails.Where(x => x.ClassID.ToString() == id).ToList();
return PartialView("_ClassesDetail", i);
}
My problem is that it seem to take about 1 second per 2-3 classes. I have one class type that has 1300 records and it takes about 5-6 minutes to return the view. What am I doing wrong? In the asp.net forms application I have a gridview that returns the same amount of data in seconds if that long. It isnt using EF though, just a sqldatasource. Could this be lazy loading?
firstly, as seen before using a int instead of a string for 'id' will speed up your EF query.
Here's one way to speed up the view rendering (or at least make it cleaner):
In view replace all the #foreach loop by a simple :
//here Razor will automatically repeat you model displayTemplate for
//each element of your IEnumerable
#Html.DisplayForModel()
And then define a Display Template for your model
~/Views/Shared/DisplayTemplates/ClassDetails.cshtml
#model SafetyReports.Models.DataModel.ClassDetails
<tr>
<td>
#Model.ClassDate
</td>
<td>
#Model.Location
</td>
<td>
#Model.Region
</td>
<td>
#Model.ClassRosters.Count
</td>
<td>
<input type="button" value="Detail" onclick="alert(#Model.ClassDetailID)"/>
</td>
</tr>
I found my issue, I had related objects being lazy loaded, I fixed the issue with including those objects with:
var i = e.ClassDetails.Where(x => x.ClassID == id).Include(x=>x.ClassInstructors).Include(x=>x.ClassRosters).ToList();

Insert "where" rule in a "foreach" search

I need some help in order to put a where rule into the foreach search. My goal is to exclude orders where the customerOrder.ERPOrderNumber starts with letter E
The code that i have returns all the orders for the specific customer.
Thank you in advance for your help.
#foreach (var customerOrder in Model.CustomerOrders)
{
<tr>
<td class="mavo-order-date">#customerOrder.OrderDate.ToShortDateString()
</td>
<td class="mavo-status">#customerOrder.Status
</td>
<td class="mavo-order-number">
#customerOrder.OrderNumber
</td>
#if (Model.ShowErpOrderNumber)
{
<td class="mavo-erp-order">#customerOrder.ERPOrderNumber
</td>
}
<td class="mavo-po">#customerOrder.CustomerPO
</td>
<td class="mavo-order-total">#customerOrder.OrderGrandTotal.ToCurrency()
</td>
<td class="mavo-view">
<a class="btn btnStyleA tbm5" href="#Url.Action("OrderHistoryDetail", "Account", new { orderId = customerOrder.ERPOrderNumber })">View Details</a>
</td>
</tr>
}
You can put an if statement inside the foreach loop to only write out the table row when the order number doesn't start with the letter E.
#foreach (var customerOrder in Model.CustomerOrders)
{
#if(!customerOrder.ERPOrderNumber.StartsWith("E"))
{
// Markup goes in here
}
}
Or you can use LINQ to filter the CustomerOrders collection.
#foreach(var customerOrder in Model.CustomerOrders.Where(x => !x.StartsWith("E"))

Resources