Skip to content

Commit d8fae76

Browse files
authored
docs(Form): Improve Form UI refresh information and example (#2793)
1 parent 6c5256a commit d8fae76

File tree

1 file changed

+108
-32
lines changed

1 file changed

+108
-32
lines changed

components/form/formitems/overview.md

Lines changed: 108 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -122,58 +122,103 @@ When the user changes a value in a non-template Form item, the other Form items
122122

123123
In such cases, there are a few ways to trigger re-rendering and UI refresh inside or outside the Form:
124124

125-
* Use a Telerik input component inside a [Form item `<Template>`](slug:form-formitems-template).
125+
* Use a Telerik input component inside a [Form item `<Template>`](slug:form-formitems-template). Define two-way binding for the `Value` parameter, or use `Value`, `ValueChanged`, and `ValueExpression`.
126+
* Use a custom component with two-way parameter binding for the respective Form model property. Alternatively, use one-way binding, but implement an `EventCallback` that updates the model property value.
126127
* Call the [`Refresh()` method of the Form](slug:form-overview#form-reference-and-methods). The method will re-render the Form itself.
127128
* Subscribe to the [`OnUpdate` event of the Form](slug:form-events#onupdate). The event is an `EventCallback`, so it will update the whole Razor component, which holds the Form.
128129
* Call `StateHasChanged()` inside the Razor component, which holds the Form. This will re-render the whole Razor component, including the Form.
129130

131+
The example below demonstrates all of the above options. Note the differences in the two custom components:
132+
133+
* `ChildTwo.razor` supports two-way binding with an `EventCallback` for its `Value` parameter.
134+
* `ChildOne.razor` does not support two-way binding and uses an `Action` instead of an `EventCallback`.
135+
130136
>caption How to re-render all Form Items or the Form's parent component
131137
132138
<div class="skip-repl"></div>
133139

134140
````RAZOR Home.razor
141+
@using System.ComponentModel.DataAnnotations
142+
135143
<p>Type in the Form textboxes and observe the different results.</p>
136144
137145
<p>
138-
<label>
146+
<label class="k-checkbox-label">
139147
<TelerikCheckBox @bind-Value="@ShouldUseOnUpdate" />
140-
Use the <strong>Form <code>OnUpdate</code> event (an <code>EventCallback</code>)</strong> to re-render inside and outside the Form
148+
Use the <strong>Form &nbsp;<code>OnUpdate</code>&nbsp; event (an &nbsp;<code>EventCallback</code>)</strong> to
149+
re-render inside and outside the Form
141150
</label>
142151
</p>
143152
144153
<TelerikForm @ref="@FormRef"
145154
Model="@Employee"
146155
OnUpdate="@OnFormUpdate">
156+
<FormValidation>
157+
<DataAnnotationsValidator />
158+
</FormValidation>
147159
<FormItems>
148-
<FormItem Field="@nameof(Person.Name)" LabelText="Regular FormItem - no re-render without OnUpdate"></FormItem>
149-
<FormItem>
160+
<FormItem Field="@nameof(Person.Name)" LabelText="No Template - no re-render without OnUpdate." />
161+
<FormItem Field="@nameof(Person.Name)">
150162
<Template>
151-
<label class="k-label k-form-label" style="color:var(--kendo-color-success)">
152-
FormItem with &nbsp;<code>&lt;Template&gt;</code>&nbsp; - re-render inside and outside the Form</label>
163+
<label class="k-label k-form-label" style="color: var(--kendo-color-success)">
164+
Telerik component - re-render inside and outside the Form.
165+
</label>
153166
<div class="k-form-field-wrap">
154167
<TelerikTextBox @bind-Value="@Employee.Name" DebounceDelay="0" />
168+
<TelerikValidationMessage For="@( () => Employee.Name )" />
169+
</div>
170+
</Template>
171+
</FormItem>
172+
<FormItem Field="@nameof(Person.Name)">
173+
<Template>
174+
<label class="k-label k-form-label" style="color: var(--kendo-color-success)">
175+
Custom component with two-way binding - re-render inside and outside the Form.
176+
</label>
177+
<div class="k-form-field-wrap">
178+
<ChildTwo @bind-Value="@Employee.Name" />
179+
<TelerikValidationMessage For="@( () => Employee.Name )" />
180+
</div>
181+
</Template>
182+
</FormItem>
183+
<FormItem Field="@nameof(Person.Name)">
184+
<Template>
185+
<label class="k-label k-form-label" style="color: var(--kendo-color-success)">
186+
Custom component with one-way binding and EventCallback -
187+
re-render inside and outside the Form.
188+
</label>
189+
<div class="k-form-field-wrap">
190+
<ChildTwo Value="@Employee.Name"
191+
ValueChanged="@OnChildTwoChange_EventCallback"
192+
ValueExpression="@( () => Employee.Name )" />
193+
<TelerikValidationMessage For="@( () => Employee.Name )" />
155194
</div>
156195
</Template>
157196
</FormItem>
158-
<FormItem>
197+
<FormItem Field="@nameof(Person.Name)">
159198
<Template>
160-
<label class="k-label k-form-label" style="color:var(--kendo-color-warning)">
161-
FormItem with Template and Form &nbsp;<code>Refresh()</code>&nbsp; - re-render inside the Form</label>
199+
<label class="k-label k-form-label" style="color: var(--kendo-color-warning)">
200+
Custom component with one-way binding and Form &nbsp;<code>Refresh()</code>&nbsp; -
201+
re-render inside the Form.
202+
</label>
162203
<div class="k-form-field-wrap">
163-
<ChildComponent Value="@Employee.Name"
164-
ValueExpression="@( () => Employee.Name )"
165-
OnChange="@OnChildChange_Refresh" />
204+
<ChildOne Value="@Employee.Name"
205+
ValueExpression="@( () => Employee.Name )"
206+
OnChange="@OnChildOneChange_Refresh" />
207+
<TelerikValidationMessage For="@( () => Employee.Name )" />
166208
</div>
167209
</Template>
168210
</FormItem>
169-
<FormItem>
211+
<FormItem Field="@nameof(Person.Name)">
170212
<Template>
171-
<label class="k-label k-form-label" style="color:var(--kendo-color-tertiary)">
172-
FormItem with Template and &nbsp;<code>StateHasChanged()</code>&nbsp; - re-render inside and outside the Form</label>
213+
<label class="k-label k-form-label" style="color: var(--kendo-color-tertiary)">
214+
Custom component with one-way binding and &nbsp;<code>StateHasChanged()</code>&nbsp; -
215+
re-render inside and outside the Form.
216+
</label>
173217
<div class="k-form-field-wrap">
174-
<ChildComponent Value="@Employee.Name"
175-
ValueExpression="@( () => Employee.Name )"
176-
OnChange="@OnChildChange_StateHasChanged" />
218+
<ChildOne Value="@Employee.Name"
219+
ValueExpression="@( () => Employee.Name )"
220+
OnChange="@OnChildOneChange_StateHasChanged" />
221+
<TelerikValidationMessage For="@( () => Employee.Name )" />
177222
</div>
178223
</Template>
179224
</FormItem>
@@ -182,7 +227,7 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
182227
183228
<br />
184229
185-
<p><code>Employee.Name</code> in UI outside the Form: <strong>@Employee.Name</strong></p>
230+
<p>&nbsp;<code>Employee.Name</code>&nbsp; in UI outside the Form: <strong>@Employee.Name</strong></p>
186231
187232
<TelerikButton OnClick="@( () => { } )"
188233
ButtonType="@ButtonType.Button">
@@ -192,7 +237,7 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
192237
@code {
193238
private TelerikForm? FormRef { get; set; }
194239
195-
private Person Employee = new Person();
240+
private Person Employee { get; set; } = new();
196241
197242
private bool ShouldUseOnUpdate { get; set; }
198243
@@ -207,18 +252,22 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
207252
// of the whole Razor component, which holds the Form.
208253
}
209254
210-
private void OnChildChange_Refresh(string newValue)
255+
private void OnChildTwoChange_EventCallback(string newValue)
256+
{
257+
Employee.Name = newValue;
258+
}
259+
260+
private void OnChildOneChange_Refresh(string newValue)
211261
{
212262
Employee.Name = newValue;
213263
214264
if (!ShouldUseOnUpdate)
215265
{
216266
FormRef?.Refresh();
217267
}
218-
219268
}
220269
221-
private void OnChildChange_StateHasChanged(string newValue)
270+
private void OnChildOneChange_StateHasChanged(string newValue)
222271
{
223272
Employee.Name = newValue;
224273
@@ -228,15 +277,9 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
228277
}
229278
}
230279
231-
protected override void OnInitialized()
232-
{
233-
Employee = new Person();
234-
235-
base.OnInitialized();
236-
}
237-
238280
public class Person
239281
{
282+
[Required]
240283
public string Name { get; set; }
241284
242285
public Person()
@@ -246,7 +289,40 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
246289
}
247290
}
248291
````
249-
````RAZOR ChildComponent.razor
292+
````RAZOR ChildTwo.razor
293+
@using System.Linq.Expressions
294+
295+
<TelerikTextBox Value="@Value"
296+
ValueChanged="@TextBoxValueChanged"
297+
ValueExpression="@ValueExpression"
298+
DebounceDelay="0" />
299+
300+
@code {
301+
[Parameter]
302+
public string Value { get; set; } = string.Empty;
303+
304+
// This parameter is an EventCallback.
305+
// It will refresh the whole parent component's UI.
306+
[Parameter]
307+
public EventCallback<string> ValueChanged { get; set; }
308+
309+
// Get a validation expression from a parent component.
310+
// See https://www.telerik.com/blazor-ui/documentation/knowledge-base/inputs-validation-child-component
311+
[Parameter]
312+
public Expression<Func<string>>? ValueExpression { get; set; }
313+
314+
private async Task TextBoxValueChanged(string newValue)
315+
{
316+
Value = newValue;
317+
318+
if (ValueChanged.HasDelegate)
319+
{
320+
await ValueChanged.InvokeAsync(newValue);
321+
}
322+
}
323+
}
324+
````
325+
````RAZOR ChildOne.razor
250326
@using System.Linq.Expressions
251327
252328
<TelerikTextBox Value="@Value"

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy