Reputation: 510
Currently I am learning razor pages and come from a WPF background.
I am displaying some data in a row format but want to create a drill down format such as this: http://jsfiddle.net/zey3h41o/
Where I can create summaries of top level data from one model and then create a drill down feature showing child entries of a data sturcture such as this:
List<Tuple<HighLevelOutput, List<HighLevelOutput>>>
And the model
public struct HighLevelOutput
{
public string CorpCustomer { get; set; }
public string Item { get; set; }
public string ItemDescription { get; set; }
public double SummedOrder { get; set; }
public double SummedForecast { get; set; }
public int Week { get; set; }
public double Difference { get; set; }
public string UoM { get; set; }
}
My Razor Page:
@page
@model DemandControlTool.Pages.CalculateLogModel
@{
ViewData["Title"] = "CalculateLog";
}
<h3>Abnormal Demand</h3>
<table class="table">
<thead>
<tr>
<th></th>
<th>
@Html.DisplayNameFor(model => model.ReportHighLevel[0].CorpCustomer)
</th>
<th>
@Html.DisplayNameFor(model => model.ReportHighLevel[0].Item)
</th>
<th class="text-center">
@Html.DisplayNameFor(model => model.ReportHighLevel[0].SummedOrder)
</th>
<th class="text-center">
@Html.DisplayNameFor(model => model.ReportHighLevel[0].SummedForecast)
</th>
<th class="text-center">
@Html.DisplayNameFor(model => model.ReportHighLevel[0].Difference)
</th>
</tr>
</thead>
</table>
<table class="log">
<thead class="log">
@foreach (var item in Model.DropDownAllOrders)
{
<tr>
<th>
@Html.DisplayFor(modelItem => item.Item1.Item)
</th>
<th>
@Html.DisplayFor(modelItem => item.Item1.ItemDescription)
</th>
<th>
@Html.DisplayFor(modelItem => item.Item1.CorpCustomer)
</th>
<th class="text-center">
@Html.DisplayFor(modelItem => item.Item1.SummedOrder)
</th>
<th class="text-center">
@Html.DisplayFor(modelItem => item.Item1.SummedForecast)
</th>
<th class="text-center">
@Html.DisplayFor(modelItem => item.Item1.Difference)
</th>
</tr>
}
</thead>
<tbody class="collapsed">
<tr><td>Drill Down Data</td></tr>
<tr><td>Drill Down Data</td></tr>
</tbody>
</table>
The problem I'm having is populating the table where I can have the collapsed entries underneath each row. In the way I've been playing with it I would need to have a separate defined row for each object in the list. I'd like the body class there to have the List for each summary row.
In the example above the collapsed body only appears under the bottom row.
Updated Edit:
@page
@model DemandControlTool.Pages.CalculateLogModel
@{
ViewData["Title"] = "CalculateLog";
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/bootstrap.css" rel="stylesheet" />
<title>Data page</title>
</head>
<body>
<div class="container">
<div id="accordion">
@{int counter = 0; }
@foreach (var dataVM in Model.CollapseReport)
{
<div class="card">
<div class="card-header" id="heading@(counter)">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse"
data-target="#collapse@(counter)" aria-expanded="true" aria-
controls="collapse@(counter)">
@dataVM.ToString()
</button>
</h5>
</div>
<div id="collapse@(counter)" class="collapse" aria-
labelledby="heading@(counter)" data-parent="#accordion">
<div class="card-body">
<ul class="list-group">
@foreach (var item in dataVM.WeeksOfData)
{
<li class="list-group-item col-xs-6">@item.Item</li>
<li class="list-group-item col-xs-6">@item.ItemDescription</li>
<li class="list-group-item col-xs-6">@item.CorpCustomer</li>
<li class="list-group-item col-xs-6">@item.Difference</li>
<li class="list-group-item col-xs-6">@item.Week</li>
}
</ul>
</div>
</div>
</div>
counter++;
}
</div>
</div>
<script src="~/jquery.min.js"></script>
<script src="~/bootstrap.bundle.min.js"></script>
</body>
</html>
Upvotes: 1
Views: 921
Reputation: 575
Base on the example you have provided, I thought about a different solution for your problem, which in my opinion is simpler and fit within the web much more better, first of all I had used JQuery and Bootstrap v.4 inside my front-end code, then I have used two components which they are:
Afterwards I create a view model for my data shape, which contains a title with a list of items (I use strings for demonstration only) as following:
public class DataViewModel
{
public string Title { get; set; }
public IEnumerable<string> Data { get; set; }
}
And create a Index an action as following (just to fill up some data and pass it to the view:
public IActionResult Index()
{
var pageViewModel = new List<DataViewModel>()
{
new DataViewModel()
{
Title="First data tab",
Data=new string []{"Item 1","Item 2","Item 3"}
},
new DataViewModel()
{
Title="Second data tab",
Data=new string []{"Item 1","Item 2","Item 3"}
}
};
return View(pageViewModel);
}
Finally the view code is like the following:
@model IEnumerable<ProgrammerGallery.Controllers.DataViewModel>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/bootstrap.min.css" rel="stylesheet" />
<title>Data page</title>
</head>
<body>
<div class="container">
<div id="accordion">
@{int counter = 0; }
@foreach (var dataVM in Model)
{
<div class="card">
<div class="card-header" id="heading@(counter)">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapse@(counter)" aria-expanded="true" aria-controls="collapse@(counter)">
@dataVM.Title
</button>
</h5>
</div>
<div id="collapse@(counter)" class="collapse show" aria-labelledby="heading@(counter)" data-parent="#accordion">
<div class="card-body">
<ul class="list-group">
@foreach (var item in dataVM.Data)
{
<li class="list-group-item">@item</li>
}
</ul>
</div>
</div>
</div>
counter++;
}
</div>
</div>
<script src="~/jquery.min.js"></script>
<script src="~/bootstrap.bundle.min.js"></script>
</body>
</html>
And the final result is:
Second Edition (collapsible item when the page is rendered beside display entity data side by side rather than string data):
Entity class:
public class Entity
{
public string Name { get; set; }
public string BriefDescription { get; set; }
public double Price { get; set; }
}
View model class:
public class DataViewModel
{
public string Title { get; set; }
public IEnumerable<Entity> Data { get; set; }
}
The action:
public IActionResult Index()
{
var pageViewModel = new List<DataViewModel>()
{
new DataViewModel()
{
Title="First data tab",
Data=new List<Entity>()
{
new Entity()
{
Name="First item",
BriefDescription="My description",
Price=1000
},
new Entity()
{
Name="Second",
BriefDescription="My description",
Price=500
},
new Entity()
{
Name="Third",
BriefDescription="My description",
Price=1000
}
}
},
new DataViewModel()
{
Title="Second data tab",
Data=new List<Entity>()
{
new Entity()
{
Name="First item",
BriefDescription="My description",
Price=1000
},
new Entity()
{
Name="Second",
BriefDescription="My description",
Price=500
},
new Entity()
{
Name="Third",
BriefDescription="My description",
Price=1000
}
}
}
};
return View(pageViewModel);
}
And finally the razor code:
@model IEnumerable<ProgrammerGallery.Controllers.DataViewModel>
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<link href="~/bootstrap.min.css" rel="stylesheet" />
<title>Data page</title>
</head>
<body>
<div class="container">
<div id="accordion">
@{int counter = 0; }
@foreach (var dataVM in Model)
{
<div class="card">
<div class="card-header" id="heading@(counter)">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" data-target="#collapse@(counter)" aria-expanded="true" aria-controls="collapse@(counter)">
@dataVM.Title
</button>
</h5>
</div>
<div id="collapse@(counter)" class="collapse" aria-labelledby="heading@(counter)" data-parent="#accordion">
<div class="card-body">
<ul class="list-group">
@foreach (var item in dataVM.Data)
{
<li class="list-group-item">@($"Name :{item.Name}, {item.BriefDescription}, {item.Price}$")</li>
}
</ul>
</div>
</div>
</div>
counter++;
}
</div>
</div>
<script src="~/jquery.min.js"></script>
<script src="~/bootstrap.bundle.min.js"></script>
</body>
</html>
Upvotes: 3