ASP.NET Core 2.2 - Bootstrap 4 Tables

This article will demonstrate some of the Bootstrap 4 table css classes I will use in upcoming articles about table functions. I will assume you have created a new ASP.NET Core 2.2 Razor Pages project. I won't use Identity or Individual User Accounts.

The FREE ASP.NET Core 6.0 - Demos And Utilities Project includes a Table Functions Demo. Access to the source code is free for registered users at Manage > Assets.

After you have implemented In Memory Entities, the entities are dynamically displayed in a simple Razor/Bootstrap table. A few table classes like table-hover, table-striped and table-sm can improve the presentation. Although the table is responsive, entities with many properties can crowd small screens. If you offer a details page, you can hide columns on Bootstrap beakpoints.

Let's start with the Food class. You can add DataAnotations to modify the DisplayNameFor property and format the date.

Edit Food.cs, add DataAnotations:
public class Food
{
    [Key]
    public int Id { get; set; }
    public string Name { get; set; }
    [Display(Name = "Food Type")]
    public FoodType FoodType { get; set; }
    [Display(Name = "Store Cold")]
    public bool ColdStore { get; set; }
    [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy hh:mm tt}")]
    public DateTime Date { get; set; }
}

There are plenty of articles about the table classes. I like the table-sm class because it displays more data per window. The table-striped class is applealing but has the same backgroud color as the table-hover class. The table-striped class applies a .05 opacity to odd rows and the table-hover applies a .075 opacity.

Edit Index.cshtml, add the table, th and td classes:
<div class="row">
    <div class="col-12">
        <table class="table table-sm table-striped table-hover border-bottom">
            <thead>
                <tr>
                    <th class="d-none d-lg-table-cell">
                        @Html.DisplayNameFor(model => model.Foods[0].Id)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Foods[0].Name)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Foods[0].FoodType)
                    </th>
                    <th class="d-none d-md-table-cell text-center">
                        @Html.DisplayNameFor(model => model.Foods[0].ColdStore)
                    </th>
                    <th class="d-none d-lg-table-cell">
                        @Html.DisplayNameFor(model => model.Foods[0].Date)
                    </th>
                </tr>
            </thead>
            <tbody>
                @if (Model.Foods.Count > 0)
                {
                    foreach (var item in Model.Foods)
                    {
                        <tr>
                            <td class="d-none d-lg-table-cell">
                                @Html.DisplayFor(modelItem => item.Id)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Name)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.FoodType)
                            </td>
                            <td class="custom-control custom-checkbox text-center d-none d-md-table-cell">
                                <input type="checkbox" asp-for="@item.ColdStore">
                                <input type="checkbox" class="custom-control-input disabled" asp-for="@item.ColdStore">
                                <label class="custom-control-label disabled">
                                    <span class="sr-only">Never</span>
                                </label>
                            </td>
                            <td class="d-none d-lg-table-cell">
                                @Html.DisplayFor(modelItem => item.Date)
                            </td>
                        </tr>
                    }
                }
                else
                {
                    <tr>
                        <td colspan="5" class="text-center">
                            No Food Found
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
</div>

You can override the colors of the striped and hover table row classes to provide more contrast.

Edit site.css, add Bootstrap overrides:
.table-striped > tbody > tr:nth-child(2n+1) > td, .table-striped > tbody > tr:nth-child(2n+1) > th {
    background-color: lightgray;
}

.table-hover tbody tr:hover td, .table-hover tbody tr:hover th {
    background-color: gray;
    color: white;
}

You can add a details page to display the hidden columns on small screens. Right click on the Pages folder to add a new page.

Add Razor Page Menu.
Razor Page Using Entity Framework.
Add Razor Page Using Entity Framework.

You can add the custom checkbox and remove the Edit link on the Details page.

Edit Details.cshtml:
<div>
    <h4>Food</h4>
    <hr />
    <dl class="row">
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Food.Name)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Food.Name)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Food.FoodType)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Food.FoodType)
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Food.ColdStore)
        </dt>
        <dd class="col-sm-10">
            <div class="custom-control custom-checkbox">
                <input type="checkbox" class="custom-control-input" asp-for="@Model.Food.ColdStore">
                <label class="custom-control-label">
                    <span class="sr-only">Never</span>
                </label>
            </div>
        </dd>
        <dt class="col-sm-2">
            @Html.DisplayNameFor(model => model.Food.Date)
        </dt>
        <dd class="col-sm-10">
            @Html.DisplayFor(model => model.Food.Date)
        </dd>
    </dl>
</div>
<div>
    <a asp-page="./Index">Back to List</a>
</div>

Add an Actions column to the table with a link to the Details page.

Edit Index.cshtml, add the column:
<div class="row">
    <div class="col-12">
        <table class="table table-sm table-striped table-hover border-bottom">
            <thead>
                <tr class="d-none d-lg-table-cell">
                    <th>
                        @Html.DisplayNameFor(model => model.Foods[0].Id)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Foods[0].Name)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.Foods[0].FoodType)
                    </th>
                    <th class="d-none d-md-table-cell text-center">
                        @Html.DisplayNameFor(model => model.Foods[0].ColdStore)
                    </th>
                    <th class="d-none d-lg-table-cell">
                        @Html.DisplayNameFor(model => model.Foods[0].Date)
                    </th>
                    <th>
                        Actions
                    </th>
                </tr>
            </thead>
            <tbody>
                @if (Model.Foods.Count > 0)
                {
                    @foreach (var item in Model.Foods)
                    {
                        <tr>
                            <td class="d-none d-lg-table-cell">
                                @Html.DisplayFor(modelItem => item.Id)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.Name)
                            </td>
                            <td>
                                @Html.DisplayFor(modelItem => item.FoodType)
                            </td>
                            <td class="custom-control custom-checkbox text-center d-none d-md-table-cell">
                                <input type="checkbox" asp-for="@item.ColdStore">
                                <input type="checkbox" class="custom-control-input disabled" asp-for="@item.ColdStore">
                                <label class="custom-control-label disabled">
                                    <span class="sr-only">Never</span>
                                </label>
                            </td>
                            <td class="d-none d-lg-table-cell">
                                @Html.DisplayFor(modelItem => item.Date)
                            </td>
                            <td>
                                <a asp-page="/Details" asp-route-id="@item.Id">Details</a>
                            </td>
                        </tr>
                    }
                }
                else
                {
                    <tr>
                        <td colspan="6" class="text-center">
                            No Food Found
                        </td>
                    </tr>
                }
            </tbody>
        </table>
    </div>
</div>

Build, run and test.

Formatted Table Desktop.
Details Page.
Formatted Table Mobile.
Update 12/30/2021

Announced the ASP.NET Core 6.0 - Demos And Utilities Project. Updated articles, asset and topic links.

Ken Haggerty
Created 08/17/19
Updated 08/28/22 02:14 GMT

Log In or Reset Quota to read more.

Article Tags:

Bootstrap Model Scaffold
Successfully completed. Thank you for contributing.
Processing...
Something went wrong. Please try again.
Contribute to enjoy content without advertisments.
You can contribute without registering.

Comments(0)

Loading...
Loading...

Not accepting new comments.

Submit your comment. Comments are moderated.

User Image.
DisplayedName - Member Since ?