Skip to content

Instantly share code, notes, and snippets.

@is-consulting
Created March 17, 2018 21:11
Show Gist options
  • Save is-consulting/0d198ed758cd5b048d9d48dd61830f3c to your computer and use it in GitHub Desktop.
Save is-consulting/0d198ed758cd5b048d9d48dd61830f3c to your computer and use it in GitHub Desktop.
Asp.net Core 2.0 TagHelper for adding 'active' class to current active link. Compatible to lowercase routing, LowercaseUrls
[HtmlTargetElement(Attributes = ControllersAttributeName)]
[HtmlTargetElement(Attributes = ActionsAttributeName)]
[HtmlTargetElement(Attributes = RouteAttributeName)]
[HtmlTargetElement(Attributes = ClassAttributeName)]
public class ActiveRouteTagHelper : TagHelper
{
private const string ActionsAttributeName = "asp-active-actions";
private const string ControllersAttributeName = "asp-active-controllers";
private const string ClassAttributeName = "asp-active-class";
private const string RouteAttributeName = "asp-active-route";
[HtmlAttributeName(ControllersAttributeName)]
public string Controllers { get; set; }
[HtmlAttributeName(ActionsAttributeName)]
public string Actions { get; set; }
[HtmlAttributeName(RouteAttributeName)]
public string Route { get; set; }
[HtmlAttributeName(ClassAttributeName)]
public string Class { get; set; } = "active";
[HtmlAttributeNotBound]
[ViewContext]
public ViewContext ViewContext { get; set; }
public override void Process(TagHelperContext context, TagHelperOutput output)
{
RouteValueDictionary routeValues = ViewContext.RouteData.Values;
string currentAction = routeValues["action"].ToString();
string currentController = routeValues["controller"].ToString();
if (string.IsNullOrEmpty(Actions))
Actions = currentAction;
if (string.IsNullOrEmpty(Controllers))
Controllers = currentController;
string[] acceptedActions = Actions.Trim().Split(',').Distinct().ToArray();
string[] acceptedControllers = Controllers.Trim().Split(',').Distinct().ToArray();
var lcComparer = new LowerCaseComparer();
if (acceptedActions.Contains(currentAction, lcComparer) && acceptedControllers.Contains(currentController, lcComparer))
{
SetAttribute(output, "class", Class);
}
base.Process(context, output);
}
private void SetAttribute(TagHelperOutput output, string attributeName, string value, bool merge = true)
{
var v = value;
TagHelperAttribute attribute;
if (output.Attributes.TryGetAttribute(attributeName, out attribute))
{
if (merge)
{
v = $"{attribute.Value} {value}";
}
}
output.Attributes.SetAttribute(attributeName, v);
}
}
public class LowerCaseComparer : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return x.ToLowerInvariant().Equals(y.ToLowerInvariant());
}
public int GetHashCode(string obj)
{
return obj.GetHashCode();
}
}
@utarn
Copy link

utarn commented Dec 29, 2020

I also update your code to support C# nullable and async
https://gist.github.com/utarn/188869d56baa3fbc5fb12ff0da6e1578

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment