Skip to content
IzzyBlazor 0.1.0-alpha.20

Enter all results ↑ ↓ move Esc close

DurationField

Since 0.1.0-alpha.20
A length of time, with a box for each unit.

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

A length of time.

Usage

razor
<DurationField @bind-Value="Model.Timeout" />
<DurationField @bind-Value="Model.Runtime" SmallestUnit="DurationUnit.Minutes" />
<DurationField @bind-Value="Model.Retention" LargestUnit="DurationUnit.Days" SmallestUnit="DurationUnit.Hours" Max="TimeSpan.FromDays(90)" />

Units and limits

Use LargestUnit and SmallestUnit for the boxes it shows. Min and Max come from [Range], or set them on the field; the server checks them on submit.

Preview

As hh:mm:ss, or d.hh:mm:ss with days.

From a second to an hour.

As hh:mm:ss, or d.hh:mm:ss with days.

Up to 90 days.

Code

Limits.razor
@using System.ComponentModel.DataAnnotations

<Form Model="Model" FormName="duration-field-limits" OnValidSubmit="Save" MaxWidth="24.Rem" Grow>
    <DurationField @bind-Value="Model!.Timeout" Hint="From a second to an hour." />
    <DurationField @bind-Value="Model!.Retention" LargestUnit="DurationUnit.Days" SmallestUnit="DurationUnit.Hours" Max="TimeSpan.FromDays(90)" Hint="Up to 90 days." />
    <Row><Button Submit>Save settings</Button></Row>
    @if (_saved is { } saved)
    {
        <Alert Status="Status.Success">Saved: time out after @saved.Timeout, keep for @(saved.Retention?.ToString() ?? "no time").</Alert>
    }
</Form>

@code {
    [SupplyParameterFromForm(FormName = "duration-field-limits")]
    private Settings? Model { get; set; }

    // What was saved, not the fields: on an interactive page they follow typing.
    private (TimeSpan Timeout, TimeSpan? Retention)? _saved;

    protected override void OnInitialized() => Model ??= new();

    private void Save() => _saved = (Model!.Timeout!.Value, Model.Retention);

    public sealed class Settings
    {
        [Required, Range(typeof(TimeSpan), "00:00:01", "01:00:00", ErrorMessage = "Pick from a second to an hour.")]
        public TimeSpan? Timeout { get; set; } = TimeSpan.FromSeconds(90);

        public TimeSpan? Retention { get; set; }
    }
}

Steps, signs, sizes, read-only and disabled

Use Step for the increments of the smallest box. A negative Min shows a sign.

Preview

As hh:mm:ss, or d.hh:mm:ss with days.

As hh:mm:ss, or d.hh:mm:ss with days.

As hh:mm:ss, or d.hh:mm:ss with days.

As hh:mm:ss, or d.hh:mm:ss with days.

As hh:mm:ss, or d.hh:mm:ss with days.

Read-only: posted, but can't be changed.

As hh:mm:ss, or d.hh:mm:ss with days.

Disabled: not posted.

As hh:mm:ss, or d.hh:mm:ss with days.

Code

States.razor
<Form Model="Model" FormName="duration-field-states" MaxWidth="24.Rem" Grow>
    <DurationField @bind-Value="Model!.Slot" Label="Quarter hours" SmallestUnit="DurationUnit.Minutes" Step="TimeSpan.FromMinutes(15)" />
    <DurationField @bind-Value="Model!.Offset" Label="Clock offset" Min="TimeSpan.FromHours(-12)" Max="TimeSpan.FromHours(14)" SmallestUnit="DurationUnit.Minutes" />
    <DurationField @bind-Value="Model!.Small" Label="Small" Size="ControlSize.Sm" />
    <DurationField @bind-Value="Model!.Large" Label="Large" Size="ControlSize.Lg" />
    <DurationField @bind-Value="Model!.Signed" Label="Signed length" ReadOnly Hint="Read-only: posted, but can't be changed." />
    <DurationField @bind-Value="Model!.Renews" Label="Renews after" Disabled Hint="Disabled: not posted." />
    <DurationField @bind-Value="Model!.Timeout" Label="Timeout" Clearable />
</Form>

@code {
    [SupplyParameterFromForm(FormName = "duration-field-states")]
    private Contract? Model { get; set; }

    protected override void OnInitialized() => Model ??= new();

    public sealed class Contract
    {
        public TimeSpan? Timeout { get; set; } = TimeSpan.FromMinutes(90);

        public TimeSpan Slot { get; set; } = TimeSpan.FromMinutes(45);
        public TimeSpan Offset { get; set; } = TimeSpan.FromHours(-5);
        public TimeSpan Small { get; set; } = new(1, 30, 0);
        public TimeSpan Large { get; set; } = new(1, 30, 0);
        public TimeSpan Signed { get; set; } = new(26, 0, 0);
        public TimeSpan Renews { get; set; } = new(0, 45, 10);
    }
}

Details

A value past LargestUnit shows in that unit, so 26 hours shows 26 in Hours. Typing 90 in Minutes becomes 1 hour and 30 minutes when the box is left. A value has whole seconds: anything finer is dropped when it posts, and so is anything under SmallestUnit once a box is edited.

Mode support

What works in each mode, DurationField
FeatureStaticInteractive
A number box per unit, days to seconds, posted as one valueYesYes
Min and Max checked on the serverYesYes
Binds TimeSpan, with a sign when Min is negativeYesYes

Static: static server-side rendering, with no circuit and no WebAssembly. Interactive: Server, WebAssembly or Auto.

Without JavaScript

Every page starts as plain HTML: before IzzyBlazor's script loads on a static page, while an interactive page prerenders, and with JavaScript off. With JavaScript off, one text box takes the length as hh:mm:ss, or d.hh:mm:ss with days, in place of a box per unit.

Accessibility

  • The boxes are a group named by the label, each a native number input named by its unit, one tab stop each. Up and Down arrows change a box.
  • A sign shows only when Min is negative or the value is, as a toggle button named "Negative".
  • The hint and errors are linked to the group, and label, hint and errors work as in TextField.

Parameters

DurationField parameters
PropTypeDefault
ClearableA button beside the boxes that empties them, for a nullable value, there while it holds something.boolfalse
ReadOnlyMakes the field read-only: it can be focused, and it still posts.boolfalse
LargestUnitThe largest unit with a box.DurationUnitDurationUnit.Hours
SmallestUnitThe smallest unit with a box.DurationUnitDurationUnit.Seconds
MinThe shortest length, checked on the server.TimeSpan?computed
MaxThe longest length, checked on the server.TimeSpan?computed
StepThe step of SmallestUnit's box, such as 15 minutes: whole units of it, under the next unit up.TimeSpan?
@bind-ValueThe value, bound with @bind-Value.TValue
DisplayNameThe field's name in validation messages from the input itself, such as a value that can't be parsed.string?

See also

  • TimeField: a time of day, in the browser's own input, with a list of times to choose from.
  • NumberField: a number input with stepper buttons.
  • Form: posts on static pages, validates live on interactive ones.

Connection lost

Rejoining the server…