There was an Html.RadioButtonList
extension method in ASP.NET MVC Futures. Has anyone found a code for a strongly typed version RadioButtonListFor<T>
. It would look like this in a view:
<%= Html.RadioButtonListFor(model=>model.Item,Model.ItemList) %>
RadioButtonList Control is same as DropDownList but it displays a list of radio buttons that can be arranged either horizontally or vertically. You can select only one item from the given RadioButtonList of options. These options are mutually exclusive.
RadioButton is a kind of toggle control which receives the input from a user in the form of a click. In radio-button, all buttons are connected with the same group name and id. User can select any one button option from the given radiobuttons or list.
Here is the usage in the aspx page
<%= Html.RadioButtonListFor(m => m.GenderRadioButtonList)%>
Here is the view model
public class HomePageViewModel { public enum GenderType { Male, Female } public RadioButtonListViewModel<GenderType> GenderRadioButtonList { get; set; } public HomePageViewModel() { GenderRadioButtonList = new RadioButtonListViewModel<GenderType> { Id = "Gender", SelectedValue = GenderType.Male, ListItems = new List<RadioButtonListItem<GenderType>> { new RadioButtonListItem<GenderType>{Text = "Male", Value = GenderType.Male}, new RadioButtonListItem<GenderType>{Text = "Female", Value = GenderType.Female} } }; } }
Here's the view model used for radio button lists
public class RadioButtonListViewModel<T> { public string Id { get; set; } private T selectedValue; public T SelectedValue { get { return selectedValue; } set { selectedValue = value; UpdatedSelectedItems(); } } private void UpdatedSelectedItems() { if (ListItems == null) return; ListItems.ForEach(li => li.Selected = Equals(li.Value, SelectedValue)); } private List<RadioButtonListItem<T>> listItems; public List<RadioButtonListItem<T>> ListItems { get { return listItems; } set { listItems = value; UpdatedSelectedItems(); } } } public class RadioButtonListItem<T> { public bool Selected { get; set; } public string Text { get; set; } public T Value { get; set; } public override string ToString() { return Value.ToString(); } }
Here's the extension methods for RadioButtonListFor
public static class HtmlHelperExtensions { public static string RadioButtonListFor<TModel, TRadioButtonListValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel<TRadioButtonListValue>>> expression) where TModel : class { return htmlHelper.RadioButtonListFor(expression, null); } public static string RadioButtonListFor<TModel, TRadioButtonListValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel<TRadioButtonListValue>>> expression, object htmlAttributes) where TModel : class { return htmlHelper.RadioButtonListFor(expression, new RouteValueDictionary(htmlAttributes)); } public static string RadioButtonListFor<TModel, TRadioButtonListValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, RadioButtonListViewModel<TRadioButtonListValue>>> expression, IDictionary<string, object> htmlAttributes) where TModel : class { var inputName = GetInputName(expression); RadioButtonListViewModel<TRadioButtonListValue> radioButtonList = GetValue(htmlHelper, expression); if (radioButtonList == null) return String.Empty; if (radioButtonList.ListItems == null) return String.Empty; var divTag = new TagBuilder("div"); divTag.MergeAttribute("id", inputName); divTag.MergeAttribute("class", "radio"); foreach (var item in radioButtonList.ListItems) { var radioButtonTag = RadioButton(htmlHelper, inputName, new SelectListItem{Text=item.Text, Selected = item.Selected, Value = item.Value.ToString()}, htmlAttributes); divTag.InnerHtml += radioButtonTag; } return divTag + htmlHelper.ValidationMessage(inputName, "*"); } public static string GetInputName<TModel, TProperty>(Expression<Func<TModel, TProperty>> expression) { if (expression.Body.NodeType == ExpressionType.Call) { var methodCallExpression = (MethodCallExpression)expression.Body; string name = GetInputName(methodCallExpression); return name.Substring(expression.Parameters[0].Name.Length + 1); } return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1); } private static string GetInputName(MethodCallExpression expression) { // p => p.Foo.Bar().Baz.ToString() => p.Foo OR throw... var methodCallExpression = expression.Object as MethodCallExpression; if (methodCallExpression != null) { return GetInputName(methodCallExpression); } return expression.Object.ToString(); } public static string RadioButton(this HtmlHelper htmlHelper, string name, SelectListItem listItem, IDictionary<string, object> htmlAttributes) { var inputIdSb = new StringBuilder(); inputIdSb.Append(name) .Append("_") .Append(listItem.Value); var sb = new StringBuilder(); var builder = new TagBuilder("input"); if (listItem.Selected) builder.MergeAttribute("checked", "checked"); builder.MergeAttribute("type", "radio"); builder.MergeAttribute("value", listItem.Value); builder.MergeAttribute("id", inputIdSb.ToString()); builder.MergeAttribute("name", name + ".SelectedValue"); builder.MergeAttributes(htmlAttributes); sb.Append(builder.ToString(TagRenderMode.SelfClosing)); sb.Append(RadioButtonLabel(inputIdSb.ToString(), listItem.Text, htmlAttributes)); sb.Append("<br>"); return sb.ToString(); } public static string RadioButtonLabel(string inputId, string displayText, IDictionary<string, object> htmlAttributes) { var labelBuilder = new TagBuilder("label"); labelBuilder.MergeAttribute("for", inputId); labelBuilder.MergeAttributes(htmlAttributes); labelBuilder.InnerHtml = displayText; return labelBuilder.ToString(TagRenderMode.Normal); } public static TProperty GetValue<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class { TModel model = htmlHelper.ViewData.Model; if (model == null) { return default(TProperty); } Func<TModel, TProperty> func = expression.Compile(); return func(model); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With