Introduction
* Kindly view my Youtube video link to learn ASP.NET Core Blazor Master Detail using Entity Framework and Web API.
In this article, let’s see how to create our own ASP.NET Core Blazor Master Detail HTML Grid with Sorting and Filtering using Entity Framework, and Web API. We also use the Dynamic Content features of Blazor to create our Master Detail Grid.
Kindly read my previous articles which explain in depth about getting started with ASP.NET Core Blazor.
This article will explain:
- Creating sample database and
Student
Master and Detail Table in SQL Server to display in our web application - How to create a ASP.NET Core Blazor Web application
- How to install the Package for using Entity Framework and creating
DBContext
class - How to get result from Web API and bind result in Blazor client Razor view
- Creating Master/Detail with Sorting and Filtering features for the HTML table
- Creating Master/Detail table using Blazor Dynamic Content
Blazor Dynamic Content
In Blazor, we can write our own component using the C# Code. We all know that in Blazor, we can write C# code in our client HTML function part, some time we need to create and bind the results dynamically to our HTML page. In this article using he Blazor Dynamic Content, we create the detail table dynamically and display during the run time as when the user clicks on the detail grid display icon in master grid.
We can also say this as Master/Detail HTML Grid or Hierarchical Grid or Nested Grid.
Why We Need Nested or Hierarchical Grid or Master/Detail Grid
In real time projects like Order Management, Production management, Students Management, etc. we need to display the data in the hierarchical result.
For example, let’s take Students
Management project for a University. For students
Management we need to create many relational tables like Student Master
, Student Details
, etc. In Student Master
, we store student ID
, Name
, Email
, Phone
and Address
. In Student Details
, we store the student
s' final exam results for displaying Student Major
, Studying Year with Term, and Grade details. Both these table will be related with StudentID
. We join both these tables to display the complete student details.
Initially, we will be displaying all the students
Master records in HTML table for view. Users can click on expand icon on each student
to view his complete details.
Here, in the below image, we can see that as we bind both the result of Student Master
and Student detail
in HTML table and we display the detail only when user clicks on the Student Master
Icon which is near to the Student ID
. When the user clicks on the Student ID
“2
”, then the next details Grid
was being displayed to show student
results in detail by Major
, Year
, Term
, and Grade
.
Here, we are displaying student
details by each student Id
.
In our example, we also added the Filtering and Sorting functionality for our Master/Detail Grid.
Background
Make sure that you have installed all the prerequisites in your computer. If not, then download and install all, one by one. Note that since Blazor is the new framework and we must have installed preview of Visual Studio 2017 (15.7) or above.
Using the Code
Step 1 - Create a database and a table
We will be using our SQL Server database for our WEB API and EF. First, we create a database named StudentsDB
and a table as StudentMaster
. Here is the SQL script to create a database table and sample record insert query in our table. Run the query given below in your local SQL Server to create a database and a table to be used in our project.
USE MASTER
GO
IF EXISTS(SELECT [name] FROM sys.databases WHERE[name] = 'StudentGradeDB')
DROP DATABASE StudentGradeDB
GO
CREATE DATABASE StudentGradeDB
GO
USE StudentGradeDB
GO
CREATE TABLE[dbo].[StudentMasters](
[StdID] INT IDENTITY PRIMARY KEY,
[StdName][varchar](100) NOT NULL,
[Email][varchar](100) NOT NULL,
[Phone][varchar](20) NOT NULL,
[Address][varchar](200) NOT NULL
)
INSERT INTO [StudentMasters]([StdName], [Email], [Phone], [Address])
VALUES('Shanu', <a href="mailto:'syedshanumcain@gmail.com'">'syedshanumcain@gmail.com'</a>,
'01030550007', 'Madurai,India')
INSERT INTO [StudentMasters]([StdName], [Email], [Phone], [Address])
VALUES('Afraz', <a href="mailto:'Afraz@afrazmail.com'">'Afraz@afrazmail.com'</a>,
'01030550006', 'Madurai,India')
INSERT INTO [StudentMasters]([StdName], [Email], [Phone], [Address])
VALUES('Afreen', <a href="mailto:'Afreen@afreenmail.com'">'Afreen@afreenmail.com'</a>,
'01030550005', 'Madurai,India')
select * from[StudentMasters]
CREATE TABLE[dbo].[StudentDetails](
[StdDtlID] INT IDENTITY PRIMARY KEY, [StdID] INT,
[Major][varchar](100) NOT NULL,
[Year][varchar](30) NOT NULL,
[Term][varchar](30) NOT NULL,
[Grade][varchar](10) NOT NULL)
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade])
VALUES(1, 'Computer Science', 'FirstYear', 'FirstTerm', 'A')
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade])
VALUES(1, 'Computer Science', 'FirstYear', 'SecondTerm', 'B')
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade])
VALUES(1, 'Computer Science', 'SecondYear', 'FirstTerm', 'C')
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade])
VALUES(2, 'Computer Engineer', 'ThirdYear', 'FirstTerm', 'A')
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade])
VALUES(2, 'Computer Engineer', 'ThirdYear', 'SecondTerm', 'A')
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade])
VALUES(3, 'English', 'First Year', 'FirstTerm', 'C')
INSERT INTO[StudentDetails]([StdID], [Major], [Year], [Term], [Grade])
VALUES(3, 'Economics', 'First Year', 'FirstTerm', 'A')
select * from StudentDetails
Step 2 - Create ASP.NET Core Blazor Application
After installing all the prerequisites listed above and ASP.NET Core Blazor Language Services, click Start >> Programs >> Visual Studio 2017 >> Visual Studio 2017 on your desktop. Click New >> Project. Select Web >> ASP.NET Core Angular Web Application. Enter your project name and click OK.
Select Blazor (ASP.NET Core hosted) and click ok.
After creating ASP.NET Core Blazor Application, wait for a few seconds. You will see the below structure in solution explorer.
What is New in ASP.NET Core Blazor Solution?
When we create our new ASP.NET Core Blazor application, we can see that there will be 3 projects that will be automatically created in the solution Explorer.
Client Project
The first project created as the Client project and it will be as our Solutionname.Client
and here, we can see our Solutionname
as “BlazorASPCORE
”. As the project named as client and this project will be mainly focused for all the client-side view. Here, we will be adding all our page view to be displayed in the client side in browser.
We can see as few of sample page has been already added here and we can also see a shared folder which is the same like our MVC application where will be having the Sharedfolder and Layout page for the Master page. Here in Blazor, we have the MainLayout
which will be work like the Master page and NavMenu for the left side menu display.
Server Project
As the name indicates, this project will be used as a Server project. This project is mainly used to create all our Controllers and WEB API Controllers to perform all business logic and perform CRUD operation using WEB APIs. In our demo application, we will be adding a Web API in this Server project and all the WEB API in our Client application. This Server project will be work like get/set the data from database and from our Client project, we bind or send the result to this server to perform the CRUD operation in database.
Shared Project
As the name indicates, this project works like a shared project. This project works as a Model for our Server project and for the Client project. The Model declared in this Shared project will be used in both the Server and in the Client project. We also install all the packages needed for our project here, for example to use the Entity Framework, we install all the packages in this Shared project.
Run to Test the Application
When we run the application, we can see that the left side has navigation and the right side contains the data. We can see as the default sample pages and menus will be displayed in our Blazor web site. We can use the pages or remove it and start with our own page.
Now let’s see how to add new page perform the CRUD operation for maintaining student
details.
Using Entity Framework
To use the Entity Framework in our Blazor application, we need to install the below packages.
Install the Packages
Go to Tools and then select -> NuGet Package Manager -> Package Manager Console.
You can see the Console at the bottom of the VS 2017 IDE and in right side of the combobox
on the console, select the Default project as your shared project ”Select Shared”.
- You can see the PM> and copy and paste the below line to install the Database Provider package. This package is used to set the database provider as SQL Server.
Install-Package Microsoft.EntityFrameworkCore.SqlServer
We can see as the package is installed in our Shared folder.
Install the Entity Framework:
- You can see the PM> and copy and paste the below line to install the EF package.
Install-Package Microsoft.EntityFrameworkCore.Tools
To create DB Context and set the DB Connection string:
- You can see the PM> and copy and paste the below line set the Connection string and create DB Context. This is an important part as we give our SQL Server name, Database Name and SQL server UID and SQL Server Password to connect to our database to display our Master/Detail Grid. We also give both our SQL Tables names “
StudentMasters
, StudentDetails
” to create the Model
class in our Shared project.
Scaffold-DbContext "Server= ServerName;Database=StudentGradeDB;
user id=UserID;password=Password;Trusted_Connection=True;MultipleActiveResultSets=true"
Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models -Tables StudentMasters,StudentDetails
Press enter create connection string, Model Class and Database Context.
We can see StudentMasters
and StudentDetails Model
class and StudentGradeDBContext
class has been created in our Shared project. We will be using this Model
and DBContext
in our Server project to create our Web API to perform the CRUD operations.
Creating Web API for Get Student Details
To create our WEB API Controller, right click Controllers folder. Click Add New Controller.
Here, we will be using Scaffold
method to create our WEB API. We select API Controller with actions, using Entity Framework.
Select our Model
and DatabaseContext
from the Shared project.
Select our StudentMasters
Model from the Shared Project.
Select the Data Context Class as our StudentsDBContext
from the Shared project. Our Controller
name will be automatically added if you need, you can change it and click the ADD.
We will be using only the Get
method from our Web API.
Same like this, we also create a Web API for our StudentDetails
.
To test Get
Method, we can run our project and copy the GET
method API path. Here, we can see our API path to get api/StudentMasters/.
Run the program and paste API path to test our output.
For StudentDetails
, we can pass the Student ID
to get only one student
details. Here, we can see the result for student ID
as “1
” we call the Web API as /api/StudentDetails/1.
Now, we will bind all this WEB API Json result in our Razor View page from our Client
project for displaying the Master/Detail HTML table.
Working with Client Project
Note: In this article, we will create 2 Razor pages. In one Razor page, we will create the Master Details HTML table with normal binding method and in another Razor page, we bind the Detail table using Blazor Dynamic Content.
Razor Page with normal binding
First, we need to add the new Razor view page.
Add Razor View
To add the Razor view page, right click the Pages folder from the Client project. Click on Add >> New Item.
Select Razor View >> Enter your page name. Here, we have given the name as Students.chtml.
In Razor view Page, we have 3 parts of code as first is the Import part where we import all the references and models for using in the view, HTML design and data bind part and finally, we have the function part to call all the web APIs to bind in our HTML page and also to perform client-side business logic to be displayed in View page.
Import Part
First, we import all the needed support files and references in our Razor View page. Here, we have first imported our Model
class to be used in our view and also imported HTTPClient
for calling the Web API to perform the CRUD operations.
@using BLAZORASPCORE.Shared
@using BLAZORASPCORE.Shared.Models
@page "/Students"
@using Microsoft.AspNetCore.Blazor.Browser.Interop
@inject HttpClient Http
Master HTML Grid Data Bind Part
Next, we design our Student
page to bind the student Master
and Student Detail
results from the Web API to HTML table.
Binding Student Master Details
In the Init
method, we get the Student Master details from Web API and bind the result in HTML table using foreach
loop. Here, we bind the result for Student Master
Grid and in each row first column, we add the Toggle image and, in this Toggle, image click event we call the getStudentsDetails(studentsID)
method to display the Detail
HTML grid for the related Student
. We pass the Student ID
to the function and we get the related student
details for the student
and bind the result in detail grid. Also, we will show the detail grid only when the toggle image button is clicked and if the toggle button is clicked again, we hide the detail grid.
@foreach (var StudentMasters in stdMaster)
{
<tr style="border-style:dashed;border-width:2px;
border-color: @(StudentMasters.StdId == studentIDs ? "#ff6a00": "#a2aabe")">
<td align="center" style="border: solid1px#659EC7; padding: 5px;table-layout:fixed;">
@if (@StudentMasters.StdId == studentIDs)
{
<img src="@Imagename" onclick="@(async () =>
await getStudentsDetails(@StudentMasters.StdId))" />
}
else
{
<img src="Images/toggle.png" onclick="@(async () =>
await getStudentsDetails(@StudentMasters.StdId))" />
}
</td>
<td align="center">
<span style="color:#9F000F">
@StudentMasters.StdId
</span>
</td>
<td align="center">
<span style="color:#9F000F">
@StudentMasters.StdName
</span>
</td>
<td align="center">
<span style="color:#9F000F">
@StudentMasters.Email
</span>
</td>
<td align="center">
<span style="color:#9F000F">
@StudentMasters.Phone
</span>
</td>
<td align="center">
<span style="color:#9F000F">
@StudentMasters.Address
</span>
</td>
</tr>
Adding Sorting features in Table Heading
Here, we have added the Sorting and Filtering features only for the Master HTML table. If needed, then we can implement this same feature for Detail grid as well.
In the Master Table heading part for each heading, we add the Sorting Image. In Sorting Image Button Click event, we call the Sorting function and pass each Sorting Column name to the click event. In Function code part, we sort the Web API and display the result by ascending and in descending order by each column header sorting image click.
<table style="background-color:#FFFFFF; border-style:inset;border-width:1px;
border-color:#6D7B8D; padding:2px;width:100%;table-layout:fixed;" cellpadding="1" cellspacing="1">
<tr style="background-color:#2d364d ; color:#FFFFFF ;border-style:dashed;
border-width:2px;border-color:0A2464;" >
<td width="30" align="center"></td>
<td width="80" align="center">
<img src="@ImageSortname" onclick="@(async () => await StudentSorting("StdId"))"
height="24" width="24"/>
Student ID
</td>
<td width="240" align="center">
<img src="@ImageSortname" onclick="@(async () => await StudentSorting("StdName"))"
height="24" width="24"/>
Student Name
</td>
<td width="240" align="center">
<img src="@ImageSortname" onclick="@(async () => await StudentSorting("Email"))"
height="24" width="24"/>
Email
</td>
<td width="120" align="center">
<img src="@ImageSortname" onclick="@(async () => await StudentSorting("Phone"))"
height="24" width="24"/>
Phone
</td>
<td width="340" align="center">
<img src="@ImageSortname" onclick="@(async () => await StudentSorting("Address"))"
height="24" width="24"/>
Address
</td>
</tr>
Adding Filtering Features in Table Heading
In the Table heading part, we add a new row. In table row, we add the Textbox
for each column to perform the filtering for the binded result. In Textbox onChange
event, we call the method to perform the Filtering operation from the code function part.
<tr style="height: 30px; background-color:#336699 ; color:#FFFFFF ;">
<td width="30" align="center"></td>
<td width="80" align="center">Filter : </td>
<td width="240" align="center">
<input width="70" <a href="mailto:onchange=@OnstdNameChanged">
onchange=@OnstdNameChanged</a> oninput="(this.dispatchEvent(new CustomEvent
('change', {bubbles: true})))" />
</td>
<td width="240" align="center">
<input width="70" <a href="mailto:onchange=@OnEmailChanged">
onchange=@OnEmailChanged</a> oninput="(this.dispatchEvent(new CustomEvent
('change', {bubbles: true})))" />
</td>
<td width="120" align="center">
<input width="70" <a href="mailto:onchange=@OnPhoneChanged">
onchange=@OnPhoneChanged</a> oninput="(this.dispatchEvent(new CustomEvent
('change', {bubbles: true})))" />
</td>
<td width="340" align="center">
<input width="70" <a href="mailto:onchange=@OnAddressChanged">
onchange=@OnAddressChanged</a> oninput="(this.dispatchEvent(new CustomEvent
('change', {bubbles: true})))" />
</td>
</tr>
Bind the Detail Grid Result
Firstly, we check the StudentDetails
result is null
. If it’s not null
, then we bind the result in HTML Table. Before binding the result, we also check for the showDetailStatus ==1
which means to show or hide the Detail Grid. By default, we set the showDetailStatus
as 0
and in Master grid Toggle image click event, we change the status to 1
and if the showDetailStatus
is 1
, then we display the Detail grid we also check the Master grid StudentsID
with student detail and bind the result in Detail Grid.
@if (stdDetail != null)
{
@if (showDetailStatus == 1)
{
@if (@StudentMasters.StdId == studentIDs)
{
<tr style="background-color:#6D7B8D ; color:honeydew ;
border-style:dashed;border-width:2px;border-color:#ECF3F4;">
<td colspan="6" align="center">
Student Details of Student Id - <strong>@StudentMasters.StdId </strong>,
Total @stdDetail.Length Grade details for this Student
</td>
</tr>
<tr>
<td></td>
<td colspan="5">
<table style="background-color:#ECF3F4;border-style:dashed;
border-width:2px;border-color:#0A2464; padding:5px;width:100%;
table-layout:fixed;" cellpadding="1" cellspacing="1">
<tr style="background-color:#659EC7 ; color:#FFFFFF ;
border-style:dashed;border-width:2px;border-color:0A2464;">
<td width="160" align="center">
<Strong>Student Detail</Strong>
</td>
<td width="240" align="center">
Major
</td>
<td width="240" align="center">
Year
</td>
<td width="120" align="center">
Term
</td>
<td width="340" align="center">
Grade
</td>
</tr>
@foreach (var stdDtls in stdDetail)
{
<tr>
<td align="center">
@stdDtls.StdDtlId
</td>
<td align="center">
<span style="color:#9F000F">
@stdDtls.Major
</span>
</td>
<td align="center">
<span style="color:#9F000F">
@stdDtls.Year
</span>
</td>
<td align="center">
<span style="color:#9F000F">
@stdDtls.Term
</span>
</td>
<td align="center">
<span style="color:#9F000F">
@stdDtls.Grade
</span>
</td>
</tr>
}
</table>
</td>
</tr>
}
}
}
Function Part
Function part to call all the web API to bind in our HTML page and also to perform client-side business logic to be displayed in View page.
Init Method
In the Init
method, we get the result of Web API for student
details and store it in the StudentMaster
object and we use this object to bind in our html table using the foreach
statement.
@functions {
StudentMasters[] stdMaster;
StudentDetails[] stdDetail;
StudentMasters stdmst = new StudentMasters();
StudentDetails stdDtl = new StudentDetails();
int showDetailStatus = 0;
int sortStatus = 0;
int studentIDs = 0;
string Imagename = "Images/toggle.png";
string ImageSortname = "Images/sortAsc.png";
protected override async Task OnInitAsync()
{
stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
}
Detail Grid Bind, Hide/Show Method
In the Master grid Toggle image click event, we call this below method and pass the studentID
to get the appropriate student
details from the Web API and bind the result in the detail grid.
protected async Task getStudentsDetails(int StudID)
{
if (studentIDs != StudID)
{
Imagename = "Images/expand.png";
showDetailStatus = 1;
}
else
{
if (showDetailStatus == 0)
{
Imagename = "Images/expand.png";
showDetailStatus = 1;
}
else
{
Imagename = "Images/toggle.png";
showDetailStatus = 0;
}
}
studentIDs = StudID;
stdDetail = await Http.GetJsonAsync<StudentDetails[]>("/api/StudentDetails/" +
Convert.ToInt32(StudID));
}
Sorting Method
In Sorting image, click on each column heading. We call this method and pass the column name to this method. In this method, depending on column name, we do Sorting the Web API result and bind the result in the HTML table. We also do the vice versa sorting of Ascending and descending.
//Sorting
protected async Task StudentSorting(string SortColumn)
{
stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
if (ids == 0)
{
ImageSortname = "Images/sortDec.png";
ids = 1;
switch (SortColumn)
{
case "StdId":
stdMaster = stdMaster.OrderBy(x => x.StdId).ToArray() ;
break;
case "StdName":
stdMaster = stdMaster.OrderBy(x => x.StdName).ToArray();
break;
case "Email":
stdMaster = stdMaster.OrderBy(x => x.Email).ToArray();
break;
case "Phone":
stdMaster = stdMaster.OrderBy(x => x.Phone).ToArray();
break;
case "Address":
stdMaster = stdMaster.OrderBy(x => x.Address).ToArray();
break;
}
}
else
{
ImageSortname = "Images/sortAsc.png";
ids = 0;
switch (SortColumn)
{
case "StdId":
stdMaster = stdMaster.OrderByDescending(x => x.StdId).ToArray();
break;
case "StdName":
stdMaster = stdMaster.OrderByDescending(x => x.StdName).ToArray();
break;
case "Email":
stdMaster = stdMaster.OrderByDescending(x => x.Email).ToArray();
break;
case "Phone":
stdMaster = stdMaster.OrderByDescending(x => x.Phone).ToArray();
break;
case "Address":
stdMaster = stdMaster.OrderByDescending(x => x.Address).ToArray();
break;
}
}
}
Filtering Method
In each column heading part, we have added a new row for performing the Filtering of the HTML grid. In each column filter Textbox Change event, we pass the Textbox
value. We call a common filtering method studentFilteringList
and in this method, we pass the filtering column Textbox
value and column Name.
// For Filtering by Student Name
void OnstdNameChanged(UIChangeEventArgs args)
{
string values = args.Value.ToString();
studentFilteringList(values, "StudentName");
}
// For Filtering by Email
void OnEmailChanged(UIChangeEventArgs args)
{
string values = args.Value.ToString();
studentFilteringList(values, "Email");
}
// For Filtering by Phone
void OnPhoneChanged(UIChangeEventArgs args)
{
string values = args.Value.ToString();
studentFilteringList(values, "Phone");
}
// For Filtering by Adress
void OnAddressChanged(UIChangeEventArgs args)
{
string values = args.Value.ToString();
studentFilteringList(values, "Address");
}
Here, we create a common function named as studentFilteringList
and in this method, we get the filtering column Textbox
value and column Name. We do filtering from the Web API and bind the filtering result to the HTML Table.
//Filtering
protected async Task studentFilteringList(String Value,string columnName)
{
stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
if (Value.Trim().Length >0)
{
switch (columnName)
{
case "StudentName":
stdMaster = stdMaster.Where(x => x.StdName.Contains(Value)).ToArray();
break;
case "Email":
stdMaster = stdMaster.Where(x => x.Email.Contains(Value)).ToArray();
break;
case "Phone":
stdMaster = stdMaster.Where(x => x.Phone.Contains(Value)).ToArray();
break;
case "Address":
stdMaster = stdMaster.Where(x => x.Address.Contains(Value)).ToArray();
break;
default:
stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
break;
}
}
else
{
stdMaster = await Http.GetJsonAsync<StudentMasters[]>("/api/StudentMasters/");
}
}
Razor Page with Dynamic Content
First, we need to add the new Razor view page.
Add Razor View
To add the Razor view page, right click the Pages folder from the Client
project. Click on Add >> New Item.
Select Razor View >> Enter your page name. Here, we have given the name as Students.chtml.
Same like our previous Razor view page, we use the same logic to bind the Master and the Detail grid but here instead of the direct HTML binding for the Detail grid, we bind the detail grid result using the Blazor Dynamic Content. We have already seen the Master data binding and Toggle button click events, Now for this page, we will directly explain only for the Dynamic Content part.
Dynamic Content Bind HTML Part
Same like our previous page, we do all status check and finally bind the Dynamic Content to display the Detail HTML table. We bind the result of Dynamic Content by using @DynamicContent
object.
@if (stdDetail != null)
{
@if (showDetailStatus == 1)
{
@if (@StudentMasters.StdId == studentIDs)
{
<tr style="background-color:#6D7B8D ; color:honeydew ;border-style:dashed;
border-width:2px;border-color:#ECF3F4;">
<td colspan="6" align="center">
Student Details of Student Id - <strong> @StudentMasters.StdId </strong> ,
Total @stdDetail.Length Grade details for this Student
</td>
</tr>
<tr>
<td></td>
<td colspan="5">
@DynamicContent
</td>
</tr>
}
}
}
Dynamic Content Bind Function
We bind the Dynamic Content results using the RenderFragment
object. Using the RenderFragment (Delegate)
in our method, we build the dynamic content and bind the result dynamically at runtime.
private Microsoft.AspNetCore.Blazor.RenderFragment DynamicContent;
In the Detail HTML table grid bind method, we create the dynamic Content to display the Detail grid inside the Master grid. In the calling method, every time we dynamically create the Detail grid and bind the result in RenderFragment
delegate with the use of builder, we create table dynamically and bind the results.
stdDetail = await Http.GetJsonAsync<StudentDetails[]>
("/api/StudentDetails/" + Convert.ToInt32(StudID));
DynamicContent = builder =>
{
var seq = 0;
builder.OpenElement(seq, "table");
builder.AddAttribute(seq, "style", "background-color:#ECF3F4;border-style:dashed;
border-width:2px;border-color:#0A2464; padding:5px;width:100%;table-layout:fixed;");
// Heading
builder.OpenElement(++seq, "tr");
builder.AddAttribute(++seq, "style", "height: 30px;border-style:inset;border-width:1px;
border-color:#6D7B8D; background-color:#336699 ; color:#FFFFFF ;");
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, "Student Details");
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, "Major");
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, "Year");
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, "Term");
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, "Grade");
builder.CloseElement();
builder.CloseElement();
//Tbody
foreach (var stdDtls in stdDetail)
{
builder.OpenElement(++seq, "tr");
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, stdDtls.StdDtlId);
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, stdDtls.Major);
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, stdDtls.Year);
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, stdDtls.Term);
builder.CloseElement();
builder.OpenElement(++seq, "td");
builder.AddContent(++seq, stdDtls.Grade);
builder.CloseElement();
builder.CloseElement();
}
builder.CloseElement();
};
Build and Run the Application
Points of Interest
In this article, we have added only one level of Hierarchy of grid, you can extend this to create multilevel Hierarchy of HTML grid. Note as when creating the DBContext
and setting the connection string, don’t forget to add your SQL connection string. Hope you like this article. In the next article, we will see more examples to work with Blazors and it's really very cool and awesome to work with Blazor.
History
- 10th June, 2018: BlazorMasterDetailGrid.zip