MVC problem creating table that iterates on view based on current week - c#

As of right now, I have a table on my view that looks like so:
The purpose of this table is to show a count of how many occurrences happened at each location (on the left) during the current week.
I have 3 tables in my database that I am using to create this table.
Table One
public partial class code_WeighLocation
{
public code_WeighLocation()
{
tbl_WeighAssc = new HashSet<tbl_WeighAssc>();
}
public int ID { get; set; }
[Required]
[StringLength(50)]
public string Weigh_Location { get; set; }
public bool Active { get; set; }
public virtual ICollection<tbl_WeighAssc> tbl_WeighAssc { get; set; }
}
Table Two - Association Table
public partial class tbl_WeighAssc
{
public int Id { get; set; }
public int WeighLocationId { get; set; }
public int TEUId { get; set; }
public int OccurenceCount { get; set; }
public virtual code_WeighLocation code_WeighLocation { get; set; }
public virtual tbl_TEUForm tbl_TEUForm { get; set; }
}
Table Three
public partial class tbl_TEUForm
{
public tbl_TEUForm()
{
tbl_TEUArrestAssc = new HashSet<tbl_TEUArrestAssc>();
tbl_WeighAssc = new HashSet<tbl_WeighAssc>();
tblTEUInspectionAsscs = new HashSet<tblTEUInspectionAssc>();
}
public int Id { get; set; }
public string PersonnelIBM { get; set; }
[Column(TypeName = "date")]
public DateTime EventDate { get; set; }
public bool Active { get; set; }
public virtual ICollection<tbl_TEUArrestAssc> tbl_TEUArrestAssc { get; set; }
public virtual tblPersonnel tblPersonnel { get; set; }
public virtual ICollection<tbl_WeighAssc> tbl_WeighAssc { get; set; }
public virtual ICollection<tblTEUInspectionAssc> tblTEUInspectionAsscs { get; set; }
}
Now, my view is taking in a viewmodel:
ViewModel
public class PersonnelDetailsVm
{
private static ConnectionStringName db = new ConnectionStringName();
public PersonnelDetailsVm()
{
CurrentWeekDates = new List<DateTime>();
}
public string IBM { get; set; }
[Display(Name = "Name")]
public string UserName { get; set; }
[Display(Name = "TEU OT Rate")]
public string Teu_OT_Rate { get; set; }
[Display(Name = "MCSAP OT Rate")]
public string Mcsap_OT_Rate { get; set; }
[StringLength(10)]
public string Division { get; set; }
public bool Active { get; set; }
public List<DateTime> CurrentWeekDates { get; set; }
public List<tbl_WeighAssc> WeighAssociations { get; set; }
public List<code_WeighLocation> WeighLocations => db.code_WeighLocation.ToList();
}
In my view to create the table that I am showing above, my code looks like this:
<table class="table table-bordered table-hover mt-3">
<thead>
<tr>
<th></th>
#foreach (var date in Model.CurrentWeekDates)
{
<th>#date.ToString("ddd") <br /> #date.ToShortDateString()</th>
}
</tr>
</thead>
<tbody>
#foreach (var weighLocation in Model.WeighLocations)
{
<tr>
<td>#weighLocation.Weigh_Location</td>
</tr>
}
</tbody>
</table>
Now, in my database, in the association table I only have 2 records, and both records were entered on Friday, 9/7/2018. One record is for WIMS/SR-1 with an occurence count of 2. The other is for FIXED/Blackbird with an occurence count for 2. So, my goal is to show those counts under Fri 9/7/2018 in their respective rows/cells and every other cell be filled with a 0 because there aren't any other records in the association table for those locations during this current week.
Here is my controller code to show how I'm populating the days of the week and getting the correct records based off of those dates.
var startOfWeek = DateTime.Today.AddDays((int) CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek -
(int) DateTime.Today.DayOfWeek);
person.CurrentWeekDates = Enumerable.Range(0, 7).Select(i => startOfWeek.AddDays(i)).ToList();
var teuFormIds = db.tbl_TEUForm
.Where(x => person.CurrentWeekDates.Contains(x.EventDate) && x.PersonnelIBM == person.IBM).Select(t => t.Id).ToList();
person.WeighAssociations = db.tbl_WeighAssc.Where(x => teuFormIds.Contains(x.TEUId)).ToList();
Any help is appreciated

