Checkbox
JavaScript off: what the HTML and CSS do on their own.
Usage
@* The label comes from the property's [Display(Name)], or Label. *@
<Checkbox @bind-Value="Model!.Subscribe" />
<Checkbox @bind-Value="Model!.RememberMe" Label="Keep me signed in" />
@* A label with markup. *@
<Checkbox @bind-Value="Model!.AcceptTerms">
I agree to the <Anchor Href="terms">terms of service</Anchor>
</Checkbox>Use a checkbox for one yes-or-no choice, such as agreeing to something; a Switch for a setting that reads as on or off, and a CheckboxGroup for several choices from a list.
What it posts
A checked box posts true, and an unchecked one posts false from a hidden field that follows it, so a property that defaults to true can be turned off on a static page. A disabled box posts nothing.
Agreeing to terms
Use ChildContent for a label with markup, such as a link, and [Required] with [Range(typeof(bool), "true", "true")] for a box that must be checked.
Preview
Code
System.ComponentModel.DataAnnotations
<Form Model="Model" FormName="checkbox-terms" OnValidSubmit="Save" MaxWidth="28.Rem" Grow>
<Checkbox @bind-Value="Model!.AcceptLicense">
Publish under the <Anchor Href="https://opensource.org/license/mit" External>MIT license</Anchor>
</Checkbox>
<Row><Button Submit>Publish package</Button></Row>
if (_published)
{
<Alert Status="Status.Success">Published under the MIT license.</Alert>
}
</Form>
{
[SupplyParameterFromForm(FormName = "checkbox-terms")]
private Package? Model { get; set; }
private bool _published;
protected override void OnInitialized() => Model ??= new();
private void Save() => _published = true;
public sealed class Package
{
// [Required] has the browser stop the post until it's checked. A bool is never null, so
// [Required] alone passes on the server: [Range] is the server's check.
[Required(ErrorMessage = "Agree to the license to publish")]
[Range(typeof(bool), "true", "true", ErrorMessage = "Agree to the license to publish")]
[Display(Name = "License")]
public bool AcceptLicense { get; set; }
}
}Off: The browser stops the post until the box is checked, in its own words.
[Required] has the browser stop the post until the box is checked, but a bool is never null, so on the server it always passes: [Range] is the check there. Give both the same ErrorMessage, and with script the browser shows it too.
Select all
Use a CheckboxGroup with SelectAll for a box that checks or clears a list of others at once; the script does it on static pages too.
Preview
Code
System.ComponentModel.DataAnnotations
Microsoft.AspNetCore.Http
<Form Model="Model" FormName="checkbox-group-everything" OnValidSubmit="Save" MaxWidth="24.Rem" Grow>
<CheckboxGroup @bind-Value="Model!.Topics" Items="Enum.GetValues<Topic>()" SelectAll SelectAllText="Everything" />
<Row Gap="3" Align="Align.Center" Wrap>
<Button Submit>Save</Button>
if (_saved is not null)
{
<TextBlock Size="TextSize.Sm" Color="Color.Muted">Last saved: _saved</TextBlock>
}
</Row>
</Form>
{
[SupplyParameterFromForm(FormName = "checkbox-group-everything")]
private Notifications? Model { get; set; }
private string? _saved;
[CascadingParameter] private HttpContext? HttpContext { get; set; }
// With nothing checked the group posts nothing: give the defaults only when this form didn't post.
protected override void OnInitialized()
{
var posted = HttpContext?.Request.HasFormContentType == true
&& HttpContext.Request.Form["_handler"] == "checkbox-group-everything";
Model ??= posted ? new() : new() { Topics = [Topic.Comments] };
}
// What was saved, not the field: on an interactive page it changes as boxes are checked.
private void Save() => _saved = Model!.Topics is { Count: > 0 } topics
? string.Join(", ", Enum.GetValues<Topic>().Where(topics.Contains)) + "."
: "nothing.";
public sealed class Notifications
{
[Display(Name = "Notify me about")]
public List<Topic>? Topics { get; set; } = [];
}
public enum Topic { Comments, Mentions, Releases }
}Off: The Everything box isn't shown, since it needs the script: check each topic.
A dash of your own
Use Indeterminate to show a dash when only some of what a box stands for is checked, and set the others from its ValueChanged on an interactive page.
Always Live
Preview
This example runs C# over a Blazor Server connection, which an Off page doesn't have. Show this page Live
Code
@* Interactive pages only: C# sets the dash and all three. On a static page, use a CheckboxGroup's
SelectAll, which the script runs. *@
<Form Model="Model" FormName="checkbox-select-all" MaxWidth="24.Rem" Grow>
<Column Gap="2">
<Checkbox Value="AllOn" ValueChanged="SetAll" ValueExpression="() => Model!.Everything"
Indeterminate="SomeOn" Label="Notify me about everything" />
<Column Gap="2" PaddingStart="6">
<Checkbox @bind-Value="Model!.Comments" />
<Checkbox @bind-Value="Model!.Mentions" />
<Checkbox @bind-Value="Model!.Releases" />
</Column>
</Column>
</Form>
{
[SupplyParameterFromForm(FormName = "checkbox-select-all")]
private Notifications? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
// The top box is worked out from the three below.
private bool AllOn => Model!.Comments && Model.Mentions && Model.Releases;
private bool SomeOn => !AllOn && (Model!.Comments || Model.Mentions || Model.Releases);
// Checking the top box sets all three.
private void SetAll(bool on) => Model!.Comments = Model.Mentions = Model.Releases = on;
public sealed class Notifications
{
public bool Everything { get; set; }
public bool Comments { get; set; } = true;
public bool Mentions { get; set; }
public bool Releases { get; set; }
}
}Nothing links the boxes but your C#, so this works on an interactive page only; on a static page, use SelectAll.
Hints, icons and the end of the row
Use Hint for help under the label, ControlPosition.End to put the box at the end of the row and Icon for an icon at its start, as on a Switch (see them there).
Sizes and disabled
Use Size to line up with buttons and other fields, and Disabled for a box that can't change, which doesn't post. There's no ReadOnly: HTML has no read-only checkbox, and in a read-only Form the box is disabled while a hidden field posts its value.
Preview
Code
<Form Model="Model" FormName="checkbox-sizes" Grow>
<Row Gap="5" Wrap>
<Checkbox @bind-Value="Model!.Small" Label="Small" Size="ControlSize.Sm" />
<Checkbox @bind-Value="Model!.Medium" Label="Medium" />
<Checkbox @bind-Value="Model!.Large" Label="Large" Size="ControlSize.Lg" />
</Row>
<Row Gap="5" Wrap>
<Checkbox @bind-Value="Model!.Locked" Label="Disabled" Disabled />
<Checkbox @bind-Value="Model!.LockedOn" Label="Disabled, checked" Disabled />
</Row>
</Form>
{
[SupplyParameterFromForm(FormName = "checkbox-sizes")]
private Options? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
public sealed class Options
{
public bool Small { get; set; } = true;
public bool Medium { get; set; } = true;
public bool Large { get; set; } = true;
public bool Locked { get; set; }
public bool LockedOn { get; set; } = true;
}
}A disabled field posts nothing, so after a static post its property holds its default (false): keep its value on the server rather than saving it from the post.
Mode support
| Feature | Off | Static | Live |
|---|---|---|---|
| Everything | Yes | Yes | Yes |
Off: JavaScript disabled. Static: a static SSR page with IzzyBlazor's script. Live: an interactive page (Server, WebAssembly or Auto).
Accessibility
- It renders a native checkbox inside its
label, so Space toggles it and clicking the label does too. - The label text, or
ChildContent, names it; the hint and errors are linked witharia-describedby, and anIconbeside it is hidden from screen readers. - With script, an unchecked indeterminate box is announced as "mixed"; with JavaScript off, only the dash shows it and screen readers hear "not checked". A checked box is "checked" either way, with no dash.
Parameters
| Prop | Type | Default |
|---|---|---|
ChildContentRich label content, such as text with a link. | RenderFragment? | |
IndeterminateShows the box as partly selected (a dash), such as a "select all" box when only some items are. | bool | false |
ControlPositionWhich side of the label the box or switch sits on. | ControlPosition | ControlPosition.Start |
IconAn icon before the label, such as a key for a security setting. | IconData? | |
@bind-ValueThe value, bound with @bind-Value. | bool | false |
DisplayNameThe field's name in validation messages from the input itself, such as a value that can't be parsed. | string? |
Plus 26 field props.
Full APISee also
- Switch: an on/off switch that posts like a checkbox.
- CheckboxGroup: several choices as checkboxes.
- RadioGroup: one choice from a list of radios.