Skip to content
IzzyBlazor 0.1.0-alpha.20

Enter all results ↑ ↓ move Esc close

Selection

Since 0.1.0-alpha.20
Checkboxes or radio buttons select items. The selection posts with a form or binds to C#.

Static server-side rendering: no circuit, no WebAssembly.

Selection

Each item can have a checkbox, or a radio button for a single choice. Set SelectionMode to Multiple for checkboxes, or Single for radio buttons. Inside a form, the selected items post their ItemKey as a Selection. On interactive pages, @bind-Selection reads and sets it from C#. SelectAllMode sets what select-all selects: the current page, or every matching item. With IzzyBlazor's script, a checkbox above the list selects the page.

Preview

  • Quarterly report draftGrace Hopper
  • Lunch on Friday?Alan Turing
  • Build failed on mainCI
  • Invoice #1042Billing

Code

SelectItems.razor
@* Selection in a form: each checked item posts its ItemKey, so Archive works with JavaScript off.
   With script, "Select all messages" above the list checks the page. Archived messages leave the
   list; on static pages hidden fields carry them to the next post. *@
<form method="post" @onsubmit="Submit" @formname="list-view-archive" style="width: 100%; max-width: 28rem">
    <AntiforgeryToken />
    @foreach (var id in _archived)
    {
        <input type="hidden" name="archived" value="@id" />
    }
    <Stack Gap="3">
        <ListView Items="Inbox" ItemKey="m => m.Id" ItemText="m => m.Subject" ItemDescription="m => m.From"
                  SelectionMode="SelectionMode.Multiple" SelectAllLabel="Select all messages" @bind-Selection="_selected" EmptyText="Nothing left in the inbox." Bordered />
        <Row Gap="3" Align="Align.Center" Wrap>
            <Button Submit Variant="ButtonVariant.Outline" Accent="Accent.Neutral" StartIcon="Lucide.Archive" Disabled="Inbox.Count == 0">Archive selected</Button>
            @if (_archived.Count > 0)
            {
                <Button Submit Name="restore" Value="all" OnClick="() => _restoring = true" Variant="ButtonVariant.Ghost" Accent="Accent.Neutral">Restore all</Button>
            }
            <TextBlock Size="TextSize.Sm" Color="Color.Muted" role="status">@_status</TextBlock>
        </Row>
    </Stack>
</form>

@code {
    // Static pages: the checked items post as "selected", and the ones archived before as "archived".
    [SupplyParameterFromForm(FormName = "list-view-archive", Name = "selected")]
    private Selection? Posted { get; set; }

    [SupplyParameterFromForm(FormName = "list-view-archive", Name = "archived")]
    private string[]? PostedArchived { get; set; }

    [SupplyParameterFromForm(FormName = "list-view-archive", Name = "restore")]
    private string? PostedRestore { get; set; }

    // Interactive pages: bound to the checkboxes; Restore all says it was pressed.
    private Selection? _selected;
    private bool _restoring;
    private HashSet<string> _archived = [];
    private string? _status;

    private readonly Message[] _messages =
    [
        new("1", "Quarterly report draft", "Grace Hopper"),
        new("2", "Lunch on Friday?", "Alan Turing"),
        new("3", "Build failed on main", "CI"),
        new("4", "Invoice #1042", "Billing"),
    ];

    private List<Message> Inbox => _messages.Where(m => !_archived.Contains(m.Id)).ToList();

    protected override void OnInitialized()
    {
        _archived = [.. PostedArchived ?? []];
        _selected = Posted;
    }

    private void Submit()
    {
        if (PostedRestore is not null || _restoring)
        {
            _restoring = false;
            _archived.Clear();
            _status = "Restored every message.";
        }
        else
        {
            var picked = (Posted ?? _selected ?? Selection.None).Apply(Inbox.AsQueryable(), m => m.Id).ToList();
            _archived.UnionWith(picked.Select(m => m.Id));
            _status = picked.Count switch
            {
                0 => "Select the messages to archive first.",
                1 => $"Archived \"{picked[0].Subject}\".",
                _ => $"Archived {picked.Count} messages.",
            };
        }

        _selected = Selection.None;
    }
}

Connection lost

Rejoining the server…