在 Bootstrap 中,如何在悬停时突出显示网格行并使其在单击时被选中?
How do I highlight a grid row on hover and make it selected on click in Bootstrap?
我正在将数据加载到 Blazor 中具有 3 列的网格。对于网格结构,我使用了 Bootstrap 行和列。如果我需要在悬停时突出显示行并使用 onClick 事件保持选中行,实现它的最佳方法是什么?
下面是我如何填充数据。
<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>
谢谢。
您可以利用 Radio toggle buttons (for single selection) or Checkbox toggle buttons (for multiple) as Block buttons 只需一点自定义样式。将整个用户行放在标签内,并使用用户名或其他唯一字段作为输入 ID。
这是一个使用单选按钮的例子:
label.btn {
border: none;
border-radius: 0;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<div class="container-fluid">
<div class="row">
<div class="col-4">User Name</div>
<div class="col-4">First Name</div>
<div class="col-4">Last Name</div>
</div>
<div class="row">
<!-- @foreach (var user in users)
{ -->
<div class="col-12 d-grid p-0">
<input type="radio" class="btn-check" name="options" id="@user.UserName" autocomplete="off">
<label class="btn btn-outline-dark text-start" for="@user.UserName">
<div class="row">
<div class="col-4">@user.UserName</div>
<div class="col-4">@user.FirstName</div>
<div class="col-4">@user.LastName</div>
</div>
</label>
</div>
<!-- } -->
<div class="col-12 d-grid p-0">
<input type="radio" class="btn-check" name="options" id="@user.UserName2" autocomplete="off">
<label class="btn btn-outline-dark text-start" for="@user.UserName2">
<div class="row">
<div class="col-4">@user.UserName2</div>
<div class="col-4">@user.FirstName</div>
<div class="col-4">@user.LastName</div>
</div>
</label>
</div>
<div class="col-12 d-grid p-0">
<input type="radio" class="btn-check" name="options" id="@user.UserName3" autocomplete="off">
<label class="btn btn-outline-dark text-start" for="@user.UserName3">
<div class="row">
<div class="col-4">@user.UserName3</div>
<div class="col-4">@user.FirstName</div>
<div class="col-4">@user.LastName</div>
</div>
</label>
</div>
</div>
</div>
<table class="table table-hover">
<tr>
<td >User Name</td>
<td >First Name</td>
<td >Last Name</td>
</tr>
@foreach (var user in users)
{
string bg = (user.Id == selectedUserId)? "bg-info" : "";
<tr class=@bg @onclick=@SelectUser(user.Id) @key=user>
<td >@user.UserName</td>
<td >@user.FirstName</td>
<td >@user.LastName</td>
</tr>
}
@code{
private int selectedUserId {get;set;} = 0;
private void SelectUser(int userId){
selectedUserId = userId;
}
}
您需要保持行的选定状态。
这是包装任何行类型的通用视图模型:
public class RowState<TItem>
{
public RowState(TItem item) => Item = item;
public TItem Item { get; set; }
public bool IsSelected { get; set; }
}
然后对选中和悬停使用样式 classes:
.hover-row:hover {
background-color: #0000ff33;
}
.selected-row {
background-color: #0000ff77;
}
我将行分隔成它自己的组件 UserRow.razor
,其中 [Parameter]
采用 RowState<User>
视图模型。
这简化了处理点击事件的逻辑和 css class 突出显示该行的逻辑。
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" : "";
}
重构您的原始代码:
<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();
}
这是一个有效的 REPL
JavaScript 答案中的 None 适用于 Blazor。忽略他们。
如果你只想到select单行,你可以使用@Ali Borjian 的回答
为了跟踪select多行的离子,您可以使用以下两种方法之一:
- 使用 class 跟踪每行的状态信息。 这是 Brian 的回答。
- 创建一个辅助列表来跟踪哪些行被 selected。 如下。
.
<div class="container-fluid">
<div class="row">
<div class="col">User ID</div>
<div class="col">User Name</div>
</div>
@foreach (var user in Users)
{
string CSS = SelectedUsers.Contains(user) ? " Selected" : "";
<div class="row @CSS" style="" @onclick="()=>ToggleSelection(user)">
<div class="col">@user.ID</div>
<div class="col">@user.Name</div>
</div>
}
</div>
@code {
class User { public int ID; public string Name; }
List<User> Users = new List<User> { new User { ID = 1, Name = "Benjamin" }, new User { ID = 2, Name = "John" }, new User { ID = 3, Name = "David" } };
List<User> SelectedUsers = new();
void ToggleSelection(User user)
{
if (SelectedUsers.Any(u => u == user)) SelectedUsers.Remove(user);
else SelectedUsers.Add(user);
}
}
<style>
.row {cursor:pointer}
.row:hover { background-color:#c2d8ff }
.Selected {background-color: #4781e9}
.Selected:hover {background-color: #83aefb}
</style>
我正在将数据加载到 Blazor 中具有 3 列的网格。对于网格结构,我使用了 Bootstrap 行和列。如果我需要在悬停时突出显示行并使用 onClick 事件保持选中行,实现它的最佳方法是什么?
下面是我如何填充数据。
<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>
谢谢。
您可以利用 Radio toggle buttons (for single selection) or Checkbox toggle buttons (for multiple) as Block buttons 只需一点自定义样式。将整个用户行放在标签内,并使用用户名或其他唯一字段作为输入 ID。
这是一个使用单选按钮的例子:
label.btn {
border: none;
border-radius: 0;
}
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<div class="container-fluid">
<div class="row">
<div class="col-4">User Name</div>
<div class="col-4">First Name</div>
<div class="col-4">Last Name</div>
</div>
<div class="row">
<!-- @foreach (var user in users)
{ -->
<div class="col-12 d-grid p-0">
<input type="radio" class="btn-check" name="options" id="@user.UserName" autocomplete="off">
<label class="btn btn-outline-dark text-start" for="@user.UserName">
<div class="row">
<div class="col-4">@user.UserName</div>
<div class="col-4">@user.FirstName</div>
<div class="col-4">@user.LastName</div>
</div>
</label>
</div>
<!-- } -->
<div class="col-12 d-grid p-0">
<input type="radio" class="btn-check" name="options" id="@user.UserName2" autocomplete="off">
<label class="btn btn-outline-dark text-start" for="@user.UserName2">
<div class="row">
<div class="col-4">@user.UserName2</div>
<div class="col-4">@user.FirstName</div>
<div class="col-4">@user.LastName</div>
</div>
</label>
</div>
<div class="col-12 d-grid p-0">
<input type="radio" class="btn-check" name="options" id="@user.UserName3" autocomplete="off">
<label class="btn btn-outline-dark text-start" for="@user.UserName3">
<div class="row">
<div class="col-4">@user.UserName3</div>
<div class="col-4">@user.FirstName</div>
<div class="col-4">@user.LastName</div>
</div>
</label>
</div>
</div>
</div>
<table class="table table-hover">
<tr>
<td >User Name</td>
<td >First Name</td>
<td >Last Name</td>
</tr>
@foreach (var user in users)
{
string bg = (user.Id == selectedUserId)? "bg-info" : "";
<tr class=@bg @onclick=@SelectUser(user.Id) @key=user>
<td >@user.UserName</td>
<td >@user.FirstName</td>
<td >@user.LastName</td>
</tr>
}
@code{
private int selectedUserId {get;set;} = 0;
private void SelectUser(int userId){
selectedUserId = userId;
}
}
您需要保持行的选定状态。 这是包装任何行类型的通用视图模型:
public class RowState<TItem>
{
public RowState(TItem item) => Item = item;
public TItem Item { get; set; }
public bool IsSelected { get; set; }
}
然后对选中和悬停使用样式 classes:
.hover-row:hover {
background-color: #0000ff33;
}
.selected-row {
background-color: #0000ff77;
}
我将行分隔成它自己的组件 UserRow.razor
,其中 [Parameter]
采用 RowState<User>
视图模型。
这简化了处理点击事件的逻辑和 css class 突出显示该行的逻辑。
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" : "";
}
重构您的原始代码:
<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();
}
这是一个有效的 REPL
None 适用于 Blazor。忽略他们。
如果你只想到select单行,你可以使用@Ali Borjian 的回答
为了跟踪select多行的离子,您可以使用以下两种方法之一:
- 使用 class 跟踪每行的状态信息。 这是 Brian 的回答。
- 创建一个辅助列表来跟踪哪些行被 selected。 如下。
.
<div class="container-fluid">
<div class="row">
<div class="col">User ID</div>
<div class="col">User Name</div>
</div>
@foreach (var user in Users)
{
string CSS = SelectedUsers.Contains(user) ? " Selected" : "";
<div class="row @CSS" style="" @onclick="()=>ToggleSelection(user)">
<div class="col">@user.ID</div>
<div class="col">@user.Name</div>
</div>
}
</div>
@code {
class User { public int ID; public string Name; }
List<User> Users = new List<User> { new User { ID = 1, Name = "Benjamin" }, new User { ID = 2, Name = "John" }, new User { ID = 3, Name = "David" } };
List<User> SelectedUsers = new();
void ToggleSelection(User user)
{
if (SelectedUsers.Any(u => u == user)) SelectedUsers.Remove(user);
else SelectedUsers.Add(user);
}
}
<style>
.row {cursor:pointer}
.row:hover { background-color:#c2d8ff }
.Selected {background-color: #4781e9}
.Selected:hover {background-color: #83aefb}
</style>