twitter-bootstrapblazorbootstrap-grid

How do I highlight a grid row on hover and make it selected on click in Bootstrap?


I am loading data to a grid with 3 columns in Blazor. For the grid structure I have used Bootstrap rows and columns. If I need to highlight rows on hover and keep the row selected using onClick event what is the best way to achieve it?

Below is how I populate data.

<div class="container-fluid">
    <div class="row">
        <div class="col">User Name</div>
        <div class="col">First Name</div>
        <div class="col">Last Name</div>
    </div>

    @foreach (var user in users)
    {
        <div class="row">
            <div class="col">@user.UserName</div>
            <div class="col">@user.FirstName</div>
            <div class="col">@user.LastName</div>
        </div>
    }
</div>

Thanks.


Solution

  • You need to maintain the rows selected state. Here is a generic view model to wrap any row type:

    public class RowState<TItem>
    {
        public RowState(TItem item) => Item = item;
        public TItem Item { get; set; }
        public bool IsSelected { get; set; }
    }
    
    

    Then using style classes for both selected and hover:

    .hover-row:hover {
        background-color: #0000ff33;
    }
    
    .selected-row {
        background-color: #0000ff77;
    }
    

    I seperated the row into its own component UserRow.razor with a [Parameter] that takes the RowState<User> viewmodel.

    This simplifies the logic to handle the click event and logic for the css class to highlight the row.

    UserRow.razor

    <div class="row hover-row @CssClass" @onclick="RowClicked" >
        <div class="col">@User.UserName</div>
        <div class="col">@User.FirstName</div>
        <div class="col">@User.LastName</div>
    </div>
    
    @code {
        [Parameter]
        public RowState<User> UserRowState { get; set; }   
    
        private void RowClicked() => UserRowState.IsSelected = !UserRowState.IsSelected;
    
        private User User => UserRowState.Item;
        private bool IsSelected => UserRowState.IsSelected;
        private string CssClass => IsSelected ? "selected-row" : "";
    }
    

    Refactoring your original code:

    <div class="container-fluid">
        <div class="row">
            <div class="col">User Name</div>
            <div class="col">First Name</div>
            <div class="col">Last Name</div>
        </div>
    
        @foreach (var user in UserRows)
        {
            <UserRow UserRowState=user />     
        }
    </div>
    
    @code {
        IEnumerable<RowState<User>> UserRows = User.DemoData
            .Select(user => new RowState<User>(user))
            .ToList();
    }
    

    Here is a working REPL