Frank Thomas
Frank Thomas

Reputation: 380

Adding classes to Blazor(Razor) Validation

I know things are still pretty early in the Blazor development track, but I'm wondering if anyone has come across a way to apply classes to a Blazor (Razor) validation message? Here's a sample of code.

        <EditForm Model="@Employee" OnValidSubmit="@HandleValidSubmit">
        <DataAnnotationsValidator />
        <ValidationSummary />
        <div class="form-group row">
            <label for="lastName" class="col-sm-3">Last Name: </label>
            <div class="col-sm-8">
                <InputText id="lastName" @bind-Value="@Employee.LastName" class="form-control" placeholder="Enter last name" />
                <ValidationMessage For="@(() => Employee.LastName)" />
            </div>
        </div>

I'd like to be able to add a text-danger, col-sm-8 or other classes to the validation message. I already know that I could do it with CSS using the default validation-error class.

Upvotes: 7

Views: 5410

Answers (3)

micka190
micka190

Reputation: 953

This is more of a complimentary answer to vi100's answer than a standalone answer, but I encountered an unexpected scenario and figured I'd help out others who may be in the same boat.


It apparently became possible to set the class attribute directly on the ValidationMessage component (I can do it in .NET 8, not sure when this was changed).

However, I strongly recommend against doing this. Unless Microsoft updates their docs to explicitly say it's okay, that is.

ValidationMessage's internal BuildRenderTree does the following:

foreach (var message in CurrentEditContext.GetValidationMessages(_fieldIdentifier))
{
    builder.OpenElement(0, "div");
    builder.AddAttribute(1, "class", "validation-message");
    builder.AddMultipleAttributes(2, AdditionalAttributes);
    builder.AddContent(3, message);
    builder.CloseElement();
}

The two important lines are:

builder.AddAttribute(1, "class", "validation-message");

Which sets the class attribute to validation-message.

And:

builder.AddMultipleAttributes(2, AdditionalAttributes);

Which sets whatever attributes were set by the user on the element.

This second one seems to have the odd effect of overriding the previously configured class attribute if the user explicitly defines a class attribute on the <ValidationMessage> component.

Looking at the source code and the documentation, there doesn't seem to be any mention of this behavior, so it may be an unexpected bug or an implementation detail that you're not supposed to rely on.

Because of this, I'd recommend going with vi100's answer over directly setting the class attribute.

Upvotes: 0

DharmaTurtle
DharmaTurtle

Reputation: 8407

It seems like you can't add a class, but you can add styles:

<ValidationMessage
    For="..."
    style="color: #dc3545!important;
           flex: 0 0 66.666667%;
           max-width: 66.666667%;" />

You can also override the validation-message class as documented here:

Control the style of validation messages in the app's stylesheet (wwwroot/css/app.css or wwwroot/css/site.css). The default validation-message class sets the text color of validation messages to red:

.validation-message {
    color: red;
}

Upvotes: 4

Vi100
Vi100

Reputation: 4203

As suggested above, you can subclass the ValidationMessage component class... I'll give you a simpler solution, since I prefer not to have a myriad of classes on my projects just for changing the appearance a little.

Just wrap the ValidatorMessage with a div and apply classes to it:

<div class="col-sm-8 text-danger">
    <ValidationMessage For="@(() => Employee.LastName)" />
</div>

Anyway, what the ValidationMessage component does (by code) is rendering a simple div with the class "validation-message" so, if you have problems with any style not being applied, take into account that you can force styles using the right CSS selectors (and maybe some !important tags...).

Upvotes: 12

Related Questions