How to use Html.CheckBox (list) with IEnumerable<T> with validation

Fabian picture Fabian · Aug 12, 2010 · Viewed 15.1k times · Source

I'm working on a page where the user needs to fill in some information and finally make a selection of 1 or more customers with check-boxes.

The list of customers is an IEnumerable<Customer> which I pass into my Model. How would I go about creating the list of check-boxes using .CheckBoxFor()?

And finally I would like to be able to validate if at least 1 check-box has been selected.

Request is the object which holds the information the user entered.

<% foreach (var customer in Model.Request.Customers) { %>
   <%= Html.CheckBoxFor(/* customer */) %>
<% } %>

Can anyone point me in the right direction? Or am I going about this all wrong?

Answer

gnome picture gnome · Aug 16, 2010

You could create a custom html extensions class and overload the CheckBoxFor method like below. The method evaluates the metadata.Model to the value passed into it (like U.S. State). You can get the checkbox value/s from the FormCollection in the ControllerAction:

public ActionResult Edit(FormCollection formCollection) 
{
    // Get the value(s)
    string checkBox = formCollection["State"];

    // perform validation
    ....
}

Example assumes a keyvaluepair generic list

<% foreach (var element in UnitedStatesDictionary())
{ %>
<%= Html.CheckBoxFor(model => model.State, null, element.Key) %><%= element.Value  %><br />
<% } %>

HtmlExtensions.cs

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

    public static class HtmlExtensions
    {
        /// <summary>
        /// Checks the box for.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="html">The HTML.</param>
        /// <param name="expression">The expression.</param>
        /// <returns>Checkbox</returns>
        public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
        {
            return CheckBoxFor(html, expression, new RouteDirection());
        }


        /// <summary>
        /// Checks the box for.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="html">The HTML.</param>
        /// <param name="expression">The expression.</param>
        /// <param name="htmlAttributes">The HTML attributes.</param>
        /// <returns>Checkbox</returns>
        public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes)
        {

            return CheckBoxFor(html, expression, htmlAttributes, "");
        }

        /// <summary>
        /// Checks the box for.
        /// </summary>
        /// <typeparam name="TModel">The type of the model.</typeparam>
        /// <typeparam name="TValue">The type of the value.</typeparam>
        /// <param name="html">The HTML.</param>
        /// <param name="expression">The expression.</param>
        /// <param name="htmlAttributes">The HTML attributes.</param>
        /// <param name="checkedValue">The checked value.</param>
        /// <returns>Checkbox</returns>
        public static MvcHtmlString CheckBoxFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression, object htmlAttributes, string checkedValue)
        {

            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
            string htmlFieldName = ExpressionHelper.GetExpressionText(expression);

            TagBuilder tag = new TagBuilder("input");
            tag.Attributes.Add("type", "checkbox");
            tag.Attributes.Add("name", metadata.PropertyName);
            if (!string.IsNullOrEmpty(checkedValue))
            {
                tag.Attributes.Add("value", checkedValue);
            }
            else
            {
                tag.Attributes.Add("value", metadata.Model.ToString());
            }

            if (htmlAttributes != null)
            {
                tag.MergeAttributes(new RouteValueDictionary(htmlAttributes));
            }

            if (metadata.Model.ToString() == checkedValue)
            {
                tag.Attributes.Add("checked", "checked");
            }
            return MvcHtmlString.Create(tag.ToString(TagRenderMode.SelfClosing));
        }
    }

While I'm at it, here's my list of United States to complete code:

