Stian
Stian

Reputation: 1602

How can I put the contents of a tag helper inside the tag?

I have a tag helper called <alert> which renders a styled <div> with some text content.

I am calling the tag helper like this now:

<alert type="danger" text="Confirm deletion of item"></alert>

How can I change the tag helper so that I can call it like this instead:

<alert type="danger">Confirm deletion of item</alert>

The reason I want to do this, is that I want to be able to easily have HTML code as contents. I.e. lists, forms, etc.

Here is the code for the tag helper:

public class AlertTagHelper : TagHelper
{
    /// <summary>
    /// primary (default), secondary, info, warning, danger
    /// </summary>
    public string Type { get; set; } = "primary";

    /// <summary>
    /// contents
    /// </summary>
    public string Text { get; set; } = "";

    /// <summary>
    /// true (default) or false
    /// </summary>
    public string DisplayIcon { get; set; } = "true";

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        bool displayIcon = DisplayIcon.ToLower() == "true";
        string icon = (Type.ToLower()) switch
        {
            "primary" => "fa-glasses",
            "secondary" => "fa-glasses",
            "info" => "fa-info-circle",
            "success" => "fa-thumbs-up",
            "warning" => "fa-exclamation-circle",
            "danger" => "fa-exclamation-triangle",
            _ => "fa-glasses",
        };
        output.TagMode = TagMode.StartTagAndEndTag;
        output.SuppressOutput(); // Produce the <div>-tag without being encapsulated by <alert></alert>.
        var sb = new StringBuilder();
        sb.AppendFormat($@"<div class=""alert-{Type} p-3 mb-3 border border-{Type} rounded display-block overflow-auto"">");
        if (displayIcon)
        { 
            sb.AppendFormat($@"<span class=""fas {icon} fa-fw fa-3x float-left mr-3""></span>");
        }
        sb.AppendFormat(Text);
        sb.AppendFormat("</div>");
        output.PreContent.SetHtmlContent(sb.ToString());
    }
}

Upvotes: 0

Views: 924

Answers (1)

Zhi Lv
Zhi Lv

Reputation: 21383

In the Custom Tag helper Process method, you could use the following code to get the Custom tag innerText value:

var innerText = output.GetChildContentAsync().Result.GetContent();

After modifying your code as below:

public class AlertTagHelper: TagHelper
{    /// <summary>
     /// primary (default), secondary, info, warning, danger
     /// </summary>
    public string Type { get; set; } = "primary";

    /// <summary>
    /// contents
    /// </summary>
    public string Text { get; set; } = "";

    /// <summary>
    /// true (default) or false
    /// </summary>
    public string DisplayIcon { get; set; } = "true";

    public override void Process(TagHelperContext context, TagHelperOutput output)
    {
        bool displayIcon = DisplayIcon.ToLower() == "true";

        string icon = (Type.ToLower()) switch
        {
            "primary" => "fa-glasses",
            "secondary" => "fa-glasses",
            "info" => "fa-info-circle",
            "success" => "fa-thumbs-up",
            "warning" => "fa-exclamation-circle",
            "danger" => "fa-exclamation-triangle",
            _ => "fa-glasses",
        };
        output.TagMode = TagMode.StartTagAndEndTag;
        output.SuppressOutput(); // Produce the <div>-tag without being encapsulated by <alert></alert>.
        var sb = new StringBuilder();
        sb.AppendFormat($@"<div class=""alert-{Type} p-3 mb-3 border border-{Type} rounded display-block overflow-auto"">");
        if (displayIcon)
        {
            sb.AppendFormat($@"<span class=""fas {icon} fa-fw fa-3x float-left mr-3""></span>");
        }


        var innerText = output.GetChildContentAsync().Result.GetContent();
        if (string.IsNullOrEmpty(Text))
        { 
            sb.AppendFormat(innerText);
        }
        else
        {
            sb.AppendFormat(Text);
        }
        sb.AppendFormat("</div>");
        output.PreContent.SetHtmlContent(sb.ToString());
    }
}

The View Page Code:

<alert type="danger" text="Confirm deletion of item"></alert>

<alert type="danger">inner Text: Confirm deletion of item</alert>

The result like this:

enter image description here

Upvotes: 4

Related Questions