问题
I was looking for a way to use the value attribute on radio button tag helper to inform if the button was checked or not, instead of using a separate field for selection. I found an answer by @Shyju to a related question. I am using a modified example of that answer to show what I mean.
Let's say I have a viewmodel
public class ExampleViewModel
{
public int Id { get; set; }
public string UserName { get; set; }
public List<UserRole> Roles { get; set; }
}
public class UserRole
{
public int Id { get; set; }
public string RoleName { get; set; }
public bool IsSelected { get; set; }
}
that is initialized in controller
public IActionResult Example()
{
var vm = new ExampleViewModel
{
Roles = new List<UserRole>
{
new UserRole {Id = 1, RoleName = "Admin"},
new UserRole {Id = 2, RoleName = "Editor"},
new UserRole {Id = 3, RoleName = "Reader"}
}
};
return View("Example",vm);
}
and used in view
<form asp-controller="Example" asp-action="Save">
<label class="label">User name</label>
<div class="col-md-10">
<input asp-for="UserName" type="text" />
</div>
<label class="label">Select a Role</label>
<div class="col-md-10">
<div class="btn-group" data-toggle="buttons">
@for (var i = 0; i < Model.Roles.Count; i++)
{
<label class="btn btn-default">
<input asp-for="Roles[i].Id" type="radio" value="@Model.Roles[i].Id" />
<input asp-for="Roles[i].IsSelected" type="radio" value=true />
@Model.Roles[i].RoleName
</label>
}
</div>
</div>
<input type="submit" />
</form>
What I would like to achieve with this, is to be able to read the UserRole.IsSelected field in controller's post method to see if the particular UserRole was checked or not. This solution works if the user checks only one button and does not alter the choice. If the user changes selection to another, then all UserRole values the user has touched will have the IsSelected field as true.
Is it possible to somehow set the IsSelected value with HTML to show only the button that is checked when the form is submitted or does it require a JavaScript function?
回答1:
Your models do not make sense for radio buttons (which are for choosing one from many). If you want to select only one role, then you models need to be
public class ExampleViewModel
{
public int Id { get; set; }
public string UserName { get; set; }
public int SelectedRole { get; set; }
public List<UserRole> RolesList { get; set; }
}
public class UserRole
{
public int Id { get; set; }
public string RoleName { get; set; }
}
and in the view
@foreach(var role < Model.RolesList)
{
<label class="btn btn-default">
<input asp-for=SelectedRole" type="radio" value="role.Id" />
<span>@role.RoleName<span>
</label>
}
and in the POST method, the value of SelectedRole
will contain the Id
of the selected UserRole
If alternatively, you want to select multiple roles, the use you existing models, but the view becomes
@for (var i = 0; i < Model.Roles.Count; i++)
{
<label class="btn btn-default">
<input asp-for="Roles[i].Id" type="hidden"/>
<input asp-for="Roles[i].IsSelected" type="checkbox"/>
<span>@Model.Roles[i].RoleName</span>
</label>
}
and in the POST method, you can get the selected roles using
IEnumerable<UserRole> selectedRoles = model.Roles.Where(x => x.IsSelected);
来源:https://stackoverflow.com/questions/38466900/is-it-possible-to-set-radio-button-tag-helper-value-attribute-as-checked-in-ht