Helper for writing Htmlhelpers

Asked

Viewed 241 times

4

I’m trying to write a Htmlhelper and seeing some basic examples I found one with the class TagBuilder that already helping:

namespace MyNamespace 
{  
    public static class MyHeleprs
    { 
        public static MvcHtmlString Image(this HtmlHelper htmlHelper, 
        string source, string alternativeText)
        {
            //declare the html helper 
            var builder = new TagBuilder("image"); 
            //hook the properties and add any required logic
            builder.MergeAttribute("src", source);
            builder.MergeAttribute("alt", alternativeText);
            //create the helper with a self closing capability
            return MvcHtmlString.Create(builder.ToString(TagRenderMode.SelfClosing));
        } 
    } 
}

Only that I wish to create a larger facilitator, in order to manipulate a value that will be displayed, some classes css etc. Soon, I would not like to have to rewrite a whole helper which already exists as the TextBoxFor or the EditorFor.

Starting from that will, so I thought I could reuse these helpers and add my manipulations.

Here’s what I was thinking about doing:

public static MvcHtmlString FieldFor<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression,
    string cssClass = "",
    bool placeHolder = false,
    bool autoFocus = false,
    object htmlAttributes = null)
{
    var builder = new TagBuilder(
        htmlHelper.TextBoxFor(expression, htmlAttributes).ToString());

    // value attribute
    ...
    builder.Attributes["type"] = "text";
    builder.Attributes["value"] = value;           

    // autofocus
    if (autoFocus)
        builder.Attributes.Add("autofocus", "autofocus");

    // css
    builder.AddCssClass(cssClass);

    // placeholder
    ...
    return new MvcHtmlString(builder.ToString(TagRenderMode.SelfClosing));
}

Anyway, highlighting what I thought:

var builder = new TagBuilder(htmlHelper.TextBoxFor(expression, htmlAttributes).ToString());

But the TagBuilder doesn’t work that way.

Manipulating something ready helps by not having to rewrite things the framework already does, such as generating the id and name of the element among others.

How can I solve this? What would be a more practical way?

1 answer

5


Example:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web;
using System.Web.Mvc;
using System.Web.Mvc.Html;
namespace System.Web.Mvc
{
    public static class Methods
    {
        public static String ControllerName(this HtmlHelper HtmlHelper)
        {
            return HtmlHelper.ViewContext.RequestContext.RouteData.Values["controller"].ToString();
        }
        public static String ControllerName(this AjaxHelper AjaxHelper)
        {
            return AjaxHelper.ViewContext.RequestContext.RouteData.Values["controller"].ToString();
        }
        public static String ActionName(this HtmlHelper HtmlHelper)
        {
            return HtmlHelper.ViewContext.RequestContext.RouteData.Values["action"].ToString();
        }
        public static String ActionName(this AjaxHelper AjaxHelper)
        {
            return AjaxHelper.ViewContext.RequestContext.RouteData.Values["action"].ToString();
        }
        public static IHtmlString FieldFor<TModel, TProperty>(
            this HtmlHelper<TModel> htmlHelper,
            Expression<Func<TModel, TProperty>> expression,
            string cssClass = "",
            string placeHolder = "",
            bool autoFocus = false,
            object htmlAttributes = null)
        {
            IDictionary<string, object> htmlAttributesList = new Dictionary<string, object>();
            if (htmlAttributes != null)
            {
                foreach (PropertyInfo prop in htmlAttributes.GetType().GetProperties())
                {
                    htmlAttributesList.Add(prop.Name, prop.GetValue(htmlAttributes));
                }
            }            
            if (!String.IsNullOrEmpty(cssClass))
            {
                htmlAttributesList.Add("css", cssClass);
            }
            if (!String.IsNullOrEmpty(placeHolder))
            {
                htmlAttributesList.Add("placeholder", placeHolder);
            }
            if (autoFocus)
            {
                htmlAttributesList.Add("autofocus", "autofocus");
            }            
            return new MvcHtmlString(htmlHelper.TextBoxFor(expression, htmlAttributesList).ToHtmlString());
        }      
    }
}

Note: There are beyond what you had some more methods that I usually use to assemble something standard, but, your doubt would be so the way to do without the TagBuilder.

How to use:

@Html.FieldFor(a => a.Nome);
@Html.FieldFor(a => a.Nome, htmlAttributes: new { id="Nome" })
@Html.FieldFor(a => a.Nome, cssClass: "", placeHolder: "", autoFocus: false, htmlAttributes: null)
@Html.FieldFor(a => a.Nome, "form-control", "Digite o seu nome", true, null)
  • 1

    Just remembering that this code is tested and worked at least in my tests I do not know if something happened keep informed... vlw @Tiagosilva

Browser other questions tagged

You are not signed in. Login or sign up in order to post.