So I’m having to ask for help here now after spending the past few nights trying everything and nothing working. This should be so simple. Basically I’m trying to get a value from a checkbox using dotnet 8. The problem is that nothing happens at all when I click the checkbox, after lots of Googling and particularly [this]Blazor Checkbox two-way binding and change event link on StackOverflow. I did note that dotnet 8 has a new [SupplyParameterFromForm] attribute that worked for something else that was always null but not for this.
@page "/Admin/Roles/Update/{Id}"
@layout AdminLayout
@using Microsoft.AspNetCore.Http.Extensions
@using System.Text
@using PersonalWebsiteBlazor.Models
@inject UserManager<AppUser> _userManager
@inject RoleManager<IdentityRole> _roleManager
<h2 class="bg-info p-1">Update Role</h2>
<NavLink class="btn btn-secondary" href="/Admin/Roles" Match="@NavLinkMatch.All">Back</NavLink>
@Message
<EditForm Model="this" FormName="UpdateRole" OnSubmit="HandleSubmit">
<AntiforgeryToken />
<input type="hidden" name="roleName" value="@RoleName" />
<input type="hidden" name="roleId" value="@RoleId" />
<h2 class="bg-info p-1 text-white">Add To @RoleName</h2>
<table class="table table-bordered table-sm">
@if (NonMembers.Count() == 0)
{
<tr><td colspan="2">All Users Are Members</td></tr>
}
else
{
@foreach (AppUser user in NonMembers)
{
<tr>
<td>@user.UserName</td>
<td>
<input type="checkbox" value="@user.Id" checked="@IsChecked" @onchange="CheckboxChecked" />
</td>
</tr>
}
}
</table>
<h2 class="bg-info p-1 text-white">Remove From @RoleName</h2>
<table class="table table-bordered table-sm">
@if (Members.Count() == 0)
{
<tr><td colspan="2">No Users Are Members</td></tr>
}
else
{
@foreach (AppUser user in Members)
{
@if (user is not null)
{
<tr>
<td>@user.UserName</td>
<td>
<input type="checkbox" name="DeleteIds" value="@user.Id" />
</td>
</tr>
}
}
}
</table>
<button type="submit" class="btn btn-primary">Save</button>
</EditForm>
@code {
public string? Message { get; set; } = "Hello World!";
[Parameter]
public bool IsChecked { get; set; } = false;
private void CheckboxChecked()
{
Console.WriteLine(DateTime.Now);
}
[Parameter]
public string Id { get; set; } = default!;
public string? RoleName { get; set; }
public string? RoleId { get; set; }
public List<string> AddIds { get; set; } = new List<string>();
public List<string> DeleteIds { get; set; } = new List<string>();
public List<AppUser> Members { get; set; } = new List<AppUser>();
public List<AppUser> NonMembers { get; set; } = new List<AppUser>();
public IdentityRole? Role { get; set; }
protected override async Task OnParametersSetAsync()
{
IdentityRole? role = await _roleManager.FindByIdAsync(Id);
List<AppUser> members = new List<AppUser>();
List<AppUser> nonMembers = new List<AppUser>();
foreach (AppUser user in _userManager.Users)
{
var list = await _userManager.IsInRoleAsync(user, role!.Name!) ? members : nonMembers;
list.Add(user);
}
Role = role;
Members = members;
NonMembers = nonMembers;
}
public async Task HandleSubmit()
{
StringBuilder sb = new StringBuilder();
foreach (var item in AddIds)
{
sb.Append(item);
}
Message = sb.ToString();
await Task.CompletedTask;
}
}
Relevant bit of code:
@foreach (AppUser user in NonMembers)
{
<tr>
<td>@user.UserName</td>
<td>
<input type="checkbox" value="@user.Id" checked="@IsChecked" @onchange="CheckboxChecked" />
</td>
</tr>
}
[Parameter]
public bool IsChecked { get; set; } = false;
private void CheckboxChecked()
{
Console.WriteLine(DateTime.Now);
}
I’m just trying really simple things to just get a value from the checkbox right now.
Basically my question is why is it always null or empty and what is the solution???
Thank you
Douglas
2
Answers
Different from .net7, you need specify server/webassembly interactive render mode to enable interactives https://learn.microsoft.com/en-us/aspnet/core/blazor/components/render-modes?view=aspnetcore-8.0#render-modes.
For Blazor server project,you could try add
@rendermode InteractiveServer
or@rendermode @(new InteractiveServerRenderMode(false))
at top of the razor components. Or you could also specify global render mode in app.razor.If you haven’t specify rendermode any where, it will be "Static server-side rendering" (static SSR). Functions won’t work.
Besides, to "to get a value from a checkbox", you could try pass the userid as a string parameter to the
CheckboxChecked
function.Test
At the moment you have one value and event handler for an array of checkboxes.
I would recommend building a form model that you can use to bind to your form. You can then retrieve this state when the form is submitted. If you use a model that represents your form, each form value is represented by only one object property.
Below is a simplified version of your scenario to demonstrate the concept. I have a link to a full working example of your scenario at the end.
html
code
The main thing to note here is that I am using
@bind-value
on the checkboxes to perform two-way binding between the checkbox and the model. You can then access this bound state at any point – crucially at the point that the form is submitted.Full working example: https://blazorfiddle.com/s/aihbmdqt