ASP.NET Core tag helper for conditionally adding a class to an element
Asked Answered
N

3

10

In Asp.Net MVC we can add class conditionally as following code:

<div class="choice @(Model.Active?"active":"")">
</div>

How can do this by using tagHelper and by remove else part in condition.

Nitramine answered 20/2, 2017 at 5:29 Comment(0)
N
12

Ability to add a conditional css class by following tagHelper provides. this code like AnchorTagHelper asp-route-* for add route values acts.

[HtmlTargetElement("div", Attributes = ClassPrefix + "*")]
public class ConditionClassTagHelper : TagHelper
{
    private const string ClassPrefix = "condition-class-";

    [HtmlAttributeName("class")]
    public string CssClass { get; set; }

    private IDictionary<string, bool> _classValues;

    [HtmlAttributeName("", DictionaryAttributePrefix = ClassPrefix)]
    public IDictionary<string, bool> ClassValues
    {
        get {
            return _classValues ?? (_classValues = 
                new Dictionary<string, bool>(StringComparer.OrdinalIgnoreCase));
        }
        set{ _classValues = value; }
    }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        var items = _classValues.Where(e => e.Value).Select(e=>e.Key).ToList();

        if (!string.IsNullOrEmpty(CssClass))
        {
            items.Insert(0, CssClass);
        }

        if (items.Any())
        {
            var classes = string.Join(" ", items.ToArray());
            output.Attributes.Add("class", classes);
        }
    }
}

in _ViewImports.cshtml add reference to taghelper as following

@addTagHelper "*, WebApplication3"

Use tagHelper in View:

<div condition-class-active="Model.Active" condition-class-show="Model.Display">
</div>

result for Active = true and Display = true is:

<div class="active show">
</div>
Nitramine answered 22/2, 2017 at 7:21 Comment(5)
is it possible to use suffixes, not only prefixes? say class-*-if?Ergotism
@Serge From the inline documentation, the * may only appear at the end. So it's probably not possible today.Deafanddumb
When I use the above code with the example it renders <div condition-class-active="condition-class-active"></div>Springhead
@MohammadAkbari please see #48252083Springhead
@mheptinstall: You have a spelling mistake. You should use condition-class-active instead of conditional-class-activeNitramine
K
2

There's no default way to do what you're asking. You would have to write a TagHelper that did that logic for you. Aka

[HtmlTargetElement(Attributes = "asp-active")]
public class FooTagHelper : TagHelper
{
    [HtmlAttributeName("asp-active")]
    public bool Active { get; set; }

    public override void Process(TagHelperOutput output, TagHelperContext context)
    {
        if (Active)
        {
            // Merge your active class attribute onto "output"'s attributes.
        }
    }
}

And then the HTML would look like:

<div class="choice" asp-active="Model.Active"></div>
Kenspeckle answered 21/2, 2017 at 21:13 Comment(0)
A
0

There is a built-in function for adding classes, see TagHelperOutputExtensions.AddClass: https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.mvc.taghelpers.taghelperoutputextensions.addclass

public class SomeHelper : TagHelper
{
    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        base.Process(context, output);
        // Wrap this in some condition.
        output.AddClass("myclass", HtmlEncoder.Default);
    }
}
Abessive answered 18/4, 2023 at 15:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.