Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the tag helper equivalent of Html.EditorFor

If I use Html.EditorFor on a property of type string then the generated element is by default an <input> of type 'text'.

Alternatively, if the property has the attribute [DataType(DataType.MultilineText)] then Html.EditorFor generates a <textarea>.

If I'm using tag helpers, however, then I have to choose the element type for myself, e.g. <input asp-for='MyProperty' />. This can use information about the property to determine the input's type (text, date, email etc), but will always generate an <input>, never a <textarea>, even if I have the [DataType] attribute.

This seems to go against the idea that I can make the change from single line to multiline in one place: the model. Now I have to go through all relevant views and make the change myself.

It seems to me perfectly possible that I could write my own tag helper that could look at the property attributes and decide whether to generate an <input> or <textarea>, but I can't find any reference to a predefined one.

Is there such a predefined tag helper, and if not, is there a reason why?

like image 427
Jasper Kent Avatar asked Jan 18 '18 13:01

Jasper Kent


Video Answer


2 Answers

The new way of using tag helper equivalent of Html.EditorFor is just by Using The Old HtmlHelper Inside Tag Helper itself. Take a look at this blog and you might find what you need or use my code instead. http://blog.techdominator.com/article/using-html-helper-inside-tag-helpers.html

 [HtmlTargetElement("editor", TagStructure = TagStructure.WithoutEndTag, 
    Attributes = ForAttributeName + "," + TemplateAttributeName)]
public class EditorTagHelper : TagHelper
{
    private IHtmlHelper _htmlHelper;

    private const string ForAttributeName = "asp-for";
    private const string TemplateAttributeName = "asp-template";

    [HtmlAttributeName(ForAttributeName)]
    public ModelExpression For { get; set; }


    [HtmlAttributeName(TemplateAttributeName)]
    public string Template { get; set; }

    [ViewContext]
    [HtmlAttributeNotBound]
    public ViewContext ViewContext { get; set; }

    public EditorTagHelper(IHtmlHelper htmlHelper)
    {
        _htmlHelper = htmlHelper;
    }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        if (context == null)
            throw new ArgumentNullException(nameof(context));

        if (output == null)
            throw new ArgumentNullException(nameof(output));

        output.SuppressOutput();

        (_htmlHelper as IViewContextAware).Contextualize(ViewContext);

        output.Content.SetHtmlContent(_htmlHelper.Editor(For.Name, Template));

        await Task.CompletedTask;
    }
}
like image 104
Prince Owusu Avatar answered Oct 02 '22 17:10

Prince Owusu


For what it's worth, some of what you discuss is actually part of the InputTagHelper. It will dynamically switch between different input types based on the property type (checkbox for bools, etc.). However, as you indicated, it will only ever generate an input, as it's explicitly an input taghelper. There's an entirely different taghelper for textareas. It is technically possible to create a custom tag helper to achieve what you want, but there's a good deal of work that goes into that. For a reference, see the source for InputTagHelper. At this time, it's not possible to call other tag helpers from a tag helper, so you would need to basically merge the entire code for InputTagHelper with that of TextAreaTagHelper into a custom tag helper. You could potentially save yourself a little work by inheriting your custom tag helper from InputTagHelper and then overriding Process to call base.Process() and then customizing the output. However, again, this is more complicated than a simple answer here can go into.

Long and short, yes, this is achievable with a custom tag helper, but it's going to require some work. Personally, I think it's a bit more work than it's worth, considering it's just one case: switching input with textarea for a multiline input, and you can technically still use EditorFor if your prefer.

If you want to go down this path, Microsoft has an article/tutorial that will give you a good start. Other than that, just study the source for the existing helpers.

like image 32
Chris Pratt Avatar answered Oct 02 '22 17:10

Chris Pratt