Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I add to or change the default CSS class when using ValidationMessage in ASP.NET Core?

I am using ValidationMessage in a razor component to show validation message, like this:

<ValidationMessage For="@(() => ViewModel.CompanyNumber)" />

This generates this HTML code:

<div class="validation-message">The company number field is required.</div>

Is it possible to change the CSS-class? I want to use something else than validation-message. Adding class="myclass" is ignored by the controller. I've also tried with @attributes without success.

like image 209
PEK Avatar asked Apr 22 '20 14:04

PEK


3 Answers

With .NET5 they added functionality to customize the validation classes on the actual input-fields (which issue 8695 was about) by way of setting a FieldCssClassProvider to the edit context. But there still seems to be no way of customizing the classes of the ValidationSummary or ValidationMessage components

Snipped directly from the .NET 5 docs

var editContext = new EditContext(model);
editContext.SetFieldCssClassProvider(new MyFieldClassProvider());

...

private class MyFieldClassProvider : FieldCssClassProvider
{
    public override string GetFieldCssClass(EditContext editContext, 
        in FieldIdentifier fieldIdentifier)
    {
        var isValid = !editContext.GetValidationMessages(fieldIdentifier).Any();

        return isValid ? "good field" : "bad field";
    }
}

Using this will yield the below html for an invalid input. At least with this we can style the actual input elements. Just not the messages...

<input class="bad field" aria-invalid="">
<div class="validation-message">Identifier too long (16 character limit).</div>
like image 162
Michel Jansson Avatar answered Oct 23 '22 13:10

Michel Jansson


You can change the validation-message class inside the css file app.css inside the wwwroot. Or site.css in in earlier previews.

.validation-message {
    color: red;
}

The class is set in ValidationMessage.cs

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

https://github.com/dotnet/aspnetcore/blob/master/src/Components/Web/src/Forms/ValidationMessage.cs

like image 45
tbdrz Avatar answered Oct 23 '22 11:10

tbdrz


Why don't you just copy the code for ValidationMessage.cs and write in your own property? There is nothing special about this class except for capturing a Cascading Parameter. Just take this file and make your own with a slightly different name then add:

[Parameter] public string AdditionalClassNames {get;set;}

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
    foreach (var message in CurrentEditContext.GetValidationMessages(_fieldIdentifier))
    {
        builder.OpenElement(0, "div");
        builder.AddMultipleAttributes(1, AdditionalAttributes);
        builder.AddAttribute(2, "class", string.IsNullOrEmpty(AdditionalClassNames) ? "validation-message" : $"validation-message {AdditionalClassNames}");
        builder.AddContent(3, message);
        builder.CloseElement();
    }
}

https://github.com/dotnet/aspnetcore/blob/master/src/Components/Web/src/Forms/ValidationMessage.cs

EDIT

Even better, it's not sealed! Just use it as a base class for a new version and add what I mentioned above.

like image 1
Lee McPherson Avatar answered Oct 23 '22 13:10

Lee McPherson