blazor-server-sideblazorise

How do I show Blazorise validations in a custom component?


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.


Solution

  • 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" ...>