Custom TextArea HTML Helper with Model Binding in MVC3 razor

  1. In MVC3 Razor we have HTML helpers to render different controls. 
  2. Instead of using these helpers we can create our own helper classes and methods and use them as we want.
  3. The creation of custom helpers provides flexibility to change the attributes and style of the control that renders.
  4. In this article we will create Custom HTML helper for TextArea with Model Binding to render TextArea.

Following are the steps :

We have created a separate folder named CustomHelpers to hold Custom HTML Helpers. We have created a class named CustomTextAreaModelBinding.cs which will contain code to render TextArea.


The class file looks like below :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Linq.Expressions;

namespace CustomHtmlHelpers.CustomHelpers
{
    public static class CustomTextAreaModelBinding
    {
        //This overload accepts single expression as parameter.
        public static MvcHtmlString Custom_TextAreaFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression)
        {
            return Custom_TextAreaFor(helper, expression, null);
        }

        //This overload accepts expression and htmlAttributes object as parameter.
        public static MvcHtmlString Custom_TextAreaFor<TModel, TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
        {
            //Fetching the metadata related to expression. This includes name of the property, model value of the property as well.
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            //Fetching the property name.
            string propertyName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName.Split('.').Last();

            //Creating a textarea tag using TagBuilder class.
            TagBuilder textarea = new TagBuilder("textarea");
            //Setting the name and id attribute.
            textarea.Attributes.Add("name", propertyName);
            textarea.Attributes.Add("id", propertyName);

            //Setting the value attribute of textbox with model value if present.
            if (metadata.Model != null)
            {
                textarea.InnerHtml = metadata.Model.ToString();
            }
            //merging any htmlAttributes passed.
            textarea.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            return MvcHtmlString.Create(textarea.ToString(TagRenderMode.Normal));
        }
    }
}

Overload 1 : The first overload accepts linq expression as parameter. This method is extension method and accepts object of HtmlHelper class. The first parameter adds this overload to System.Web.MVC namespace. On view we can access this method using @html. This overload in turn calls another overload.

Overload 2 : The second overload accepts linq expression and htmlAttributes object as parameters. We have use ModelMetaData class to get all details or meta data about the expression. We get the property name and model value using ModelMetaData class.

The propertyName is used to set the name attribute of the control. We have used TagBuilder class to create TextArea tag.
          We have also assigned other attributes passed using htmlAttributes object. The Model value is fetched if present and assigned to textarea's innerHtml property. The entire control is returned as MVCHtmlString format.


ViewModel :


using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.ComponentModel.DataAnnotations;


namespace CustomHtmlHelpers.Models
{
    public class Register
    {
        public string Address { get; set; }
    }
}

We have created an Address property in ViewModel. We will bind our TextArea with this property.

Controller :



public ActionResult About()
        {
            Register register = new Register();
            register.Address = "Mumbai, India";
            return View(register);
        }

In the About Action method, we have created object of Register class, assigned value to address property and we have returned the View with this ViewModel object.

View :



@model CustomHtmlHelpers.Models.Register

@{
    ViewBag.Title = "About Us";
}

<h2>About</h2>
<div>
@Html.Custom_TextAreaFor(Model => Model.Address)
@Html.Custom_TextAreaFor(Model => Model.Address, new { style="color:Red;resize:none;"})
</div>

UI :



Rendered HTML :

<textarea id="Address" name="Address">Mumbai, India</textarea>
<textarea id="Address" name="Address" style="color:Red;resize:none;">Mumbai, India</textarea>

This is how we can create our own Custom Helper to render TextArea with Model Binding.

2 comments:

  1. Nice example on how to create Custom Helper for TextArea control.

    ReplyDelete