These overloads will do the hopefully-obvious thing with a Model => Model.Property
and a List of SelectListItem
s (or a single SelectListItem
)
Use the RadioButtonLabelLayout
setting to control whether you nest the radio button inside its label, or lay them out as siblings; and whether you like text before button or vice versa.
public static class HtmlHelperRadioButtonExtensions
{
/// <summary>
/// Returns radio buttons for the property in the object represented by the specified expression.
/// A radio button is rendered for each item in <paramref name="listOfValues"/>.
/// Use <paramref name="labelLayout"/> to control whether each label contains its button, or is a sibling,
/// and whether button precedes text or vice versa.
/// <list type="bullet">
/// <item>
/// <term>Example result for the default labelLayout= RadioButtonLabelLayout.LabelTagContainsButtonThenText:</term>
/// <description>
/// <label for="Object_Property_Red"><input id="Object_Property_Red" name="Object.Property" type="radio" value="Red" /> Red</label>
/// <label for="Object_Property_Blue"><input id="Object_Property_Blue" name="Object.Property" type="radio" value="Blue" /> Blue</label>
/// </description>
/// </item>
/// <item>
/// <term>Example result for labelLayout= RadioButtonLabelLayout.SiblingBeforeButton:</term>
/// <description>
/// <label for="Object_Property_Red">Red</label> <input id="Object_Property_Red" name="Object.Property" type="radio" value="Red" />
/// <label for="Object_Property_Blue"> Blue</label> <input id="Object_Property_Blue" name="Object.Property" type="radio" value="Blue" />
/// </description>
/// </item>
/// </list>
/// </summary>
/// <param name="listOfValues">Used to generate the Value and the Label Text for each radio button</param>
/// <param name="labelLayout">One <see cref="RadioButtonLabelLayout"/> to control the layout of the rendered button and its label.</param>
/// <returns>
/// An MvcHtmlString for the required buttons
///
/// </returns>
public static MvcHtmlString
RadioButtonsFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> listOfValues,
RadioButtonLabelLayout labelLayout = RadioButtonLabelLayout.LabelTagContainsButtonThenText)
{
if (listOfValues == null) { return null; }
var buttons= listOfValues.Select(item => RadioButtonFor(htmlHelper, expression, item, labelLayout));
return MvcHtmlString.Create(buttons.Aggregate(new StringBuilder(), (sb, o) => sb.Append(o), sb => sb.ToString()));
}
/// <summary> Create an <see cref="IEnumerable{T}"/> list of radio buttons ready for individual processing before rendering</summary>
public static IEnumerable<MvcHtmlString> RadioButtonListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> listOfValues,
RadioButtonLabelLayout labelLayout)
{
if (listOfValues == null) { return new MvcHtmlString[0]; }
return listOfValues.Select( item => RadioButtonFor(htmlHelper, expression, item, labelLayout) );
}
public static MvcHtmlString RadioButtonFor<TModel, TProperty>(
HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
SelectListItem item,
RadioButtonLabelLayout labelLayout)
{
var id = htmlHelper.IdFor(expression) + " " + item.Value;
var radio = htmlHelper.RadioButtonFor(expression, item.Value, new {id}).ToHtmlString();
var labelText = HttpUtility.HtmlEncode(item.Text);
TagBuilder nestingLabel = null;
switch (labelLayout)
{
case RadioButtonLabelLayout.LabelTagContainsTextThenButton:
nestingLabel = new TagBuilder("label") {InnerHtml = labelText + " " + radio};
return MvcHtmlString.Create(nestingLabel.ToString());
case RadioButtonLabelLayout.LabelTagContainsButtonThenText:
nestingLabel = new TagBuilder("label") {InnerHtml = radio + " " + labelText};
return MvcHtmlString.Create(nestingLabel.ToString());
case RadioButtonLabelLayout.SiblingBeforeButton:
return MvcHtmlString.Create(radio + " " + htmlHelper.Label(id, labelText));
case RadioButtonLabelLayout.SiblingAfterButton:
return MvcHtmlString.Create(htmlHelper.Label(id, labelText) + " " + radio);
default:
throw new ArgumentOutOfRangeException("labelLayout", labelLayout,
"This is not a valid RadioButtonLayoutStyle for rendering a radio button");
}
}
}
public enum RadioButtonLabelLayout
{
LabelTagContainsButtonThenText = 0,
LabelTagContainsTextThenButton = 1,
SiblingBeforeButton = 2,
SiblingAfterButton = 3,
}