Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

.NET Core required field indicator

This is for an ASP.NET MVC Core 1.1 web app.

I'd like a nice way of displaying a required field indicator (like a red * after the label) for fields in my model which have the [Required] attribute set.

Currently I have my labels on the form using the LabelTagHelper, like this:

<label asp-for="Surname" class="required"></label>

I have some CSS which adds the * symbol after my label based on the presence of the "required" class:

label.required:after {
    color: #A94442;
    content: ' *';
    display:inline;
}

This works. But of course if I change my model and add or remove a [Required] attribute for a field I have to make sure I manually go to the markup and make the corresponding change, adding or removing the "required" class for the label in question.

Can anyone help me with an elegant way to add the "required" class to a label based on the presence of the [Required] attribute on model rather than having to hardcode it into the cshtml?

Maybe a custom tag helper which inherits from LabelTagHelper? And uses reflection to see if the [Required] attribute is in the model field?

Or is there a better way?

like image 690
Paul Avatar asked Feb 11 '17 18:02

Paul


2 Answers

You can create a dedicated TagHelper to achieve this purpose:

[HtmlTargetElement("label", Attributes = ForAttributeName)]
public class RequiredTagHelper : TagHelper
{
    private const string ForAttributeName = "asp-for";

    [HtmlAttributeName(ForAttributeName)]
    public ModelExpression For { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));

        if (output == null)
            throw new ArgumentNullException(nameof(output));

        if (For.Metadata.IsRequired)
        {
            var existingClass = output.Attributes.FirstOrDefault(f => f.Name == "class");
            var cssClass = string.Empty;
            if (existingClass != null)
            {
                cssClass = $"{existingClass.Value} ";
            }

            cssClass += "required";
            output.Attributes.SetAttribute("class", cssClass);
        }
    }
}
like image 163
Métoule Avatar answered Oct 26 '22 22:10

Métoule


Suggestion:

Instead of just output.Attributes.Remove(existingClass);, maybe some verification in case the label doesn't have the attribute "class":

if(existingClass != null)
{
     output.Attributes.Remove(existingClass);
}   
like image 39
João Neto Avatar answered Oct 26 '22 23:10

João Neto