Custom RadioButton 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 Radio Button with Model Binding to render radio buttons.

Following are the steps :

We have created a separate folder named CustomHelpers to hold Custom HTML Helpers. We have created a class named CustomRadioButtonHelperModelBinding which will contain code to render radio buttons.


The class file looks like below :

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

namespace CustomHtmlHelpers.CustomHelpers
{
    public static class CustomRadioButtonHelperModelBinding
    {
        public static MvcHtmlString CustomRadioButtonFor<TModel,TValue>(this HtmlHelper<TModel> helper, Expression<Func<TModel,TValue>> expression)
        {

            //Fetching the metadata related to expression. This includes property name, model value etc.
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);
            //Fetching the property name from metadata object.
            string propertyName = metadata.DisplayName ?? metadata.PropertyName ?? htmlFieldName;

            //Created a StringBuilder object to hold the html markup as string.
            StringBuilder radiobutton = new StringBuilder();
            TagBuilder radio = null;
            TagBuilder label = null;
            //Iterating over list from model.
            foreach (SelectListItem item in (IEnumerable<SelectListItem>)metadata.Model)
            {
                //Creating new radio control for each item in list.
                radio = new TagBuilder("input");
                //Creating new label control for each item in list.
                label = new TagBuilder("label");
                label.InnerHtml = item.Text;
                //Setting the input type to radio to render radio button.
                radio.Attributes.Add("type", "radio");
                radio.Attributes.Add("name", propertyName);
                radio.Attributes.Add("value", item.Text);
                //appending the label string to string builder object.
                radiobutton.Append(label.ToString());
                //appending the radio string to string builder object.
                radiobutton.Append(radio.ToString());
            }
            return MvcHtmlString.Create(radiobutton.ToString());
        }
    }
}

The above class is static class contains a static method which is extension method. This method accepts linq expression as parameter. The property name is fetched from the linq expression. The property name is used to group the radio buttons. The list from model is used to render the radio buttons.  We have created a object of StringBuilder class to hold the strings of label and radio button. We have used TagBuilder class to create both label and radio button control. 
                       The list fetched from model is iterated and for each item in the list the label and radio button is created and the string is added to StringBuilder object. Thus for all the values in the list the label and radio controls are created.

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 List<selectlistitem> players { get; set; }
    }
}

We have created a property named players. We will set this property with list in controller as shown below.


Controller :




public ActionResult About()
        {
            Register register = new Register();
            List<selectlistitem> listOfPLayers = new List<selectlistitem>();
            listOfPLayers.Add(new SelectListItem { Text = "Jack Wilshere", Value = "10" });
            listOfPLayers.Add(new SelectListItem { Text = "Thierry Henry", Value = "14" });
            listOfPLayers.Add(new SelectListItem { Text = "Cesc Fabregas", Value = "04" });
            listOfPLayers.Add(new SelectListItem { Text = "Santi Cazorla", Value = "19" });
            listOfPLayers.Add(new SelectListItem { Text = "Tomas Rosicky", Value = "08" });
            register.players = listOfPLayers;
            return View(register);
        }

We have created object of ViewModel i.e. Register. We have also created a list of type SelectedListItem and assigned to players property of ViewModel. This property is then used on view as shown below.

View :




@model CustomHtmlHelpers.Models.Register

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

<h2>About</h2>
<p>
@Html.CustomRadioButtonFor(c => c.players)
</p>

UI :



Rendered HTML :


<label>Jack Wilshere</label>
<input name="players" type="radio" value="Jack Wilshere"></input>
<label>Thierry Henry</label>
<input name="players" type="radio" value="Thierry Henry"></input>
<label>Cesc Fabregas</label>
<input name="players" type="radio" value="Cesc Fabregas"></input>
<label>Santi Cazorla</label>
<input name="players" type="radio" value="Santi Cazorla"></input>
<label>Tomas Rosicky</label>
<input name="players" type="radio" value="Tomas Rosicky"></input>

0 comments:

Post a Comment