Avrohom Yisroel
Avrohom Yisroel

Reputation: 9450

Can we check which property fails validation in Blazor?

I have a Blazor component that holds a form input and some extra markup. Thanks to some excellent help from @enet (see this answer) I now have it so that if the validation on the model property fails, the <ValidationMessage> correctly displays the message.

However, I would like to have this <ValidationMessage> tag surrounded by HTML that only appears when the validation message is shown, ie when validation fails for that property. I can do that by introducing a private bool, and using it as follows...

    @if (_showValidationMsg) {
      <div class="input-group-append"><label class="input-group-text has-error" for="@PropertyName">
        <ValidationMessage For="@ValueExpression" /></label>
      </div>
    }

@code {
  // other stuff here as well

  private bool _showValidationMsg = false;

  private async Task OnChanged(ChangeEventArgs cea) {
    await ValueChanged.InvokeAsync(cea.Value?.ToString() ?? "");
    FieldIdentifier identifier = CascadedEditContext.Field(PropertyName);
    CascadedEditContext.NotifyFieldChanged(identifier);
    _showValidationMsg = !CascadedEditContext.Validate();
  }

}

This works fine when the component only has one input element, but one of my components has two input controls, and I would like to know which one has failed validation, so I can show/hide the correct bit of HTML.

Is there a way of finding out which model properties failed validation?

Upvotes: 2

Views: 1028

Answers (1)

aryeh
aryeh

Reputation: 1040

Once you have called CascadedEditContext.Validate (you can ignore the result as you don't need it, see below), you can then use GetValidationMessages to get the validation messages for the property. If there aren't any, it passed validation.

Using your code as a base, you could wrap this into a reusable method as follows...

private async Task<bool> CheckValidationFor(ChangeEventArgs cea, EventCallback<string> valueChangedEventCallback, string propertyName) {
  await valueChangedEventCallback.InvokeAsync(cea.Value?.ToString() ?? "");
  FieldIdentifier identifier = CascadedEditContext.Field(propertyName);
  CascadedEditContext.NotifyFieldChanged(identifier);
  CascadedEditContext.Validate();
  return CascadedEditContext.GetValidationMessages(identifier).Any();

}

You could then simplify your OnChanged1 code to this...

private async Task OnChanged1(ChangeEventArgs cea) =>
  _showValidationMsg1 = await CheckValidationFor(cea, Value1Changed, PropertyName1);

Likewise for OnChanged2

Upvotes: 3

Related Questions