Creating A Reusable Grid Component For Blazor

Introduction

In this article, we will create a reusable grid component for Blazor called BlazorGrid. It will display the user data in a grid and will support the client-side pagination.

Take a look at the final application.

Creating BlazorGrid

Since this is a reusable component, we will also publish it to nuget.org as a NuGet package. To learn how to publish the BlazorGrid component to a NuGet gallery, refer to my article Blazor - Publishing A Component To NuGet Gallery.

Prerequisites

  • Install the .NET Core 2.1 or above SDK from here.
  • Install the latest version of Visual Studio 2017 from here.
  • Install ASP.NET Core Blazor Language Services extension from here.
  • Install Blazor templates on the command line using the following command.
dotnet new -i Microsoft.AspNetCore.Blazor.Templates

Source Code: Get the source code from GitHub.

Creating the Blazor Library project

To create a Blazor library project, follow the steps mentioned below.

  1. Navigate to the folder where you want to create your project.
  2. Open command prompt or Windows PowerShell as administrator.
  3. Run the following command.
dotnet new blazorlib -o BlazorGridComponent

It will create a Blazor library project with the name BlazorGridComponent.

Open this project using Visual Studio. You will see a folder structure as shown in the image below.

Solution Blazor Grid-2

There are some predefined files provided in this project. We will delete Component 1. cshtml, ExampleJsInterop.cs, exampleJsInterop.js, and background.png files to make our solution clean. Do not delete styles.css as we will put the CSS definitions for our custom component in this file.

Creating BlazorGrid component

Now, we will add the component view page to our project.

Right-click on the BlazorGridComponent project and then select Add >> New Item. An “Add New Item” dialog box will open; select “Web” from the left panel, then select “Razor View” from the templates panel, and name it BlazorGrid.cshtml. Click Add. Refer to the image below.

Add New Item

Open the BlazorGrid.cshtml file and put the following code into it.

@typeparam TableItem
<table>
    <thead>
        <tr class="jsgrid-grid-header">@GridHeader</tr>
    </thead>
    <tbody>
        @foreach (var item in ItemList)
        {
            <tr class="jsgrid-row-item">@GridRow(item)</tr>
        }
    </tbody>
</table>
<div class="pagination">
    <button class="btn page-button btn-info" onclick=@(async()=>SetPagerSize("back"))>«</button>
    <button class="btn page-button btn-secondary" onclick=@(async()=>NavigateToPage("previous"))>Prev</button>
    @for (int i = startPage; i <= endPage; i++)
    {
        var currentPage = i;
        <button class="btn page-button @(currentPage == curPage ? "current-page" : "")" onclick=@(async()=>updateList(currentPage))>
            @currentPage
        </button>
    }
    <button class="btn page-button btn-secondary" onclick=@(async()=>NavigateToPage("next"))>Next</button>
    <button class="btn page-button btn-info" onclick=@(async()=>SetPagerSize("forward"))>»</button>
    <span class="page-button btn btn-link disabled">Page @curPage of @totalPages</span>
</div>
@functions{
    int totalPages;
    int curPage;
    int pagerSize;
    int startPage;
    int endPage;
    [Parameter]
    RenderFragment GridHeader { get; set; }
    [Parameter]
    RenderFragment<TableItem> GridRow { get; set; }
    [Parameter]
    IEnumerable<TableItem> Items { get; set; }
    [Parameter]
    int PageSize { get; set; }
    IEnumerable<TableItem> ItemList { get; set; }
    protected override async Task OnInitAsync()
    {
        pagerSize = 5;
        curPage = 1;
        ItemList = Items.Skip((curPage - 1) * PageSize).Take(PageSize);
        totalPages = (int)Math.Ceiling(Items.Count() / (decimal)PageSize);
        SetPagerSize("forward");
    }
    public void updateList(int currentPage)
    {
        ItemList = Items.Skip((currentPage - 1) * PageSize).Take(PageSize);
        curPage = currentPage;
        this.StateHasChanged();
    }
    public void SetPagerSize(string direction)
    {
        if (direction == "forward" && endPage < totalPages)
        {
            startPage = endPage + 1;
            if (endPage + pagerSize < totalPages)
            {
                endPage = startPage + pagerSize - 1;
            }
            else
            {
                endPage = totalPages;
            }
            this.StateHasChanged();
        }
        elseif (direction == "back" && startPage > 1)
        {
            endPage = startPage - 1;
            startPage = startPage - pagerSize;
        }
    }
    public void NavigateToPage(string direction)
    {
        if (direction == "next")
        {
            if (curPage < totalPages)
            {
                if (curPage == endPage)
                {
                    SetPagerSize("forward");
                }
                curPage += 1;
            }
        }
        elseif (direction == "previous")
        {
            if (curPage > 1)
            {
                if (curPage == startPage)
                {
                    SetPagerSize("back");
                }
                curPage -= 1;
            }
        }
        updateList(curPage);
    }
}