/// <summary>
/// United States dictionary.
/// </summary>
/// <returns>List of United States</returns>
public static List<KeyValuePair<string, string>> UnitedStatesDictionary()
{
    var arrList = new List<KeyValuePair<string, string>>();
    arrList.Add(new KeyValuePair<string, string>("AL", "Alabama"));
    arrList.Add(new KeyValuePair<string, string>("AK", "Alaska"));
    arrList.Add(new KeyValuePair<string, string>("AZ", "Arizona" ));
    arrList.Add(new KeyValuePair<string, string>("AR", "Arkansas" ));
    arrList.Add(new KeyValuePair<string, string>("CA", "California" ));
    arrList.Add(new KeyValuePair<string, string>("CO", "Colorado" ));
    arrList.Add(new KeyValuePair<string, string>("CT", "Connecticut" ));
    arrList.Add(new KeyValuePair<string, string>("DE", "Delaware" ));
    arrList.Add(new KeyValuePair<string, string>("DC", "District Of Columbia" ));
    arrList.Add(new KeyValuePair<string, string>("FL", "Florida" ));
    arrList.Add(new KeyValuePair<string, string>("GA", "Georgia" ));
    arrList.Add(new KeyValuePair<string, string>("HI", "Hawaii" ));
    arrList.Add(new KeyValuePair<string, string>("ID", "Idaho" ));
    arrList.Add(new KeyValuePair<string, string>("IL", "Illinois" ));
    arrList.Add(new KeyValuePair<string, string>("IN", "Indiana" ));
    arrList.Add(new KeyValuePair<string, string>("IA", "Iowa" ));
    arrList.Add(new KeyValuePair<string, string>("KS", "Kansas" ));
    arrList.Add(new KeyValuePair<string, string>("KY", "Kentucky" ));
    arrList.Add(new KeyValuePair<string, string>("LA", "Louisiana" ));
    arrList.Add(new KeyValuePair<string, string>("ME", "Maine" ));
    arrList.Add(new KeyValuePair<string, string>("MD", "Maryland" ));
    arrList.Add(new KeyValuePair<string, string>("MA", "Massachusetts" ));
    arrList.Add(new KeyValuePair<string, string>("MI", "Michigan" ));
    arrList.Add(new KeyValuePair<string, string>("MN", "Minnesota" ));
    arrList.Add(new KeyValuePair<string, string>("MS", "Mississippi" ));
    arrList.Add(new KeyValuePair<string, string>("MO", "Missouri" ));
    arrList.Add(new KeyValuePair<string, string>("MT", "Montana" ));
    arrList.Add(new KeyValuePair<string, string>("NE", "Nebraska" ));
    arrList.Add(new KeyValuePair<string, string>("NV", "Nevada" ));
    arrList.Add(new KeyValuePair<string, string>("NH", "New Hampshire" ));
    arrList.Add(new KeyValuePair<string, string>("NJ", "New Jersey" ));
    arrList.Add(new KeyValuePair<string, string>("NM", "New Mexico" ));
    arrList.Add(new KeyValuePair<string, string>("NY", "New York" ));
    arrList.Add(new KeyValuePair<string, string>("NC", "North Carolina" ));
    arrList.Add(new KeyValuePair<string, string>("ND", "North Dakota" ));
    arrList.Add(new KeyValuePair<string, string>("OH", "Ohio" ));
    arrList.Add(new KeyValuePair<string, string>("OK", "Oklahoma" ));
    arrList.Add(new KeyValuePair<string, string>("OR", "Oregon" ));
    arrList.Add(new KeyValuePair<string, string>("PA", "Pennsylvania" ));
    arrList.Add(new KeyValuePair<string, string>("RI", "Rhode Island" ));
    arrList.Add(new KeyValuePair<string, string>("SC", "South Carolina" ));
    arrList.Add(new KeyValuePair<string, string>("SD", "South Dakota" ));
    arrList.Add(new KeyValuePair<string, string>("TN", "Tennessee" ));
    arrList.Add(new KeyValuePair<string, string>("TX", "Texas" ));
    arrList.Add(new KeyValuePair<string, string>("UT", "Utah" ));
    arrList.Add(new KeyValuePair<string, string>("VT", "Vermont" ));
    arrList.Add(new KeyValuePair<string, string>("VA", "Virginia" ));
    arrList.Add(new KeyValuePair<string, string>("WA", "Washington" ));
    arrList.Add(new KeyValuePair<string, string>("WV", "West Virginia" ));
    arrList.Add(new KeyValuePair<string, string>("WI", "Wisconsin" ));
    arrList.Add(new KeyValuePair<string, string>("WY", "Wyoming" ));
    return arrList;
}