Asp.Net Core 2复杂标记助手

时间:2018-04-20 10:52:09

标签: asp.net asp.net-core asp.net-core-tag-helpers

我是Asp.Net Core的新手,我遇到了Tag Helpers的问题。

我试图为2个场景创建一个Tag Helper: - 输入组 - 复选框

当我从asp-for标签开始时,我没有建立其他标签的问题,但我不知道如何构建"智能"标签,例如带有asp-for字段的输入标签和所有验证。

以下是我正在尝试构建的内容:

INPUT GROUP

<div class="input-group">
    <input class="form-control" placeholder="Search" type="text" data-val="true" data-val-maxlength="Max value" data-val-maxlength-max="5" id="SearchText" name="SearchText" value="" maxlength="5">
    <span class="input-group-append"><button class="btn btn-light" id="myButtonId" type="button">Search</button></span>
</div>

这就是我现在所拥有的:

<div class="input-group">
    <input asp-for="SearchText" class="form-control" placeholder="Buscar" add-on-button="myButtonId" add-on-append="true" />
</div>

这就是Tag Helper

[HtmlTargetElement("input", Attributes = "add-on-button,add-on-append", ParentTag = "div")]
public class TextBoxButtonHelper : TagHelper
{
    public string AddOnButton { get; set; }
    public bool AddOnAppend { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        var tagAddOn = new TagBuilder("span");
        tagAddOn.AddCssClass(AddOnAppend ? "input-group-append" : "input-group-prepend");

        var tagButton = new TagBuilder("button");
        tagButton.Attributes.Add("id", AddOnButton);
        tagButton.Attributes.Add("class", "btn btn-light");
        tagButton.Attributes.Add("type", "button");
        tagButton.InnerHtml.Append(context.AllAttributes["placeholder"]?.Value.ToString());

        tagAddOn.InnerHtml.AppendHtml(tagButton);

        if (AddOnAppend)
            output.PostElement.AppendHtml(tagAddOn); 
        else
            output.PreElement.AppendHtml(tagAddOn);
    }
}

我想拥有的将是这样的:

<input-tag asp-for="SearchText" class="form-control" placeholder="Buscar" button="myButtonId" append="true" />

所以只有一个标签可以生成所有代码,但我不知道如何生成&#34; TextBoxFor&#34;在Tag Helper里面。

CHECKBOX 与chechbox相同的问题,我需要从一个标签创建它:

<div class="custom-control custom-control-primary custom-checkbox">
    <input class="custom-control-input" data-val="true" data-val-required="The SearchActive field is required." id="SearchActive" name="SearchActive" type="checkbox" value="true">
    <label class="custom-control-label" for="SearchActive">Solo activos</label>
    <input name="SearchActive" type="hidden" value="false">
</div>

感谢您的帮助...

3 个答案:

答案 0 :(得分:1)

要针对当前模型评估的表达式。

[HtmlAttributeName("asp-for")]
public ModelExpression For { get; set; }

使用命名空间

using Microsoft.AspNetCore.Mvc.ViewFeatures;

完整代码:

[HtmlTargetElement("input", Attributes = "add-on-button,add-on-append", 
ParentTag = "div")]
public class TextBoxButtonHelper : TagHelper
{
    public string AddOnButton { get; set; }
    public bool AddOnAppend { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput 
    output)
    {
      //Your code
    }

  [HtmlAttributeName("asp-for")]
  public ModelExpression For { get; set; }
}

答案 1 :(得分:0)

看起来你可以使用output.Content.SetHtmlContent() - 当然对于复选框来踢出一堆html 如上所述:

https://docs.microsoft.com/en-us/aspnet/core/mvc/views/tag-helpers/authoring?view=aspnetcore-2.1#pass-a-model-to-a-tag-helper

答案 2 :(得分:0)

感谢您的回答,但您提供的解决方案都没有回答我的问题,但帮助找到解决方案。

这是两者的标记助手,它可以正常工作,以防有人想要使用它。

带按钮+输入的输入组

我们正在寻找的HTML是:

