【问题标题】:ASP Net Core TagHelper Add CSS ClassASP Net Core TagHelper 添加 CSS 类
【发布时间】:2018-06-08 07:04:18
【问题描述】:

我需要为必填字段自动显示一个星号,因此我设法在网上找到了一些执行此操作的代码。我添加了一个名为“required-label”的 CSS 类,也将其变为红色。但是,它仅将 CSS 类应用于星号而不是标签。任何想法如何将 CSS 类应用于两者?这是所要求的完整的 sn-p。

using Microsoft.AspNetCore.Mvc.Rendering;
using Microsoft.AspNetCore.Mvc.TagHelpers;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using System.Threading.Tasks;

namespace App.TagHelpers
{
    [HtmlTargetElement("label", Attributes = ForAttributeName)]
    public class LabelRequiredTagHelper : LabelTagHelper
    {
        private const string ForAttributeName = "asp-for";

        public LabelRequiredTagHelper(IHtmlGenerator generator) : base(generator)
        {
        }

        public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
        {
            await base.ProcessAsync(context, output);

            if (For.Metadata.IsRequired)
            {
                var sup = new TagBuilder("sup");
                sup.InnerHtml.Append("*");
                sup.AddCssClass("required-label");
                output.Content.AppendHtml(sup);
            }
        }
    }
}

感谢 Manoj Kulkarni 提供的代码示例。

【问题讨论】:

  • 上述代码的 HTML 输出是什么,你能把那个的 sn-p 贴出来吗?
  • 现在添加完整代码 Rikin

标签: css asp.net-core


【解决方案1】:

OP 中的标签助手可以工作,但不是附加一个 sup 元素来包含星号,我认为您需要做的就是向标签元素本身添加一个 css 类,并使用 CSS 相应地设置标签的样式。

tag-helper 稍作调整

[HtmlTargetElement("label", Attributes = ForAttributeName)]
public class LabelRequiredTagHelper : LabelTagHelper
{
    private const string ForAttributeName = "asp-for";
    private const string RequiredCssClass = "required";

    public LabelRequiredTagHelper(IHtmlGenerator generator) : base(generator)
    {
    }

    public override async Task ProcessAsync(TagHelperContext context, 
        TagHelperOutput output)
    {
        await base.ProcessAsync(context, output);

        if (For.Metadata.IsRequired)
        {
            output.Attributes.AddCssClass(RequiredCssClass);
        }
    }
}

AddCssClass 分机

public static class TagHelperAttributeListExtensions
{
    public static void AddCssClass(this TagHelperAttributeList attributeList, 
        string cssClass)
    {
        var existingCssClassValue = attributeList
            .FirstOrDefault(x => x.Name == "class")?.Value.ToString();

        // If the class attribute doesn't exist, or the class attribute
        // value is empty, just add the CSS class
        if (String.IsNullOrEmpty(existingCssClassValue))
        {
            attributeList.SetAttribute("class", cssClass);
        }
        // Here I use Regular Expression to check if the existing css class
        // value has the css class already. If yes, you don't need to add
        // that css class again. Otherwise you just add the css class along
        // with the existing value.
        // \b indicates a word boundary, as you only want to check if
        // the css class exists as a whole word.  
        else if (!Regex.IsMatch(existingCssClassValue, $@"\b{ cssClass }\b",
            RegexOptions.IgnoreCase))
        {
            attributeList.SetAttribute("class", $"{ cssClass } { existingCssClassValue }");
        }
    }
}

视图模型

包含必需属性的示例视图模型,用[Required] 注释。默认情况下还需要一个布尔值。

public class LoginViewModel
{
    [Required]
    public string Username { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

    [Display(Name = "Remember my login?")]
    public bool RememberMe { get; set; }

    public string ReturnUrl { get; set; }
}

景色

例如,我有一个登录页面,它采用LoginViewModel

@model LoginViewModel
@{
    ViewData["Title"] = "Login";
}

<form asp-area="" asp-controller="account" asp-action="login">
    <input type="hidden" asp-for="ReturnUrl" />

    <div asp-validation-summary="ModelOnly" class="text-danger"></div>

    <div class="form-group">
        <label asp-for="Email"></label>
        <input type="email" class="form-control" asp-for="Email" />
    </div>
    <div class="form-group">
        <label asp-for="Password"></label>
        <input type="password" class="form-control" asp-for="Password" />
    </div>
    <div class="form-group">
        <div class="custom-control custom-checkbox">
            <input type="checkbox" class="custom-control-input" asp-for="RememberMe" />
            <label asp-for="RememberMe" class="custom-control-label"></label>
        </div>
    </div>
    <button type="submit" class="btn btn-primary btn-block">Login</button>
</form>

值得知道复选框RememberMe 的标签。在视图上,我添加了额外的 css 类 custom-control-label,标签助手仍然设法添加所需的 css 类 required

生成的 HTML

样式(在 SASS 中)

您可以看出我正在使用 Bootstrap css 框架,并且已经有复选框标签的样式,所以我想排除这些样式(由 custom-control-label css 类表示)。

label.required:not(.custom-control-label)::after {
    content: "*";
    padding-left: .3rem;
    color: theme-color('danger');      /* color: #dc3545; */
}

结果

如果您希望所需的标签也为红色,您可以这样设置样式:

label.required:not(.custom-control-label) {
    color: theme-color('danger');      /* color: #dc3545; */

    &::after {
        content: "*";
        padding-left: .3rem;
    }
}

【讨论】:

  • 感谢大卫的例子。对于之前的一些 MVC 项目,我使用了一个 Html Helper,它会自动突出显示必填字段的标签。这段代码在 ASP Net Core 中几乎实现了相同的功能,所以我真的想拥有相同的功能。很明显,我年纪大了就变得懒惰,希望一切都是自动的,而不必用 class="required" 手动装饰。
  • 终于明白你的意思了。我已经更新了 OP。请看一看。
  • 很好的答案!除了内置的LabelTagHelper,你能解释一下这个 taghelper 是如何工作(调用)的吗?我的意思是,我们似乎有两个针对label 标签的TagHelper,那么它们都会执行吗?按什么顺序?
  • @S.Serpooshan:问得好!我认为这个自定义标签助手和内置标签标签助手都会运行,因为它们针对相同的元素 labelasp-for 属性是可选的,但我把它放在那里是为了确保这个自定义标签助手只会运行在那些具有asp-for 属性的人身上)。这里的技巧是:1)同一目标元素的内容在所有针对同一元素的标签助手之间共享/缓存 2)(如果您查看内置标签标签助手的源代码)一个标签助手没有如果另一个标签助手已经这样做了,则更新/生成内容。
  • @S.Serpooshan:就我而言,哪个先运行并不重要。如果内置的首先运行(我认为这是正确的),当我的自定义调用await base.ProcessAsync() 时,它会处理相同的逻辑,即如果内容已被修改,它将不会重新生成内容。如果我的自定义第一个运行,它仍然调用base.ProcessAsync() 来生成内容,因为我的继承自LabelTagHelper。稍后当默认的内置标签标签助手运行并看到内容已被修改时,它无论如何都不会重新生成内容。免责声明:我不是 100% 确定,但 LOL
猜你喜欢
  • 2020-12-08
  • 1970-01-01
  • 2017-03-09
  • 2018-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-15
  • 1970-01-01
相关资源
最近更新 更多