Let’s understand this code

In the HTML section of the code, we have defined a table. The <thead> section of the table will display the header of the grid as defined in the GridHeader parameter. Similarly, the <tbody> section will iterate through the content of the GridRow parameter to display the data in rows.

We have also defined the HTML of the pagination section. It contains Next and Prev buttons to move through the pages. We have also defined the buttons to navigate to the next set of pages. The default pager size is set to five. This means the page buttons will be displayed in a set of five buttons.

In the functions section, we have defined four parameters for the BlazorGrid component.

  • Items: The list of items supplied to the BlazorGrid.
  • PageSize: Size of each page of BlazorGrid.
  • GridHeader: Header for BlazorGrid.
  • GridRow: Rows for BlazorGrid.

Inside the OnInitAsync method, we are initializing the pagerSize to five and setting the curPage to one. We will calculate the total number of pages and bind the data to the first page of the grid.

The updated list method will be invoked when we click on a page button. It will bind the data to the current page of the grid.

The SetPagerSize method will set the page number in every page set. The page buttons will be displayed in a set of five buttons and if the number of pages is more than five, the page button will be displayed in the next pager set. This method will accept a string parameter and based on the value it will set the page buttons for the next or previous set of five buttons. A demo of the pager set is shown below.

Creating BlazorGrid

The NavigateToPage method will be invoked by clicking the Next or Prev button. It will navigate the user to the immediate next or immediate previous page in the grid.

Adding CSS for BlazorGrid component

Open the "/content/styles.css" file and put the following code into it.

.jsgrid-grid-header {
    text-align: center;
    border-collapse: collapse;
    background: #ebebeb;
}
.jsgrid-row-item:hover {
    background: #9fcdf4;
}
th, td {
    padding: 15px;
    border: 1px solid #d1d1d1;
    text-align: center;
}
.pagebutton {
    margin-right: 5px;
    margin-top: 5px;
}
.currentpage {
    background-color: dodgerblue;
    color: white;
}

In this file, we have defined styling for the BlazorGrid component. Now, we will use this component in a Blazor project.

Create a Blazor web application

Open Visual Studio and select File >> New >> Project.

After selecting the project, a “New Project” dialog will open. Select .NET Core inside the Visual C# menu from the left panel. Then, select “ASP.NET Core Web Application” from the available project types. Put the name of the project as TestApplication and press OK.

After clicking on OK, a new dialog will open asking you to select the project template. You can observe two drop-down menus at the top left of the template window. Select “.NET Core” and “ASP.NET Core 2.1” from these dropdowns. Then, select the “Blazor” template and press OK. Refer to the image below.

.NET Core-

Adding the BlazorGrid component to the Blazor project

To include the BlazorGridComponent project in this Blazor project, follow the steps mentioned below.

  1. Right-click on the solution and select Add >> Existing item.
  2. Browse to the BlazorGridComponent library, select the BlazorGridComponent.csproj file, and click Add.

This will include the BlazorGridComponent project in the current solution. Refer to the image below.

Solution Test Application-

The next step is to add the reference to the shared component. Right-click “TestApplication\Dependencies”. Select "Add Reference..." Then, select BlazorGridComponent project and click OK. Refer to the image below.

Reference Manager-

The final step is to add the following line to the "TestApplication\ _ViewImports.cshtml" file.

This will allow us to use the shared BlazorGridComponent in our TestApplication project.

Using BlazorGrid component

Open "TestApplication\Pages\FetchData.cshtml" file. In the HTML section of the code put the following lines inside the else section.

<BlazorGrid Items="@forecasts" PageSize="4">
    <GridHeader>
        <th>Date</th>
        <th>TemperatureC</th>
        <th>TemperatureF</th>
        <th>Summary</th>
    </GridHeader>
    <GridRow>
        <td>@context.Date.ToShortDateString()</td>
        <td>@context.TemperatureC</td>
        <td>@context.TemperatureF</td>
        <td>@context.Summary</td>
    </GridRow>
</BlazorGrid>

The name of the HTML tag will be the same as the file name of our component, which is <BlazorGrid> in this case. We are setting the value of the Items parameter to forecasts. We have set the PageSize to 4 which means the grid will display four items on each page. The headers for the Grid are defined in <GridHeader>.

Inside the <GridRow> we have declared the row items for our grid using the implicit parameter “context”. The Blazor framework provides this and we need to use it to initialize the arguments of type RenderFragment<T>, which is GridRow in this case.

Execution demo: Run the application and navigate to the Fetch data page. You will see the data is being displayed in a Grid fashion as shown in the image below.

Weather forecast-

Conclusion

We have created a shared Blazor component – BlazorGrid. It displays the user data in a grid. This component also provides client-side pagination. We learned how to reference and use the shared component in a Blazor application.

Get the source code from GitHub and play around to get a better understanding.

You can also read my other articles on my blog here.


Similar Articles