Use Form Items inside Custom Components
Environment
Product | Form for Blazor |
Description
This KB article answers the following questions:
- How to add Form items in another component, wnich is inside the Telerik Blazor form?
- How to wrap Form items in a reusable custom component?
- How to implement a
FormGroup
that contains a nested shared component withFormItem
instances inside? - How to put a
<FormItem>
in another component (control)?
Solution
To render Form items inside custom Razor components:
- Define all
<FormGroup>
and<FormItem>
instances inside the<FormItems>
tag of the Form. - Add a
<FormItemsTemplate>
tag to the Form. - Define group renderers and item renderers for the Form groups and items, which will be children of the
<FormItemsTemplate>
. - Add the custom Razor components inside
<FormItemsTemplate>
. - Define parameters for the custom Razor components, which will receive Form groups or Form items.
- Define the required renderers inside the custom Razor components, according to the parameters from the previous step.
Example
The example below assumes that the project name is YourAppName
and the Person
class is defined in namespace YourAppName.Data
. Rename the namespaces in Home.razor
, MultipleFormItems.razor
, and Person.cs
before running the code in your app.
-
Home.razor
is the main Razor file, which holds the Form. -
SingleFormGroup.razor
includes a complete Form Group. The component receives anIFormGroup
as a parameter. -
MultipleFormItems.razor
renders multiple Form items that belong to a group. The component receives all items as a collection in a single parameter of typeFormGroupRendererTemplateContext
. This approach is not required and you can also define a different parameter for each item. -
SingleFormItem.razor
includes a single Form item. The component receives anIFormItem
as a parameter.
@using YourAppName.Data
<TelerikForm Model="@Employee"
Width="600px">
<FormValidation>
<DataAnnotationsValidator></DataAnnotationsValidator>
<TelerikValidationSummary />
</FormValidation>
<FormItems>
<FormItem Field="@nameof(Person.Id)"></FormItem>
<FormGroup LabelText="Names" Id="names-group">
<FormItem Field="@nameof(Person.FirstName)" LabelText="First Name"></FormItem>
<FormItem Field="@nameof(Person.LastName)" LabelText="Last Name"></FormItem>
</FormGroup>
<FormItem Field="@nameof(Person.BirthDate)" LabelText="Date of Birth" Id="birth-date-item"></FormItem>
<FormGroup LabelText="Evaluations" Id="evaluations-group">
<FormItem Field="@nameof(Person.InterviewNotes)"
LabelText="Interview Notes"
EditorType="@FormEditorType.TextArea"></FormItem>
<FormItem Field="@nameof(Person.PerformanceReview)"
LabelText="Performance Notes"
EditorType="@FormEditorType.TextArea"></FormItem>
</FormGroup>
</FormItems>
<FormItemsTemplate Context="formContext">
@{
var rootFormMembers = formContext.Items;
}
<TelerikFormItemRenderer Item="@( rootFormMembers.OfType<IFormItem>().First(x => x.Field == nameof(Person.Id)) )" />
<TelerikFormGroupRenderer Group="@( (IFormGroup)rootFormMembers.First(x => x.Id == "names-group") )">
<Template Context="groupContext">
<MultipleFormItems Context="@groupContext" />
</Template>
</TelerikFormGroupRenderer>
<SingleFormItem FormItem="@( rootFormMembers.OfType<IFormItem>().First(x => x.Field == nameof(Person.BirthDate)) )" />
<SingleFormGroup FormGroup="@( (IFormGroup)rootFormMembers.First(x => x.Id == "evaluations-group") )" />
</FormItemsTemplate>
</TelerikForm>
@code {
private Person? Employee { get; set; }
protected override void OnInitialized()
{
Employee = new Person()
{
Id = 1,
FirstName = "John",
LastName = "Doe",
BirthDate = DateTime.Today.AddYears(-30)
};
base.OnInitialized();
}
}
<div style="margin:.6em 0;padding:1em;background:#cf9;border:1px solid #ccc;">
<p><strong><code>SingleFormGroup.razor</code></strong></p>
<TelerikFormGroupRenderer Group="@FormGroup">
<Template Context="groupContext">
@foreach (IFormItem item in groupContext.Items)
{
<TelerikFormItemRenderer Item="@item" />
}
</Template>
</TelerikFormGroupRenderer>
</div>
@code {
[Parameter]
public IFormGroup? FormGroup { get; set; }
}
@using YourAppName.Data
<div style="margin:.4em 0;padding:1em;background:#ffd;border:1px solid #ccc;">
<p><strong><code>MultipleFormItems.razor</code></strong></p>
<TelerikFormItemRenderer Item="@( Context?.Items.Cast<IFormItem>().First(x => x.Field == nameof(Person.FirstName)) )" />
<TelerikFormItemRenderer Item="@( Context?.Items.Cast<IFormItem>().First(x => x.Field == nameof(Person.LastName)) )" />
</div>
@code {
[Parameter]
public FormGroupRendererTemplateContext? Context { get; set; }
}
<div style="margin:.4em 0;padding:1em;background:#fdc;border:1px solid #ccc;">
<p><strong><code>SingleFormItem.razor</code></strong></p>
<TelerikFormItemRenderer Item="@FormItem" />
</div>
@code {
[Parameter]
public IFormItem? FormItem { get; set; }
}
using System.ComponentModel.DataAnnotations;
namespace YourAppName.Data
{
public class Person
{
[Editable(false)]
public int Id { get; set; }
[Required]
[MaxLength(24)]
public string FirstName { get; set; } = string.Empty;
[Required]
[MaxLength(24)]
public string LastName { get; set; } = string.Empty;
[Required]
public DateTime BirthDate { get; set; } = DateTime.Today;
public string InterviewNotes { get; set; } = string.Empty;
public string PerformanceReview { get; set; } = string.Empty;
}
}