I am not sure if I get this right, but I guess what you need is this,
for each time you are looping your locations, you should loop your dates again, and then do count or sum occurencecount (depending on your system design I didn't get it) and display it.
You don't need to worry about the cell order because you are looping the same days always so they will align first col is always the first day and so on.
also please double check the conditions I used, I am not sure if it is correct, but anyway this is the approach.
<!-- Loop through locations -->
#foreach (var weighLocation in Model.WeighLocations)
{
<tr>
<td>#weighLocation.Weigh_Location</td>
<!-- loop through current days week days for each location-->
#foreach(var currentDay in Model.CurrentWeekDates)
{
<!-- Here you count the rows or maybe sum the OccurenceCount I am not sure how you design it, I used count but you can use sum OccurenceCount -->
<td>
<!-- Compare the location id and the teuForm date -->
#Model.WeighAssociations.Where(e => e.WeighLocationId == weighLocation.Id && e.tbl_TEUForm.EventDate == currentDay).Count()
</td>
}
</tr>
}

I have figured this out.
In my view I edited the table tbody code to this:
<tbody>
#foreach (var weighLocation in Model.WeighLocations)
{
<tr>
<td>#weighLocation.Weigh_Location</td>
#foreach (var date in Model.CurrentWeekDates)
{
if (Model.WeighAssociations.Any(x => x.tbl_TEUForm.EventDate == date && x.WeighLocationId == weighLocation.ID))
{
<td>#Model.WeighAssociations.Single(x => x.tbl_TEUForm.EventDate == date && x.WeighLocationId == weighLocation.ID).OccurenceCount</td>
}
else
{
<td>0</td>
}
}
</tr>
}
</tbody>

Related

Dynamic Table in Blazor horzontal data braked on group id

I need a dynamic table in balzor basically it will have a serious of columns A-B B-C and within those columns will lie a series of numbers for example
This is the data from the locker table
ID
ItemID
IsRented
GroupId
1
10001
False
1
2
10002
True
1
3
10003
False
1
4
10004
True
1
5
20005
False
2
6
20006
True
2
7
20097
False
2
Locker Defination
public class Locker
{
public int Id { get; set; }
public int? LockerId { get; set; }
public int? GroupId { get; set; }
public string? RowId { get; set; }
public string? Name { get; set; }
public int? Size { get; set; }
public bool? IsRented { get; set; }
public string? Description { get; set; }
public int? BookingId { get; set; }
public int? Book { get; set; }
public bool? IsActive { get; set; }
public bool? IsDeleted { get; set; }
public bool? IsModified { get; set; }
public string? CreatedBy { get; set; }
public string? LastModifiedBy { get; set; }
public DateTime? LastModifiedDate { get; set; }
}
Where it would print a table with
This is table I want produced?.
ID
A - B
B - C
1
10001
20001
2
10002
20002
A - Z Along the top then the groups along the rows but the group id is how I no it should change to a differnt column ie 1000s should be in column a 2000s should be in column b.
What I have tried so far in blazor is
Html Markup
<table>
<thead>
<tr>
#foreach (var item in headings)
{
<th>item</th>
}
</tr>
</thead>
<tbody>
<tr>
#foreach(var item in Elements)
{
#if(item.IsRented==true)
{
<td style="color:red"> </td>
}else
{
<td style="color:green"> #item.LockerId</td>
}
}
</tr>
</tbody>
The above table gets it data from the web service below but as you see above would print out all the elments for each A ,B ,C D but I dont want that is there a way to use the group id effencitally here.
#code {
public List<Locker> Elements { get; set; }
private bool _readOnly;
string[] headings = { "A", "B", "C", "D", "E", "F" ,"G","H"};
private Func<Locker, string> _cellStyleFunc => x =>
{
string style = "";
if (x.IsRented == false)
style += "background-color:#00FF00";
else
style += "background-color:#FF0000";
return style;
};
protected override async Task OnInitializedAsync()
{
Elements = new List<Locker>();
string url = Constants.BaseUrl + Constants.GetAllLockers;
var response = await httpClient.GetAsync(url);
if (response.IsSuccessStatusCode)
{
var byteArray = await response.Content.ReadAsByteArrayAsync();
var content = Encoding.UTF8.GetString(byteArray, 0, byteArray.Length);
Elements = JsonConvert.DeserializeObject<List<Locker>>(content);
}
}
}
My Linq to get all the items.
public IEnumerable<Locker> GetAll()
{
return _context.Lockers.Where(w=> w.IsActive==true &&
w.IsDeleted == false).AsEnumerable();
}

