TextArea
An interactive page: C# runs over a Blazor Server connection.
Usage
@* Label, required mark and limits from the model. *@
<TextArea @bind-Value="Model!.Description" />
@* A short bio that grows and counts toward its [StringLength]. *@
<TextArea @bind-Value="Model!.Bio" Rows="2" AutoGrow ShowCount
Hint="Up to 160 characters, shown on your profile." />A text area takes its label, hint, required mark and limits from the model, as a TextField does. Use a text field for one line, such as a name or a title.
Rows and placeholder
Use Rows for how many lines show (4 by default); longer text scrolls, and people can drag the corner to make it taller.
Preview
Code
<Form Model="Model" FormName="text-area-rows" MaxWidth="28.Rem" Grow>
<TextArea @bind-Value="Model!.Notes" Rows="6" Placeholder="Steps to reproduce, what you expected, what happened" />
</Form>
{
[SupplyParameterFromForm(FormName = "text-area-rows")]
private BugReport? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
public sealed class BugReport
{
public string? Notes { get; set; }
}
}A placeholder disappears as people type, so keep anything they need while writing in the Hint.
Growing, with a count
Use AutoGrow to grow with the text from Rows up, and ShowCount to show "n / max" under the field, against the limit from [StringLength], [MaxLength] or MaxLength.
Preview
Code
System.ComponentModel.DataAnnotations
<Form Model="Model" FormName="text-area-count" MaxWidth="28.Rem" Grow>
<TextArea @bind-Value="Model!.Bio" Rows="2" AutoGrow ShowCount Hint="Shown on your public profile." />
</Form>
{
[SupplyParameterFromForm(FormName = "text-area-count")]
private Profile? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
public sealed class Profile
{
[StringLength(160)]
public string? Bio { get; set; } = "Designer at Acme. I draw interfaces, then delete half of them.";
}
}Growing is CSS (field-sizing), so it works with JavaScript off in browsers that support it; others keep the scroll bar and the corner to drag. The count needs a limit, and the browser stops typing at it.
Required, with a length
Use [Required] and [StringLength] with a MinimumLength for the rules, and their ErrorMessage for the words the browser and the server show.
Preview
Code
System.ComponentModel.DataAnnotations
<Form Model="Model" FormName="text-area-feedback" OnValidSubmit="Send" MaxWidth="28.Rem" Grow>
<TextArea @bind-Value="Model!.Message" Label="What could be better?" Rows="3" AutoGrow ShowCount
Hint="20 to 500 characters." />
<Row><Button Submit>Send feedback</Button></Row>
if (_sent is not null)
{
<Alert Status="Status.Success">Thanks: we got your _sent.Length characters.</Alert>
}
</Form>
{
[SupplyParameterFromForm(FormName = "text-area-feedback")]
private Suggestion? Model { get; set; }
// What was sent, not the field: on an interactive page the field follows typing.
private string? _sent;
protected override void OnInitialized() => Model ??= new();
private void Send() => _sent = Model!.Message;
public sealed class Suggestion
{
[Required(ErrorMessage = "Tell us what could be better.")]
[StringLength(500, MinimumLength = 20, ErrorMessage = "Write 20 to 500 characters.")]
public string? Message { get; set; }
}
}Live: The browser checks in the model's words, as on static pages, and Send runs C# without a page load.
The browser checks the minimum only on text someone has typed, so the validator's check after posting is the one to rely on; it also catches text that arrives too long, from a crafted post.
Sizes, read-only and disabled
Use Size to line up with buttons and other fields, ReadOnly for text that posts but can't change, and Disabled for text that doesn't post.
Preview
Code
<Form Model="Model" FormName="text-area-states" MaxWidth="28.Rem" Grow>
<TextArea @bind-Value="Model!.Small" Label="Small" Size="ControlSize.Sm" Rows="2" />
<TextArea @bind-Value="Model!.Large" Label="Large" Size="ControlSize.Lg" Rows="2" />
<TextArea @bind-Value="Model!.Terms" Label="Terms" Rows="2" ReadOnly Hint="Read-only: posted, but can't be changed." />
<TextArea @bind-Value="Model!.Notes" Label="Internal notes" Rows="2" Disabled Hint="Disabled: not posted." />
</Form>
{
[SupplyParameterFromForm(FormName = "text-area-states")]
private Contract? Model { get; set; }
protected override void OnInitialized() => Model ??= new();
public sealed class Contract
{
public string? Small { get; set; } = "Net 30.";
public string? Large { get; set; } = "Renews every year.";
public string? Terms { get; set; } = "Payment is due 30 days after the invoice date.";
public string? Notes { get; set; } = "Ask about a three-year term at renewal.";
}
}Read-only text can still be selected and copied, and it posts like any other, so a crafted post can change it: check it on the server if it matters. A disabled field posts nothing, so after a static post its property is null: keep its value on the server rather than saving it from the post.
Mode support
| Feature | Off | Static | Live |
|---|---|---|---|
| Label, hint and length limits from the model | Yes | Yes | Yes |
| Checks before posting, server messages under the field | Yes | Yes | Yes |
| Grows with the text (AutoGrow) | Yes | Yes | Yes |
| The count follows typing (ShowCount) | No | Yes | Yes |
Off: JavaScript disabled. Static: a static SSR page with IzzyBlazor's script. Live: an interactive page (Server, WebAssembly or Auto).
Accessibility
- Label, hint and errors work as in
TextField: a linkedlabel,aria-describedbyandaria-invalid. - With a maximum length, the browser stops typing at the limit (
maxlength). - With script, the
ShowCountcounter ("12 / 200") is the field's description, after the hint and errors, so screen readers read it on focus; it isn't announced as it changes. With JavaScript off it doesn't update, so it isn't linked.
Parameters
| Prop | Type | Default |
|---|---|---|
ReadOnlyMakes the field read-only: it can be focused and its text selected, and it still posts. | bool | false |
RowsVisible lines. | int | 4 |
AutoGrowGrows with the text instead of scrolling, from Rows lines up, where the browser supports CSS field-sizing. | bool | false |
PlaceholderExample text shown when empty. | string? | |
MaxLengthMaximum length. | int? | computed |
MinLengthMinimum length. | int? | computed |
ShowCountShows "n / max" under the field. | bool | false |
@bind-ValueThe value, bound with @bind-Value. | string? | |
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
- TextField: a labeled text input with add-ons and a password reveal.
- Form: posts on static pages, validates live on interactive ones.
- FieldFrame: the label, hint and errors around a control of your own.