Thursday, 09 July 2020
Imagine you need to ensure at least one checkbox is checked from a group of checkboxes. It does not matter which one, but it must be one of them. This is how to do it in Blazor.
This article was published at GitHub. It is open source and you can make edits, comments etc.
Sometimes in a HTML form you need to present a choice of options and you need the user to select at least one. It may not matter which one or if more than one is selected, but at least one choice is mandatory.
Examples could include toppings on a pizza or permissions for a user.
In Blazor, you can easily validate against whether a checkbox is checked or not (see Blazor Forms and Validation) but validating that one of many is checked is a little more involved.
I had this requirement for a project recently and this is how I figured it out.
You can see the code and a working sample for this article at https://github.com/martinkearn/Blazor-Checkbox-Group, all the code featured in this article is in Index.razor.
This is the full code for the solution. The only other thing you'll need to is add to a standard Blazor template is to add the following to _Imports.razor
@using System.ComponentModel
@using System.ComponentModel.DataAnnotations
This is all in a razor page. In my GitHub sample it is in Index.razor
but could be anywhere.
@page "/"
<h1>Blazor-Checkbox-Group</h1>
<EditForm EditContext="editContext" OnSubmit="HandleSubmit">
<p>Make at least one choice...</p>
<p>
<label>
Choice A:
<InputCheckbox type="checkbox" id="choiceA" @bind-Value="model.ChoiceA" />
</label>
</p>
<p>
<label>
Choice B:
<InputCheckbox type="checkbox" id="choiceA" @bind-Value="model.ChoiceB" />
</label>
</p>
<p>
<label>
Choice C:
<InputCheckbox type="checkbox" id="choiceA" @bind-Value="model.ChoiceC" />
</label>
</p>
<button type="submit">Submit</button>
<DataAnnotationsValidator />
<ValidationSummary />
</EditForm>
@if (formIsValid)
{
<p>The form is valid, well done for checking at least one of the checkboxes.</p>
}
@code{
ModelForForm model;
EditContext editContext;
bool formIsValid;
protected override void OnInitialized()
{
model = new ModelForForm();
editContext = new EditContext(model);
}
private void HandleSubmit()
{
var isValid = editContext.Validate();
if (isValid)
{
// Set form is valid for the purposes of the sample, just to show that the form is valid.
formIsValid = true;
}
else
{
return;
}
}
private class ModelForForm
{
public bool ChoiceA { get; set; }
public bool ChoiceB { get; set; }
public bool ChoiceC { get; set; }
[Required]
[Range(typeof(bool), "true", "true", ErrorMessage = "At least one choice is required.")]
public bool OneChoiceSelected
{
get
{
return ((ChoiceA) || (ChoiceB) || (ChoiceC));
}
set { }
}
}
}
The key feature here is the OneChoiceSelected
property.
OneChoiceSelected
is a property that represents the full group of checkboxes and is Required
.
As well as being required, you can see that I have set a Range
attribute which ensures the property's value is true
. If it is not true the ErrorMessage
will be shown and the model will fail validation.
The clever bit (at least it is clever for me) is that the get
for OneChoiceSelected
is:
get
{
return ((ChoiceA) || (ChoiceB) || (ChoiceC));
};
This means that if any of the bool
properties are true
then OneChoiceSelected
is also true
. If they are all false
, then OneChoiceSelected
is also false
.
The rest of the form is standard Blazor model binding and validation where each choice has its own <InputCheckBox>
.
See Built-in forms components for details of how this works.
This is an elegant Blazor solution for ensuring that at least one of many checkboxes are checked.
The solution uses built in validation, conventions and data annotations.
Got a comment?
All my articles are written and managed as Markdown files on GitHub.
Please add an issue or submit a pull request if something is not right on this article or you have a comment.
If you'd like to simply say "thanks", then please send me a .