I'm using Blazorise with a server-side Blazor application. When I try and wrap the Blazorise input components in my custom components the validation messages stop working.
By this I mean, that when I click on submit I don't see any error messages under the fields with invalid values. If I don't wrap the Blazorise inputs and click submit I see error messages.
Here's an example. This form contains the same field twice. One wrapped inside my custom component TextField
and the other unwrapped.
<Form>
<Validations @ref="@fluentValidations" Mode="ValidationMode.Manual" Model="AccountDto" HandlerType="typeof(FluentValidationHandler)">
<TextField Label="Name" @bind-Text="@Account.Name" />
<Validation>
<Field>
<FieldLabel For="account-name-input">Name</FieldLabel>
<TextEdit ElementId="account-name-input" @bind-Text="@Account.Name">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
</Validations>
<Field>
<Button Type="ButtonType.Submit"
PreventDefaultOnSubmit
Clicked="Submit">
Submit
</Button>
</Field>
</Form>
The code behind contains the following for the form (I left out a lot of fluff):
private Validations fluentValidations = null!;
private async Task Submit()
{
if (await fluentValidations.ValidateAll())
await CreateAccount(Account);
}
The custom component looks like. (The code behind file contains nothing interesting):
<Validation>
<Field>
<FieldLabel For="@GetInputId()">
@Label
</FieldLabel>
<TextEdit ElementId="@GetInputId()"
Text="@Text"
TextChanged="TextChanged"
Disabled="@Disabled">
<Feedback>
<ValidationError />
</Feedback>
</TextEdit>
</Field>
</Validation>
I know the validation works correctly because the error does appear in the unwrapped component, but not in my component.
In your wrapped component, you need to have not just the Text
, and TextChanged
parameters but a third parameter named TextExpression
. This parameter tells Blazor how to get the reference to the bound field used for the validation.
[Parameter] public string Text { get; set; }
[Parameter] public EventCallback<string> TextChanged { get; set; }
[Parameter] public Expression<Func<string>> TextExpression { get; set; }
Next, instead of having @bind-Text
pass all the parameters down to the TextEdit.
<TextEdit Text="@Text" TextChanged="@TextChanged" TextExpression="@TextExpression" ...>