How to display value by selecting from model in the controller ASP MVC

I want to display a name in the razor page by select it from a model and pass it through Viewbag in the controller.
Controller
public IActionResult sheet()
{
var tp1 = _db.Topic.Where(t => t.sheet_id == 1).ToList();
var tp1name = tp1.Select(t => t.topic1name);
ViewBag.tp1name = tp1name;
return View();
}
Model
public class Topic
{
[Key]
public int topic_id { get; set; }
[Required]
public int sheet_id { get; set; }
[Required]
public string topic1name { get; set; }
[Required]
public string topic2name { get; set; }
}
public class Transaction
{
[Key]
public int id { get; set; }
[Required]
public int sheet_id { get; set; }
[Required]
public string topic1score { get; set; }
}
View page
#model transaction
<table class="table">
<tr>
<td rowspan="2">1</td>
<td rowspan="2">#ViewBag.tp1name</td>
<td rowspan="2">30</td>
<td>Below average</td>
<td>Average</td>
<td>Above average</td>
</tr>
It returns
System.Linq.Enumerable+SelectListIterator`2[UserLoginApp.Models.Topic,System.String] in the view page instead of topic1name
tp1 is a list of topics.
so when you do a select it creates a new Enumerable en for each item in tp1 it selects the value of topic1name.
Thus creating an Enumerable+SelectListIterator
I think you want the value of one item:
var tp1 = _db.Topic.FirstOrDefault(t => t.sheet_id == 1)
if(tp1 != null)
ViewBag.tp1name = tp1.topic1name;

How do you reference a foreign key from a razor view page?

New to .net core here and I am going through razor tutorials and trying to add my own things to it. I have two tables: Order and Stock. I can list all Orders or all stocks, but when I want to list all Orders, I want to display the stock name (not the stockID) in the view page (near end of code). How do you reference the foreign key 'stockID' from the view page? Here is my code:
public class OrderModel
{
public int Id { get; set; }
public string OrderName { get; set; }
public DateTime OrderDate { get; set; } = DateTime.UtcNow;
public int Quantity { get; set; }
public decimal StockUnitCost { get; set; }
public decimal StockTotalCost { get; set; }
public decimal WinLoseAmt { get; set; }
public int StockId { get; set; }
}
public class StockModel
{
public int Id { get; set; }
public string StockName { get; set; }
public string StockTicker { get; set; }
public string StockType { get; set; }
public string Sector { get; set; }
}
public class OrderDisplayModel : PageModel
{
private readonly IOrderData _orderData;
private readonly IStockData _stockData;
public OrderModel Order { get; set; }
public List<OrderModel> orderList { get; set; }
public OrderDisplayModel(IOrderData orderData, IStockData stockData)
{
_orderData = orderData;
_stockData = stockData;
}
public async Task OnGet()
{
orderList = await _orderData.GetOrder();
}
}
<h1>My Orders</h1>
<table class="'table table-striped">
<thead class="thead-dark">
<tr>
<th>Order Name</th>
<th>Stock</th>
<th>Quantity</th>
<th>Cost Basis</th>
<th>Total Cost</th>
<th>Open Mkt Gain</th>
<th>Order Date</th>
</tr>
</thead>
<tbody>
#foreach (var order in Model.orderList)
{
<tr>
<td>#order.OrderName</td>
<td>#Model.StockPurchased</td>
<td>#order.StockId</td>
<td>#order.Quantity</td>
<td>#order.StockUnitCost</td>
<td>#order.StockTotalCost</td>
<td>#order.WinLoseAmt</td>
<td>#order.OrderDate</td>
</tr>
}
</tbody>
</table>
Thanks!
Create a virtual property and make it ForeignKey (and InverseProperty if you want to have another virtual collection property from Stock to Orders).
Something like this
....
public int StockId { get; set; }
[ForeignKey(nameof(StockId))]
[InverseProperty("Orders")]
public virtual Stock Stock { get; set; }
Then, you can either .Include(s=>s.Stock) in you context call and access it like order.Stock.StockName. Or setup Lazy loading (which requires a a bit more work in recent .NET core versions) and you access it without needing to Inclue it.

Listing all Items under a Category C# MVC

I would like some direction on how to be able to list all the items under a certain category in a view. I have already searched around and can't find anything, If someone know of any other posts or articles please point me there. Other wise here is my model...
public class Category
{
[Key]
public int ID { get; set; }
[Display(Name = "Category")]
public string Name { get; set; }
public virtual ICollection<MenuItem> MenuItem { get; set; }
}
public class MenuItem
{
[Key]
public int ID { get; set; }
public string Name { get; set; }
[DataType(DataType.MultilineText)]
public string Description { get; set; }
public string Image { get; set; }
public int CategoryID { get; set; }
public virtual Category Category { get; set; }
}
Thanks for any help anyone can provide.
assuming your category is set at the model
#foreach(var item in Model.MenuItem)
{
#Html.HiddenFor(x => item.ID)
<div>#Html.DisplayFor(x => item.Name)</div>
// carry on with other properties / markup
}
Say you want to loop over the MenuItem property in the Category model, in your view you'd have something like this:
At the top of the View, you'd have this:
#model Category
#foreach (var item in Model.MenuItem)
{
<tr id="menu-item">
<td>#id</td>
<td>#Name</td>
<td>#Description</td>
<td>#Image</td>
</tr>
}
#foreach (var item in Model.MenuItem)
{
<tr>
<td>#Name</td>
<td>#Description</td>
</tr>
{

C# reflection use variable as object.[var]

I'm trying to generate a table in a razor view using reflection to pull the properties from the model.
Here is what I've tried:
#if (#Model.Count() > 0)
{
System.Reflection.PropertyInfo[] properties = Model.First().GetType().GetProperties();
<table>
<thead>
<tr>
#foreach (var property in properties)
{
if (char.IsLower(property.Name.ToCharArray()[0])) //ignore foreign keys
{
continue;
}
<th>#property.Name</th>
}
</tr>
</thead>
<tbody>
#foreach (PCNWeb.Models.Switch item in Model)
{
/*System.Reflection.PropertyInfo[]*/ properties = item.GetType().GetProperties();
<tr>
#foreach (var property in properties)
{
<td>
#Html.DisplayFor(modelItem => item.[property.Name])
</td>
}
</tr>
}
</tbody>
</table>
}
Let me point out the part of the code that I'm not sure what to do with:
<td>
#Html.DisplayFor(modelItem => item.[property.Name])
</td>
The property.Name contains the name of the property of item that I want to access.
If I were to hand write the innermost td one example would be:
<td>
#Html.DisplayFor(modelItem => item.Switch_Location)
</td>
where "Switch_Location" is the value of property.Name
So basically I need to access the value of a property of item based on the name of the property stored in a variable.
EDIT adding model:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace PCNWeb.Models
{
public partial class Switch
{
public Switch()
{
this.Ports = new List<Port>();
this.Switch_Location = new Switch_Location();
this.Switch_Model = new Switch_Model();
this.UPS = new UPS();
}
[Key]
public int switchRecId { get; set; }
[Required]
public int locationRecId { get; set; }
[Required]
public int modelRecId { get; set; }
//public int gatewayRecId { get; set; }
[Required]
public int upsRecId { get; set; }
[Required]
public int Number { get; set; }
[Required]
[StringLength(64)]
public string Name { get; set; }
[StringLength(80)]
public string Description { get; set; }
[StringLength(32)]
public string Cabinet { get; set; }
[StringLength(40)]
public string Power_Feed { get; set; }
[Required]
public Nullable<int> ipOctet1 { get; set; }
[Required]
public Nullable<int> ipOctet2 { get; set; }
[Required]
public Nullable<int> ipOctet3 { get; set; }
[Required]
public Nullable<int> ipOctet4 { get; set; }
public virtual ICollection<Port> Ports { get; set; }
public virtual Switch_Location Switch_Location { get; set; }
public virtual Switch_Model Switch_Model { get; set; }
public virtual UPS UPS { get; set; }
}
}
So basically I need to access the value of a property of item based on the name of the property stored in a variable.
No, you need to access the value of a property based on a PropertyInfo object describing it. That's far far easier.
property.GetValue(item)
If you dont really need the DisplayFor method, you can do it like this in your loop:
<tbody>
#foreach (PCNWeb.Models.Switch item in Model)
{
/*System.Reflection.PropertyInfo[]*/ properties = item.GetType().GetProperties();
<tr>
#foreach (var property in properties)
{
<td>
#property.GetValue(item,null)
</td>
}
</tr>
}
</tbody>

Categories

Resources