@@ -122,58 +122,103 @@ When the user changes a value in a non-template Form item, the other Form items
122
122
123
123
In such cases, there are a few ways to trigger re-rendering and UI refresh inside or outside the Form:
124
124
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.
126
127
* Call the [ ` Refresh() ` method of the Form] ( slug:form-overview#form-reference-and-methods ) . The method will re-render the Form itself.
127
128
* 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.
128
129
* Call ` StateHasChanged() ` inside the Razor component, which holds the Form. This will re-render the whole Razor component, including the Form.
129
130
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
+
130
136
> caption How to re-render all Form Items or the Form's parent component
131
137
132
138
<div class =" skip-repl " ></div >
133
139
134
140
```` RAZOR Home.razor
141
+ @using System.ComponentModel.DataAnnotations
142
+
135
143
<p>Type in the Form textboxes and observe the different results.</p>
136
144
137
145
<p>
138
- <label>
146
+ <label class="k-checkbox-label" >
139
147
<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
141
150
</label>
142
151
</p>
143
152
144
153
<TelerikForm @ref="@FormRef"
145
154
Model="@Employee"
146
155
OnUpdate="@OnFormUpdate">
156
+ <FormValidation>
157
+ <DataAnnotationsValidator />
158
+ </FormValidation>
147
159
<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)" >
150
162
<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>
153
166
<div class="k-form-field-wrap">
154
167
<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 )" />
155
194
</div>
156
195
</Template>
157
196
</FormItem>
158
- <FormItem>
197
+ <FormItem Field="@nameof(Person.Name)" >
159
198
<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>
162
203
<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 )" />
166
208
</div>
167
209
</Template>
168
210
</FormItem>
169
- <FormItem>
211
+ <FormItem Field="@nameof(Person.Name)" >
170
212
<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>
173
217
<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 )" />
177
222
</div>
178
223
</Template>
179
224
</FormItem>
@@ -182,7 +227,7 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
182
227
183
228
<br />
184
229
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>
186
231
187
232
<TelerikButton OnClick="@( () => { } )"
188
233
ButtonType="@ButtonType.Button">
@@ -192,7 +237,7 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
192
237
@code {
193
238
private TelerikForm? FormRef { get; set; }
194
239
195
- private Person Employee = new Person ();
240
+ private Person Employee { get; set; } = new();
196
241
197
242
private bool ShouldUseOnUpdate { get; set; }
198
243
@@ -207,18 +252,22 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
207
252
// of the whole Razor component, which holds the Form.
208
253
}
209
254
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)
211
261
{
212
262
Employee.Name = newValue;
213
263
214
264
if (!ShouldUseOnUpdate)
215
265
{
216
266
FormRef?.Refresh();
217
267
}
218
-
219
268
}
220
269
221
- private void OnChildChange_StateHasChanged (string newValue)
270
+ private void OnChildOneChange_StateHasChanged (string newValue)
222
271
{
223
272
Employee.Name = newValue;
224
273
@@ -228,15 +277,9 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
228
277
}
229
278
}
230
279
231
- protected override void OnInitialized()
232
- {
233
- Employee = new Person();
234
-
235
- base.OnInitialized();
236
- }
237
-
238
280
public class Person
239
281
{
282
+ [Required]
240
283
public string Name { get; set; }
241
284
242
285
public Person()
@@ -246,7 +289,40 @@ In such cases, there are a few ways to trigger re-rendering and UI refresh insid
246
289
}
247
290
}
248
291
````
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
250
326
@using System.Linq.Expressions
251
327
252
328
<TelerikTextBox Value="@Value"
0 commit comments