Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 84 additions & 18 deletions aspnetcore/blazor/forms/input-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ The components in the table are also supported outside of a form in Razor compon
| <xref:Microsoft.AspNetCore.Components.Forms.InputSelect%601> | `<select>` |
| <xref:Microsoft.AspNetCore.Components.Forms.InputText> | `<input>` |
| <xref:Microsoft.AspNetCore.Components.Forms.InputTextArea> | `<textarea>` |
| [`Label<TValue>`](#label-component) (.NET 11 or later) | `<label>` |

For more information on the <xref:Microsoft.AspNetCore.Components.Forms.InputFile> component, see <xref:blazor/file-uploads>.

Expand Down Expand Up @@ -458,28 +459,93 @@ The validation summary displays the friendly name when the field's value is inva

> The Production Date field must be a date.

<!-- UPDATE 11.0 The feature has been backlogged.
https://github.com/dotnet/aspnetcore/issues/49147
:::moniker-end

> [!NOTE]
> Alternatively, the [`[Display]` attribute](xref:System.ComponentModel.DataAnnotations.DisplayAttribute) on the model class property is supported:
>
> ```csharp
> [Required, Display(Name = "Production Date")]
> public DateTime ProductionDate { get; set; }
> ```
>
> [`[DisplayName]` attribute](xref:System.ComponentModel.DisplayNameAttribute) is also supported:
>
> ```csharp
> [Required, DisplayName("Production Date")]
> public DateTime ProductionDate { get; set; }
> ```
>
> Between the two approaches, the `[Display]` attribute is recommended, which makes additional properties available. The `[Display]` attribute also enables assigning a resource type for localization.
:::moniker range=">= aspnetcore-11.0"

<!-- UPDATE 11.0 - API cross-link

<xref:Microsoft.AspNetCore.Components.Forms.DisplayName%601>
-->
The `DisplayName` component can be used to display property names from metadata attributes

```csharp
[Required, DisplayName("Production Date")]
public DateTime ProductionDate { get; set; }
```

The [`[Display]` attribute](xref:System.ComponentModel.DataAnnotations.DisplayAttribute) on the model class property is supported:

```csharp
[Required, Display(Name = "Production Date")]
public DateTime ProductionDate { get; set; }
```

Between the two approaches, the `[Display]` attribute is recommended, which makes additional properties available. The `[Display]` attribute also enables assigning a resource type for localization. When both attributes are present, `[Display]` takes precedence over `[DisplayName]`. If neither attribute is present, the component falls back to the property name.

Use the `DisplayName` component in labels or table headers:

```razor
<label>
<DisplayName For="@(() => Model!.ProductionDate)" />
<InputDate @bind-Value="Model!.ProductionDate" />
</label>
```

:::moniker-end

:::moniker range=">= aspnetcore-11.0"

## `Label` component

<!-- UPDATE 11.0 - API cross-link

<xref:Microsoft.AspNetCore.Components.Forms.Label%601>
-->

The `Label` component renders a `<label>` element that automatically extracts the display name from a model property using `[Display]` or `[DisplayName]` attributes. This simplifies form creation by eliminating the need to manually specify label text.

### Nested pattern

The nested pattern wraps the input component inside the label:

```razor
<Label For="() => Model!.ProductionDate">
<InputDate @bind-Value="Model!.ProductionDate" />
</Label>
```

This renders:

```html
<label>Production Date<input type="date" ... /></label>
```

### Non-nested pattern

For accessibility requirements or styling flexibility, use the non-nested pattern where the label's `for` attribute references the input's `id`:

```razor
<Label For="() => Model!.ProductionDate" />
<InputDate @bind-Value="Model!.ProductionDate" />
```

This renders:

```html
<label for="Model_ProductionDate">Production Date</label>
<input id="Model_ProductionDate" type="date" ... />
```

The `id` attribute is automatically sanitized to create a valid HTML id (dots are replaced with underscores to avoid CSS selector conflicts).

Input components automatically generate an `id` attribute based on the bound expression. If an explicit `id` is provided, it takes precedence:

```razor
<Label For="() => Model!.ProductionDate" for="prod-date" />
<InputDate @bind-Value="Model!.ProductionDate" id="prod-date" />
```

:::moniker-end

## Error message template support
Expand Down