I have a razor page that has components placed on the form by evaluating data from a Screen Layout table.
It scans this table, which defines the Label and what type of control it will be, typically a DropDown or a Text box.
I created a reusable razor component for this.
Here is the component:
@using Radzen
@using Radzen.Blazor
<div class="row">
<div class="col-md-4 align-items-center d-flex">
<RadzenLabel Text=@ScreenLayout.Label></RadzenLabel>
<div>
</div>
<div class="col-md-8">
@if (ScreenLayout.FieldType == "SELECT")
{
<RadzenDropDown
AllowClear="true"
FilterCaseSensitivity="FilterCaseSensitivity.CaseInsensitive"
FilterOperator="StringFilterOperator.Contains"
AllowFiltering="true"
Data=@DropdownData @bind-Value=ComponentValue
TextProperty="TextProperty"
ValueProperty="ValueProperty" Class="w-100"
Name=@ScreenLayout.FormFieldName
Placeholder=@(string.Concat("Select the ", ScreenLayout.Label))
Change=@(args => UpdateComponentValue(args)) >
</RadzenDropDown>
}
@if (ScreenLayout.FieldType=="TEXT")
{
<RadzenTextBox @bind-Value=ComponentValue
Name=@ScreenLayout.FormFieldName
Change=@(args => UpdateComponentValue(args))/>
}
@if (ScreenLayout.Required=="Y")
{
<RadzenRequiredValidator
Component=@ScreenLayout.FormFieldName
Text=@(string.Concat(ScreenLayout.Label, " is required "))
Popup=true
Style="position: relative" />
}
@if (ScreenLayout.MaxLength > 0)
{
<RadzenLengthValidator
Component=@ScreenLayout.FormFieldName
Text=@(string.Concat(ScreenLayout.Label, " Max Length is ", ScreenLayout.MaxLength, " characters."))
Popup=true
Style="position: relative" />
}
</div>
</div>
</div>
@code {
[Parameter]
public ScreenLayout ScreenLayout { get; set; }
[Parameter]
public IList<DropDownSource> DropdownData { get; set; }
[Parameter]
public string ComponentValue { get; set; }
[Parameter]
public EventCallback<string> ComponentValueChanged { get; set; }
async Task UpdateComponentValue(object value)
{
await ComponentValueChanged.InvokeAsync(ComponentValue);
}
}
And then the consuming page:
<RadzenTemplateForm TItem="InputOrderSubmission" Data=@inputOrderSubmission Submit=@HandleValidSubmit InvalidSubmit=@HandleInvalidSubmit>
@foreach (var screenLayout in ScreenLayouts.OrderBy(o=>o.FieldID))
{
@if(screenLayout.Visible=="N")
{
continue;
}
@switch(screenLayout.FormFieldName)
{
case "txtStore":
{
<FormControlComponent @bind-ComponentValue=inputOrderSubmission.LocationId
ScreenLayout=@screenLayout
DropdownData=@LocationCodes >
</FormControlComponent>
break;
}
case "txtName":
{
<FormControlComponent @bind-ComponentValue=inputOrderSubmission.Company
ScreenLayout=@screenLayout >
</FormControlComponent>
break;
}
//Removed rest of case statements for brevity
}
}
<RadzenButton style="width: 160px" ButtonType=ButtonType.Submit Icon="save" BusyText="Saving ..." IsBusy=@Busy Text="Save" />
</RadzenTemplateForm>
}
It all works great except for the validation.
As soon as any one of the Radzen Controls in the FormControlComponent' value is changed, all of the Radzen Controls fire the Validation, not just the one component being changed.
Example:
Before Validation:
After clicking on "Save" I get the expected validation messages:
Starting with a fresh page, I select one item from the top DropDown, and all the validation for the rest of the controls fire as well.
Any Idea why this happens?