<div class="input-group">
    <input placeholder="Search" class="form-control" type="text" data-val="true" data-val-maxlength="Max" data-val-maxlength-max="5" id="SearchText" name="SearchText" value="" maxlength="5">
    <span class="input-group-append">
        <button class="btn btn-light" id="btnSearch" type="button">Search</button>
    </span>
</div>

最终的助手标记是:

<input asp-for="SearchText" placeholder="Search" add-on-button="btnSearch" add-on-button-text="Search" add-on-button-icon="ti-search" add-on-append="true" class="form-control" />

如您所见,我们可以指示按钮的名称,文本和/或图标(我们可以构建带有图标,文本或两者的按钮),我们也可以指示按钮是在开头还是在端。

这是Tag Helper:

[HtmlTargetElement("input", Attributes = "add-on-button,add-on-button-text,add-on-button-icon,add-on-append")]
public class TextBoxButtonTag : TagHelper
{
    public string AddOnButton { get; set; }
    public string AddOnButtonText { get; set; }
    public string AddOnButtonIcon { get; set; }
    public bool AddOnAppend { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        var tagSpan = new TagBuilder("span");
        tagSpan.AddCssClass(AddOnAppend ? "input-group-append" : "input-group-prepend");

        var tagButton = new TagBuilder("button");
        tagButton.Attributes.Add("id", AddOnButton);
        tagButton.Attributes.Add("class", "btn btn-light");
        tagButton.Attributes.Add("type", "button");

        if (!string.IsNullOrEmpty(AddOnButtonIcon))
        {
            var tagButtonIcon = new TagBuilder("i");
            tagButtonIcon.Attributes.Add("class", string.Concat("ti-search", string.IsNullOrEmpty(AddOnButtonText) ? "" : " pr-1"));
            tagButtonIcon.Attributes.Add("style", "vertical-align: middle");
            tagButton.InnerHtml.AppendHtml(tagButtonIcon);
        }

        tagButton.InnerHtml.AppendHtml(AddOnButtonText);


        tagSpan.InnerHtml.AppendHtml(tagButton);

        output.PreElement.AppendHtml(@"<div class='input-group'>");
        if (AddOnAppend)
            output.PostElement.AppendHtml(tagSpan); 
        else
            output.PreElement.AppendHtml(tagSpan);
        output.PostElement.AppendHtml("</div>");
    }
}

特殊设计的复选框

我们正在寻找的HTML是:

<div class="custom-control custom-control-primary custom-checkbox">
    <input type="checkbox" data-val="true" data-val-required="The SearchActive field is required." id="SearchActive" name="SearchActive" value="true" class="custom-control-input">
    <label class="custom-control-label" for="SearchActive">Only active</label>
    <input name="SearchActive" type="hidden" value="false">
</div>

最终的助手标记是:

<input asp-for="SearchActive" add-on-checkbox="Only active" />

这是Tag Helper:

[HtmlTargetElement("input", Attributes = "add-on-checkbox")]
public class CheckBoxTag : TagHelper
{
    [HtmlAttributeName("asp-for")]
    public ModelExpression Source { get; set; }

    public string AddOnCheckbox { get; set; }

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        output.Attributes.Add("class", "custom-control-input");

        var tagLabel = new TagBuilder("label");
        tagLabel.AddCssClass("custom-control-label");
        tagLabel.Attributes.Add("for", Source.Name);
        tagLabel.InnerHtml.Append(AddOnCheckbox);

        var tagHidden = new TagBuilder("input");
        tagHidden.Attributes.Add("name", Source.Name);
        tagHidden.Attributes.Add("type", "hidden");
        tagHidden.Attributes.Add("value", "false");

        output.PreElement.AppendHtml(@"<div class='custom-control custom-control-primary custom-checkbox'>");
        output.PostElement.AppendHtml(tagLabel);
        output.PostElement.AppendHtml(tagHidden);
        output.PostElement.AppendHtml("</div>");
    }
}

为了工作,对于这两种情况,您需要指出所有属性。有一种方法可以选择这些属性,但我没有在这里实现。

我希望这对某人有所帮助,因为我还没有找到任何文章说明如何做到这一点。

感谢您的帮助。