DmitryEfimenko / TwitterBootstrapMvc

Fluent implementation of ASP.NET-MVC HTML helpers for Twitter Bootstrap.
Apache License 2.0
223 stars 79 forks source link

HelpIcon method #436

Open johnwc opened 7 years ago

johnwc commented 7 years ago

You have a HelpText method, can you also add a HelpIcon method that produces the below HTML after the label?

<a title="" role="button" data-original-title="" data-toggle="popover" data-placement="auto" data-content="Help text description here, with support of <strong>html content.</strong>" data-trigger="focus"><span class="fa fa-info-circle"></span></a>
DmitryEfimenko commented 7 years ago

This seems too narrow of a use case. There are too many variations how other people might want this to be implemented. How to display this in horizontal vs inline forms. What if someone wants it before label or after input... show me your full use case and I'll see what can be done.

johnwc commented 7 years ago

I could say the exact same thing for HelpText. I'm asking for it to be able to be called on any label. In all my use of surfing the web, I have never seen it before the label or attached to any side of the input field. The only options/variations that are available for it is the placement and trigger tag.

Since I am a paid customer, I'd be more than happy to add this along with other things that help build this library. Effort is no issue.

johnwc commented 7 years ago

This is the code that I am using, that needs the functionality.

@f.FormGroup().DropDownListFor(m => m.Day, Model.DaysOptions).Label().HelpIcon()
johnwc commented 7 years ago

I'd be more than happy to make an extension for this in my code, if you could show me an example that produced sample html appended to the label.

DmitryEfimenko commented 7 years ago

I added .AppendHtml() and .PrependHtml() methods to the Label. Please get latest to get these. Now you can write a simple extension in your code like below:

public static class BmvcExtensions
{
    public static BootstrapLabel<TModel> HelpIcon<TModel>(this BootstrapLabel<TModel> label, IHtmlString helpText)
    {
        // customize the html below to fit your needs
        label.AppendHtml(MvcHtmlString.Create("<span>" + helpText.ToHtmlString() + "</span>"));
        return label;
    }
}
johnwc commented 7 years ago

Awesome, there is only one thing that it's missing though. I need access to the ModelMetadata object of the property. I need to retrieve the attributes of the property for the help content. Can you make the _labelModel field accessible to the extension, so that I can read the ModelMetadata?

DmitryEfimenko commented 7 years ago

it is already accessible:

var metadata = label._labelModel.Metadata;

It just has Attribute [EditorBrowsable(EditorBrowsableState.Never)] on it so that it does not pollute IntelliSense inside view with irrelevant properties.

markusgud commented 7 years ago

I tried using the new AppendHtml function to add an icon with popover. The problem is that it will be rendered outside the label, so it will ruin the form layout.

I also tried this, which works fine, except when the "required star" is shown, then the icon is rendered between the label and the "required star" instead of after the "required star".

{
  ...
  var lbl = tb.Label().Widths(Model.LabelWidths);
}
@lbl.LabelText(Model.Label).LabelHtml(Html.Bootstrap().Icon("glyphicon glyphicon-info-sign").Popover(new Popover(Model.Label, Model.Popover).Closeable())).ShowRequiredStar(Model.IsRequired)

Is it possible to make sure it is rendered as the last element within the label always?

johnwc commented 7 years ago

You should not be doing anything with the label in the method. You can use this extension that I created to accomplish this. You can remove the ShowRequiredStar call if you want, I did not want it to be there if there was a help icon.

public static BootstrapLabel<TModel> HelpIcon<TModel>(this BootstrapLabel<TModel> label, string helpText, string helpTitle)`
{
    if (!string.IsNullOrWhiteSpace(helpText))
    {
        TagBuilder a = new TagBuilder("a");
        a.Attributes.Add("title", helpTitle);
        a.Attributes.Add("role", "button");
        a.Attributes.Add("data-original-title", "");
        a.Attributes.Add("data-toggle", "popover");
        a.Attributes.Add("data-placement", "auto");
        a.Attributes.Add("data-content", helpText);
        a.Attributes.Add("data-trigger", "focus");
        a.Attributes.Add("data-html", "true");
        TagBuilder span = new TagBuilder("span");
        span.AddCssClass("fa");
        span.AddCssClass("fa-question-circle");
        a.InnerHtml = span.ToString();
        label.AppendHtml(new MvcHtmlString(a.ToString()));
        label.ShowRequiredStar(false);
    }
    return label;
}