Skip to content

Commit 7e9b605

Browse files
authored
[11.0 P1] Forms on Blazor support DisplayName attribute and Label component (#36438)
1 parent 80a945e commit 7e9b605

1 file changed

Lines changed: 84 additions & 18 deletions

File tree

aspnetcore/blazor/forms/input-components.md

Lines changed: 84 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The components in the table are also supported outside of a form in Razor compon
3737
| <xref:Microsoft.AspNetCore.Components.Forms.InputSelect%601> | `<select>` |
3838
| <xref:Microsoft.AspNetCore.Components.Forms.InputText> | `<input>` |
3939
| <xref:Microsoft.AspNetCore.Components.Forms.InputTextArea> | `<textarea>` |
40+
| [`Label<TValue>`](#label-component) (.NET 11 or later) | `<label>` |
4041

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

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

459460
> The Production Date field must be a date.
460461
461-
<!-- UPDATE 11.0 The feature has been backlogged.
462-
https://github.com/dotnet/aspnetcore/issues/49147
462+
:::moniker-end
463463

464-
> [!NOTE]
465-
> Alternatively, the [`[Display]` attribute](xref:System.ComponentModel.DataAnnotations.DisplayAttribute) on the model class property is supported:
466-
>
467-
> ```csharp
468-
> [Required, Display(Name = "Production Date")]
469-
> public DateTime ProductionDate { get; set; }
470-
> ```
471-
>
472-
> [`[DisplayName]` attribute](xref:System.ComponentModel.DisplayNameAttribute) is also supported:
473-
>
474-
> ```csharp
475-
> [Required, DisplayName("Production Date")]
476-
> public DateTime ProductionDate { get; set; }
477-
> ```
478-
>
479-
> 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.
464+
:::moniker range=">= aspnetcore-11.0"
465+
466+
<!-- UPDATE 11.0 - API cross-link
467+
468+
<xref:Microsoft.AspNetCore.Components.Forms.DisplayName%601>
469+
-->
470+
The `DisplayName` component can be used to display property names from metadata attributes
471+
472+
```csharp
473+
[Required, DisplayName("Production Date")]
474+
public DateTime ProductionDate { get; set; }
475+
```
476+
477+
The [`[Display]` attribute](xref:System.ComponentModel.DataAnnotations.DisplayAttribute) on the model class property is supported:
478+
479+
```csharp
480+
[Required, Display(Name = "Production Date")]
481+
public DateTime ProductionDate { get; set; }
482+
```
483+
484+
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.
485+
486+
Use the `DisplayName` component in labels or table headers:
487+
488+
```razor
489+
<label>
490+
<DisplayName For="@(() => Model!.ProductionDate)" />
491+
<InputDate @bind-Value="Model!.ProductionDate" />
492+
</label>
493+
```
494+
495+
:::moniker-end
496+
497+
:::moniker range=">= aspnetcore-11.0"
498+
499+
## `Label` component
500+
501+
<!-- UPDATE 11.0 - API cross-link
480502
503+
<xref:Microsoft.AspNetCore.Components.Forms.Label%601>
481504
-->
482505

506+
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.
507+
508+
### Nested pattern
509+
510+
The nested pattern wraps the input component inside the label:
511+
512+
```razor
513+
<Label For="() => Model!.ProductionDate">
514+
<InputDate @bind-Value="Model!.ProductionDate" />
515+
</Label>
516+
```
517+
518+
This renders:
519+
520+
```html
521+
<label>Production Date<input type="date" ... /></label>
522+
```
523+
524+
### Non-nested pattern
525+
526+
For accessibility requirements or styling flexibility, use the non-nested pattern where the label's `for` attribute references the input's `id`:
527+
528+
```razor
529+
<Label For="() => Model!.ProductionDate" />
530+
<InputDate @bind-Value="Model!.ProductionDate" />
531+
```
532+
533+
This renders:
534+
535+
```html
536+
<label for="Model_ProductionDate">Production Date</label>
537+
<input id="Model_ProductionDate" type="date" ... />
538+
```
539+
540+
The `id` attribute is automatically sanitized to create a valid HTML id (dots are replaced with underscores to avoid CSS selector conflicts).
541+
542+
Input components automatically generate an `id` attribute based on the bound expression. If an explicit `id` is provided, it takes precedence:
543+
544+
```razor
545+
<Label For="() => Model!.ProductionDate" for="prod-date" />
546+
<InputDate @bind-Value="Model!.ProductionDate" id="prod-date" />
547+
```
548+
483549
:::moniker-end
484550

485551
## Error message template support

0 commit comments

Comments
 (0)