In this blog post I will display data within another data. Or, report within sub-report. Sometimes we need this functionality to display details of a particular object, on the same web page without navigating somewhere else.
We will need the following JavaScript files:
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.7.1.js")"></script> | |
<script type="text/javascript" src="@Url.Content("~/bootstrap/js/bootstrap.js")" src="js/bootstrap.min.js"></script> |
First, create ASP.NET MVC Solution in Visual Studio 2017, and add the following code in Home Controller:
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Web; | |
using System.Web.Mvc; | |
using Report_Subreport.Models; | |
namespace Report_Subreport.Controllers | |
{ | |
public class HomeController : Controller | |
{ | |
public ActionResult Index() | |
{ | |
List<Student> students = GetStudents(); | |
var booleanGroupQuery = | |
from student in students | |
group student by student.Scores.Average() >= 80; //pass or fail! | |
var stuentList = new List<Student>(); | |
var keys = new List<string>(); | |
foreach (var bgq in booleanGroupQuery) | |
{ | |
var key = bgq.Key ? "Score is greater than 80" : "Score is less than 80"; | |
keys.Add(key); | |
foreach (var groupDetails in bgq) | |
{ | |
var student = new Student(); | |
student.Key = key; | |
student.First = groupDetails.First; | |
student.Last = groupDetails.Last; | |
student.ID = groupDetails.ID; | |
student.Average = groupDetails.Scores.Average(); | |
stuentList.Add(student); | |
} | |
} | |
ViewBag.StudentList = stuentList; | |
ViewBag.Keys = keys; | |
return View(); | |
} | |
public static List<Student> GetStudents() | |
{ | |
// Use a collection initializer to create the data source. Note that each element | |
// in the list contains an inner sequence of scores. source: msdn | |
List<Student> students = new List<Student> | |
{ | |
new Student {First="Svetlana", Last="Omelchenko", ID=111, Scores= new List<int> {97, 72, 81, 60}}, | |
new Student {First="Claire", Last="O'Donnell", ID=112, Scores= new List<int> {75, 84, 91, 39}}, | |
new Student {First="Sven", Last="Mortensen", ID=113, Scores= new List<int> {99, 89, 91, 95}}, | |
new Student {First="Cesar", Last="Garcia", ID=114, Scores= new List<int> {72, 81, 65, 84}}, | |
new Student {First="Debra", Last="Garcia", ID=115, Scores= new List<int> {97, 89, 85, 82}} | |
}; | |
return students; | |
} | |
} | |
} |
In the code above we fill the View Bag with students list to pass to the View with this line of code:
ViewBag.StudentList = stuentList;
Then we call the view below:
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<link href="~/bootstrap/css/bootstrap.min.css" rel="stylesheet" media="screen"> | |
<script type="text/javascript" src="@Url.Content("~/Scripts/jquery-1.7.1.js")"></script> | |
<script type="text/javascript" src="@Url.Content("~/bootstrap/js/bootstrap.js")" src="js/bootstrap.min.js"></script> | |
</head> | |
<body> | |
@{ | |
var keys = (List<string>)ViewBag.Keys; | |
var studList = (List<Report_Subreport.Models.Student>)ViewBag.StudentList; | |
<table class="table table-striped"> | |
<thead style="margin-left: 5px" class="bg-success"> | |
<tr> | |
<th style="width: 100%; font-size: x-large">Subreport – nested data example</th> | |
<th></th> | |
<th></th> | |
<th></th> | |
</tr> | |
</thead> | |
<tbody style="margin-left: 5px"> | |
<tr> | |
<th colspan="5"> | |
@foreach (var k in keys) | |
{ | |
<table class="table table-striped"> | |
<thead style="margin-left: 5px" id="toggleBack" onclick="$(this).next().show();"> | |
<tr> | |
<th style="width: 50px"> | |
<button type="button" class="btn btn-primary">+</button> | |
</th> | |
<th style="text-align: left">@k</th> | |
<th></th> | |
<th></th> | |
</tr> | |
</thead> | |
<tbody style="margin-left: 5px" id="toggleHide" onclick="$(this).hide();"> | |
<tr> | |
<th scope="row"> | |
<button type="button" class="btn btn-primary">-</button></th> | |
<td><strong>Student ID</strong></td> | |
<td><strong>First Name</strong></td> | |
<td><strong>Last Name</strong></td> | |
<td><strong>Average</strong></td> | |
</tr> | |
@foreach (var details in studList) | |
{ | |
if (details.Key.Equals(k)) | |
{ | |
<tr> | |
<th scope="row"></th> | |
<td>@details.ID</td> | |
<td>@details.First</td> | |
<td>@details.Last</td> | |
<td>@details.Average</td> | |
</tr> | |
} | |
} | |
</tbody> | |
</table> | |
} | |
</th> | |
</tr> | |
</tbody> | |
</table> | |
} | |
</body> | |
</html> | |
<script type="text/javascript"> | |
$(document).ready(function () { | |
// | |
}); | |
</script> | |
We iterate through our list to get the following end result:
Picture below shows the initial page
The following picture shows expanded list under its parent list:
Video:
And the source code is at GitHub here:
https://github.com/thoughtsonprogramming/report-subreport