@@ -122,58 +122,103 @@ When the user changes a value in a non-template Form item, the other Form items
122122
123123In 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 <code>OnUpdate</code> event (an <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 <code><Template></code> - 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 <code>Refresh()</code> - 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 <code>Refresh()</code> -
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 <code>StateHasChanged()</code> - 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 <code>StateHasChanged()</code> -
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> <code>Employee.Name</code> 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