1 // Copyright (c) Microsoft Corporation. All rights reserved. See License.txt in the project root for license information.
2 
3 using System;
4 using System.Collections;
5 using System.Collections.Generic;
6 using System.Globalization;
7 using System.Linq;
8 using System.Web.Mvc;
9 using System.Web.Mvc.Html;
10 using Microsoft.Web.Mvc.Properties;
11 
12 namespace Microsoft.Web.Mvc
13 {
14     public static class RadioListExtensions
15     {
RadioButtonList(this HtmlHelper htmlHelper, string name)16         public static MvcHtmlString[] RadioButtonList(this HtmlHelper htmlHelper, string name)
17         {
18             return RadioButtonList(htmlHelper, name, (IDictionary<string, object>)null);
19         }
20 
RadioButtonList(this HtmlHelper htmlHelper, string name, object htmlAttributes)21         public static MvcHtmlString[] RadioButtonList(this HtmlHelper htmlHelper, string name, object htmlAttributes)
22         {
23             return RadioButtonList(htmlHelper, name, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
24         }
25 
RadioButtonList(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes)26         public static MvcHtmlString[] RadioButtonList(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes)
27         {
28             IEnumerable<SelectListItem> selectList = htmlHelper.GetSelectData(name);
29             return htmlHelper.RadioButtonListInternal(name, selectList, true /* usedViewData */, htmlAttributes);
30         }
31 
RadioButtonList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList)32         public static MvcHtmlString[] RadioButtonList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList)
33         {
34             return RadioButtonList(htmlHelper, name, selectList, null);
35         }
36 
RadioButtonList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)37         public static MvcHtmlString[] RadioButtonList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, object htmlAttributes)
38         {
39             return RadioButtonList(htmlHelper, name, selectList, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
40         }
41 
RadioButtonList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)42         public static MvcHtmlString[] RadioButtonList(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, IDictionary<string, object> htmlAttributes)
43         {
44             return htmlHelper.RadioButtonListInternal(name, selectList, false /* usedViewData */, htmlAttributes);
45         }
46 
GetSelectData(this HtmlHelper htmlHelper, string name)47         private static IEnumerable<SelectListItem> GetSelectData(this HtmlHelper htmlHelper, string name)
48         {
49             object o = null;
50             if (htmlHelper.ViewData != null)
51             {
52                 o = htmlHelper.ViewData.Eval(name);
53             }
54             if (o == null)
55             {
56                 throw new InvalidOperationException(
57                     String.Format(
58                         CultureInfo.CurrentCulture,
59                         MvcResources.HtmlHelper_MissingSelectData,
60                         name,
61                         typeof(IEnumerable<SelectListItem>)));
62             }
63             IEnumerable<SelectListItem> selectList = o as IEnumerable<SelectListItem>;
64             if (selectList == null)
65             {
66                 throw new InvalidOperationException(
67                     String.Format(
68                         CultureInfo.CurrentCulture,
69                         MvcResources.HtmlHelper_WrongSelectDataType,
70                         name,
71                         o.GetType().FullName,
72                         typeof(IEnumerable<SelectListItem>)));
73             }
74             return selectList;
75         }
76 
RadioButtonListInternal(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, bool usedViewData, IDictionary<string, object> htmlAttributes)77         private static MvcHtmlString[] RadioButtonListInternal(this HtmlHelper htmlHelper, string name, IEnumerable<SelectListItem> selectList, bool usedViewData, IDictionary<string, object> htmlAttributes)
78         {
79             if (String.IsNullOrEmpty(name))
80             {
81                 throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
82             }
83             if (selectList == null)
84             {
85                 throw new ArgumentNullException("selectList");
86             }
87 
88             // If we haven't already used ViewData to get the entire list of items then we need to
89             // use the ViewData-supplied value before using the parameter-supplied value.
90             if (!usedViewData)
91             {
92                 object defaultValue = htmlHelper.ViewData.Eval(name);
93 
94                 if (defaultValue != null)
95                 {
96                     IEnumerable defaultValues = new[] { defaultValue };
97                     IEnumerable<string> values = from object value in defaultValues
98                                                  select Convert.ToString(value, CultureInfo.CurrentCulture);
99                     HashSet<string> selectedValues = new HashSet<string>(values, StringComparer.OrdinalIgnoreCase);
100                     List<SelectListItem> newSelectList = new List<SelectListItem>();
101 
102                     foreach (SelectListItem item in selectList)
103                     {
104                         item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
105                         newSelectList.Add(item);
106                     }
107 
108                     selectList = newSelectList;
109                 }
110             }
111 
112             IEnumerable<MvcHtmlString> radioButtons = selectList.Select(item => htmlHelper.RadioButton(name, item.Value, item.Selected, htmlAttributes));
113 
114             return radioButtons.ToArray();
115         }
116     }
117 }
118