I'm creating banking application in MVC 5.
Load table by bank and Load table rows by Bank,
But I cannot figure out do this exactly like above image,
This what I'm getting , it has 10 tables, instead just 2 tables
this is cshtml code for above view
#model IEnumerable<albaraka.Models.ProductApprovals>
#{
ViewBag.Title = "Product_Approvals";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>sadfasf</h2>
<h2>Product Approvals</h2>
#using (Html.BeginForm("Index", "Student", FormMethod.Get))
{
<div> Filter by : Date #Html.TextBox("SearchString", ViewBag.CurrentFilter as string) Filter by : Country #Html.TextBox("SearchString", ViewBag.CurrentFilter as string) <input type="submit" value="Search" /> </div>
}
#foreach (var item in Model)
{
#Html.DisplayNameFor(model => model.SubsidaryName); <p   /> #Html.DisplayFor(modelItem => item.SubsidaryName);
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.ProductNameEn)
</th>
<th>
#Html.DisplayNameFor(model => model.ProdcutNameAr)
</th>
<th>
#Html.DisplayNameFor(model => model.CurrentStatus)
</th>
<th>
Actions
</th>
</tr>
#foreach (var inside in Model)
{
if (inside.Subsidary_ID == item.Subsidary_ID)
{
<tr>
<td>
#Html.DisplayFor(modelItem => inside.ProductNameEn)
</td>
<td>
#Html.DisplayFor(modelItem => inside.ProdcutNameAr)
</td>
<td>
#Html.DisplayFor(modelItem => inside.CurrentStatus)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Details", "Details", new { /* id=item.PrimaryKey */ }) |
#Html.ActionLink("Delete", "Delete", new { /* id=item.PrimaryKey */ })
</td>
</tr>
}
}
</table>
}
This is Model class
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace albaraka.Models
{
public class ProductApprovals
{
public DateTime SearchDate { get; set; }
public string Country { get; set; }
public string Product_ID { get; set; }
public string Subsidary_ID { get; set; }
public string SubsidaryName { get; set; }
public string ProductNameEn { get; set; }
public string ProdcutNameAr { get; set; }
public string CurrentStatus { get; set; }
}
}
This is Controller class
public ActionResult Product_Approvals()
{
var productApproveResult =(from p in db.AB_Product
join s in db.AB_Subsidary on p.Subsidary_ID equals s.SubsidaryID
select new ProductApprovals
{
Product_ID = p.ProductID,
Subsidary_ID = s.SubsidaryID,
SubsidaryName = s.SubsidaryNameEn,
ProductNameEn = p.ProductTitleEn,
ProdcutNameAr = p.ProductTitleAr,
CurrentStatus = p.Status
}).ToList();
return View(productApproveResult);
}
How to stop this repeating ,appricate if can show a way to this in view page
You need a view model(s) to represent what you want to display in the view. It should be something like
public class BankVM
{
public string SubsidaryName { get; set; }
public IEnumerable<ProductVM> Products { get; set; }
}
public class ProductVM
{
public string ProductNameEn { get; set; }
public string ProdcutNameAr { get; set; }
public string CurrentStatus { get; set; }
}
and pass a collection of BankVM to the view
#model IEnumerable<yourAssembly.BankVM>
#foreach(var bank in Model)
{
<h3>#Html.DisplayFor(m => bank.SubsidaryName)</h3>
<table>
foreach(var product in bank.Products)
{
<tr>
<td>#Html.DisplayFor(m => product.ProductNameEn)</td>
<td>#Html.DisplayFor(m => product.ProductNameAr)</td>
....
</tr>
}
</table>
}
In the controller, you can use a Linq .GroupBy() method to populate your collection of BankVM
Related
I have Course and Student model with foreign key. I want to show student details in index view with CourseName and CourseId.
This is Course Model
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace JECRC.Models
{
public class Course
{
[Key]
public int CourseId { get; set; }
[Required]
public string CourseName { get; set; }
public List<Student> Students { get; set; }
public Faculty Faculty { get; set; }
}
}
This is Student Model
using System.ComponentModel.DataAnnotations;
namespace JECRC.Models
{
public class Student
{
[Key]
public int StudentId { get; set; }
[Required]
public string StudentName { get; set; }
[Required]
public string Class { get; set; }
public int CourseId { get; set; }
public Course Course { get; set; }
}
}
This is my Student Controller
using JECRC.Context;
using JECRC.Models;
using Microsoft.AspNetCore.Mvc;
namespace JECRC.Controllers
{
public class StudentController : Controller
{
private readonly DataContext dc;
public StudentController(DataContext dc)
{
this.dc = dc;
}
public IActionResult Index()
{
IEnumerable<Student> students = dc.Students;
return View(students);
}
}
}
and this is my Index View
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.StudentId)
</th>
<th>
#Html.DisplayNameFor(model => model.StudentName)
</th>
<th>
#Html.DisplayNameFor(model => model.Class)
</th>
#Html.DisplayNameFor(model => model.Course.CourseName)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.StudentId)
</td>
<td>
#Html.DisplayFor(modelItem => item.StudentName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Class)
</td>
<td>
#Html.DisplayFor(modelItem => item.Course.CourseName)
</td>
</tr>
}
</tbody>
</table>
I know I have to join these two table Student and Course in Student controller but i don't know how to do it, please help me to solve this problem,I will be very thank full for this.
I have standards views generated with scaffolding my model from Main table.
Now instead of standard Details view which shows details of single record based on Main table I want to show list (like in Index view) of all rows where this id appears in another table (called Audit table).
So when user clicks Details in Index view of Main table (model) it should get list of records from Audit table where that id appears.
Main table model:
public partial class Main
{
public int id{ get; set; }
public int SocID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string User { get; set; }
}
Audit table model:
public partial class Audit
{
public int idAudit{ get; set; }
public int id{ get; set; }
public int SocID { get; set; }
public string Name { get; set; }
public string Title { get; set; }
public string User { get; set; }
public string DateOfChange { get; set; }
public string Operation { get; set; }
}
So I've modified Details class in my Main model Controller to return all records from Audit table based on id from Main table in following way:
public IActionResult Details(int? id)
{
if (id == null)
{
return NotFound();
}
var Audit = (from c in _context.Audit
where c.id == id
select new Audit
{
SocID = c.SocID,
Name = c.Name,
Title = c.Title,
User = c.User,
DateOfChange = c.DateOfChange,
Operation = c.Operation
}).ToList();
if (Audit == null)
{
return NotFound();
}
return View(Audit);
}
And my View for Details class looks like this now:
#model IEnumerable<Audit>
#{
ViewData["Title"] = "Audit ....";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<div class="table-responsive tableFixHead">
<table class="table table-striped table-hover mx-auto w-auto" id="nkz10table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.SocID)
</th>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Title)
</th>
<th>
#Html.DisplayNameFor(model => model.User)
</th>
<th>
#Html.DisplayNameFor(model => model.DateOfChange)
</th>
<th>
#Html.DisplayNameFor(model => model.Operation)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.SocID)
</td>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Title)
</td>
<td>
#Html.DisplayFor(modelItem => item.User)
</td>
<td>
#Html.DisplayFor(modelItem => item.DateOfChange)
</td>
<td>
#Html.DisplayFor(modelItem => item.Operation)
</td>
</tr>
}
</tbody>
</table>
</div>
EDIT
In Index view I'm calling Details with:
#model IEnumerable<Audit>
....
<a asp-action="Details" asp-route-id="#item.id">Details</a>
when I click Details for specific id which has several records in Audit table I get
404 - page not found.
What am I doing wrong?
Problem was with definition of controller, here is what worked for me in the end:
public async Task<IActionResult> Details(int? id)
{
if (id == null)
{
return NotFound();
}
var audit= _context.audit
.Where(m => m.Nkz10Pk == id);
if (audit== null)
{
return NotFound();
}
return View(audit);
}
I have created a view which contains 2 tables.
What I want is to filter each table data according to their transaction type for example table1 should show only Payables List and table2 should show only Reciveable List.
here is the code
Note When I navigate to the view server shows me The resource cannot be found.other views are fine. here is my code.
My project has BOL(EF Model) BLL(Business object) DAL(Data Access layer) and my main Mvc project
View
#model shinwari_traders.Areas.Shinwari.Models.ADetailsVm
#{
ViewBag.Title = "Index";
}
<h2>AccountDetails</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table id="Payables" class="table">
<tr>
<th>
Date
</th>
<th>
Discription
</th>
<th>
Amount
</th>
</tr>
#foreach (var item in Model.Payables)
{
<tr>
<td>
#item.Date
</td>
<td>
#item.Discription
</td>
<td>
#item.Amount
</td>
</tr>
}
</table>
<table id="Reciveables" class="table">
<tr>
<th>
Date
</th>
<th>
Discription
</th>
<th>
Amount
</th>
</tr>
#foreach (var item in Model.Reciveables)
{
<tr>
<td>
#item.Date
</td>
<td>
#item.Discription
</td>
<td>
#item.Amount
</td>
</tr>
}
</table>
Controller
public class AccountDetailsController : Controller
{
private TransictionBs objbs;
public AccountDetailsController()
{
objbs = new TransictionBs(int accountid);
}
// GET: Shinwari/AccountDetails
public ActionResult Index(int accountid)
{ var v= new ADetails();
v.Payable = objbs.GetALL().Where(p => p.AId==accountid&& p.tbl_TransictionType.Type.Contains("Payable"));
v.Reciveable = objbs.GetALL().Where(r => r.AId==accountid && r.tbl_TransictionType.Type.Contains("Reciveable"));
return View(v);
}
}
}
Model Class
public class ADetailsVm
{
public List<BOL.tbl_Transiction> Payables { get; set; }
public List<BOL.tbl_Transiction> Reciveables { get; set; }
}
DatabaseTable
public partial class tbl_Transiction
{
public int TId { get; set; }
public Nullable<System.DateTime> Date { get; set; }
public Nullable<int> AId { get; set; }
public string Discription { get; set; }
public Nullable<double> PKR { get; set; }
public Nullable<double> Rate { get; set; }
public Nullable<double> Amount { get; set; }
public Nullable<int> TTId { get; set; }
public virtual tbl_Accounts tbl_Accounts { get; set; }
public virtual tbl_TransictionType tbl_TransictionType { get; set; }
}
You need a new view model with 2 collection properties one for each collection.
public class AccountDetailsVm
{
public List<BOL.tbl_Transiction> Reciveable {set;get;}
public List<BOL.tbl_Transiction> Payable {set;get;}
}
And in your GET action, create an object of this view model, fill these 2 properties.
public ActionResult Index(int accountid)
{
var v=new AccountDetailsVm();
//Load both the collection properties
v.Payables = objbs.GetALL()
.Where(p => p.AId==accountid && p.tbl_TransictionType.Type.Contains("Payable"));
v.Reciveable = objbs.GetByID(accountid).tbl_TransictionType.Type.Contains("Reciveable");
return View(v);
}
And your view is bound to the new view model. I just added the minimal code here. You can convert the rendering to a table.
#model AccountDetailsVm
<h1>Reciveable</h1>
#foreach(var item in Model.Reciveable)
{
<p>#item.Amount</p>
}
<h1>Payable</h1>
#foreach(var item in Model.Payable)
{
<p>#item.Amount</p>
}
Im newbie to mvc.I have a menusettings page where user can add menu according to his role.For that I want to create a view.How can I bind the model to view properly so that i can save the settings.My concern is inorder to access ienumerable item in the viewmodel,viewmodel should also be ienumerable.Here i cannot convert the viewmodel to ienumerable.
Any help will be greatly appreciated
ModelClass is
public partial class Role
{
public int Id { get; set; }
public string RoleName { get; set; }
public Nullable<int> ParentID { get; set; }
public virtual ICollection<MenuRole> MenuRoles { get; set; }
}
public partial class Menu
{
public int Id { get; set; }
public string MenuName { get; set; }
public string NavigateUrl { get; set; }
public Nullable<int> ParentID { get; set; }
public virtual ICollection<MenuRole> MenuRoles { get; set; }
}
ViewModel Is
public class MenuRoleVM
{
public int? RoleId { get; set; }
public SelectList RoleList { get; set; }
public IEnumerable<Menu> MenuList { get; set; }
}
My controller is
public class MenuSettingsController : Controller
{
public ActionResult Add()
{
var _menuRoleVM = new MenuRoleVM
{
RoleList = new SelectList(_db.Roles.ToList(), "Id", "RoleName"),
MenuList = _db.Menus
.Where(m => m.NavigateUrl != "#").ToList()
};
return View(_menuRoleVM);
}
}
Below example will help. Here, I have the model ContactModel with properties - FirstName, LastName and Email.
#model IEnumerable<CrazyContacts.Models.ContactModel>
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<p>
#Html.ActionLink("Create New", "Create")
</p>
<table class="table">
<tr>
<th>
#Html.DisplayNameFor(model => model.FirstName)
</th>
<th>
#Html.DisplayNameFor(model => model.LastName)
</th>
<th>
#Html.DisplayNameFor(model => model.Email)
</th>
<th></th>
</tr>
#foreach (var item in Model) {
<tr>
<td>
#Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
#Html.DisplayFor(modelItem => item.Email)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new { id=item.Id }) |
#Html.ActionLink("Details", "Details", new { id=item.Id }) |
#Html.ActionLink("Delete", "Delete", new { id=item.Id })
</td>
</tr>
}
</table>
Thanks for your input #Stephen.
I got the code running by the adding the view as below
#foreach (var item in Model.MenuList.Select((x, i) => new {Data=x,Index=i }))
{
<tr>
<td>#(item.Index+1)</td>
<td>#item.Data.MenuName</td>
</tr>
}
I have an entity called Fixture, and basically I want to display some fixtures on the page.
My Model is as follows :-
public class Fixture
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int FixtureId { get; set; }
[Display(Name = "Fixture Date")]
[DisplayFormat(DataFormatString = "{0:dd/MM/yyyy}", ApplyFormatInEditMode = true)]
public DateTime? FixtureDate { get; set; }
public DateTime? FixtureTime { get; set; }
public int? CityId { get; set; }
public City City { get; set; }
public int CountryIdA { get; set; }
public int CountryIdB { get; set; }
public int? ScoreA { get; set; }
public int? ScoreB { get; set; }
public Round Round { get; set; }
public int? RoundId { get; set; }
public List<Scorer> Scorers { get; set; }
}
and my ViewModel is as follows :-
public class FixtureViewModel
{
public Fixture Fixture { get; set; }
public IEnumerable<Fixture> FixtureList { get; set; }
public IEnumerable<GroupCountry> GroupCountryList { get; set; }
public IEnumerable<Group> GroupList { get; set; }
public string CountryNameA { get; set; }
public string CountryNameB { get; set; }
}
and I am displaying them in this index page :-
<table>
<tr>
<th>
#Html.DisplayName("Date")
</th>
<th>
#Html.DisplayName("Country A")
</th>
<th>
#Html.DisplayName("Country A")
</th>
<th>
#Html.DisplayName("Score A")
</th>
<th>
#Html.DisplayName("Score B")
</th>
<th>
#Html.DisplayName("Round")
</th>
<th></th>
</tr>
#foreach (Fixture item in Model.FixtureList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.FixtureDate)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountryIdA)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountryIdB)
</td>
<td>
#Html.DisplayFor(modelItem => item.ScoreA)
</td>
<td>
#Html.DisplayFor(modelItem => item.ScoreB)
</td>
<td>
#Html.DisplayFor(modelItem => item.Round.RoundName)
</td>
<td>
#Html.ActionLink("Edit", "Edit", new {id = item.FixtureId}) |
#Html.ActionLink("Details", "Details", new {id = item.FixtureId}) |
#Html.ActionLink("Delete", "Delete", new {id = item.FixtureId})
</td>
</tr>
}
</table>
Now in the index page, I wish to display something like this :-
<td>
#Html.DisplayFor(modelItem => item.CountryIdA.Country.CountryName)
</td>
<td>
#Html.DisplayFor(modelItem => item.CountryIdB.Country.CountryName)
</td>
How can I achieve that?
I added a navigation item Country in the Model, however I still cannot display the correct CountryName.
Thanks for your help and time
Well CountryIdA and CountryIdB are just Integers. If you are trying to say...
Find a fixture with CountryIdA/B, then get it's Country, and then CountryName
then this is not appropriate to put in a view. Your view should not handle any data access, that is the job of your controller/model. I would suggest adding two Country properties to your view model, one for IdA and one for IdB. Then you can populate these in your controller action and have access to them in your view.
Your controller might look something like...
ViewModel.CountryA = Countries.Where(x => x.CountryID = ViewModel.CountryIdA)
You can extend Fixture in your model by creating a partial class Fixture in the same namespace, create two custom properties CountryIdA/B that does a lookup for the currect IDs.