namespace System.Web.Mvc.Html {
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Web;
using System.Web.Mvc.Resources;
public static class SelectExtensions {
// DropDownList
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name) {
return DropDownList(htmlHelper, name, null /* selectList */, null /* optionLabel */, null /* htmlAttributes */);
}
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, string optionLabel) {
return DropDownList(htmlHelper, name, null /* selectList */, optionLabel, null /* htmlAttributes */);
}
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList) {
return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, null /* htmlAttributes */);
}
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, object htmlAttributes) {
return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, IDictionary htmlAttributes) {
return DropDownList(htmlHelper, name, selectList, null /* optionLabel */, htmlAttributes);
}
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, string optionLabel) {
return DropDownList(htmlHelper, name, selectList, optionLabel, null /* htmlAttributes */);
}
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, string optionLabel, object htmlAttributes) {
return DropDownList(htmlHelper, name, selectList, optionLabel, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString DropDownList(this HtmlHelper htmlHelper, string name, IEnumerable selectList, string optionLabel, IDictionary htmlAttributes) {
return DropDownListHelper(htmlHelper, name, selectList, optionLabel, htmlAttributes);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList) {
return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, null /* htmlAttributes */);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, object htmlAttributes) {
return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, IDictionary htmlAttributes) {
return DropDownListFor(htmlHelper, expression, selectList, null /* optionLabel */, htmlAttributes);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, string optionLabel) {
return DropDownListFor(htmlHelper, expression, selectList, optionLabel, null /* htmlAttributes */);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, string optionLabel, object htmlAttributes) {
return DropDownListFor(htmlHelper, expression, selectList, optionLabel, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString DropDownListFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, string optionLabel, IDictionary htmlAttributes) {
if (expression == null) {
throw new ArgumentNullException("expression");
}
return DropDownListHelper(htmlHelper, ExpressionHelper.GetExpressionText(expression), selectList, optionLabel, htmlAttributes);
}
private static MvcHtmlString DropDownListHelper(HtmlHelper htmlHelper, string expression, IEnumerable selectList, string optionLabel, IDictionary htmlAttributes) {
return SelectInternal(htmlHelper, optionLabel, expression, selectList, false /* allowMultiple */, htmlAttributes);
}
// ListBox
public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name) {
return ListBox(htmlHelper, name, null /* selectList */, null /* htmlAttributes */);
}
public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable selectList) {
return ListBox(htmlHelper, name, selectList, (IDictionary)null);
}
public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable selectList, object htmlAttributes) {
return ListBox(htmlHelper, name, selectList, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString ListBox(this HtmlHelper htmlHelper, string name, IEnumerable selectList, IDictionary htmlAttributes) {
return ListBoxHelper(htmlHelper, name, selectList, htmlAttributes);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString ListBoxFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList) {
return ListBoxFor(htmlHelper, expression, selectList, null /* htmlAttributes */);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString ListBoxFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, object htmlAttributes) {
return ListBoxFor(htmlHelper, expression, selectList, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "Users cannot use anonymous methods with the LambdaExpression type")]
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString ListBoxFor(this HtmlHelper htmlHelper, Expression> expression, IEnumerable selectList, IDictionary htmlAttributes) {
if (expression == null) {
throw new ArgumentNullException("expression");
}
return ListBoxHelper(htmlHelper,
ExpressionHelper.GetExpressionText(expression),
selectList,
htmlAttributes);
}
private static MvcHtmlString ListBoxHelper(HtmlHelper htmlHelper, string name, IEnumerable selectList, IDictionary htmlAttributes) {
return SelectInternal(htmlHelper, null /* optionLabel */, name, selectList, true /* allowMultiple */, htmlAttributes);
}
// Helper methods
private static IEnumerable GetSelectData(this HtmlHelper htmlHelper, string name) {
object o = null;
if (htmlHelper.ViewData != null) {
o = htmlHelper.ViewData.Eval(name);
}
if (o == null) {
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.HtmlHelper_MissingSelectData,
name,
"IEnumerable"));
}
IEnumerable selectList = o as IEnumerable;
if (selectList == null) {
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentCulture,
MvcResources.HtmlHelper_WrongSelectDataType,
name,
o.GetType().FullName,
"IEnumerable"));
}
return selectList;
}
internal static string ListItemToOption(SelectListItem item) {
TagBuilder builder = new TagBuilder("option") {
InnerHtml = HttpUtility.HtmlEncode(item.Text)
};
if (item.Value != null) {
builder.Attributes["value"] = item.Value;
}
if (item.Selected) {
builder.Attributes["selected"] = "selected";
}
return builder.ToString(TagRenderMode.Normal);
}
private static MvcHtmlString SelectInternal(this HtmlHelper htmlHelper, string optionLabel, string name, IEnumerable selectList, bool allowMultiple, IDictionary htmlAttributes) {
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (String.IsNullOrEmpty(fullName)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}
bool usedViewData = false;
// If we got a null selectList, try to use ViewData to get the list of items.
if (selectList == null) {
selectList = htmlHelper.GetSelectData(fullName);
usedViewData = true;
}
object defaultValue = (allowMultiple) ? htmlHelper.GetModelStateValue(fullName, typeof(string[])) : htmlHelper.GetModelStateValue(fullName, typeof(string));
// If we haven't already used ViewData to get the entire list of items then we need to
// use the ViewData-supplied value before using the parameter-supplied value.
if (!usedViewData) {
if (defaultValue == null) {
defaultValue = htmlHelper.ViewData.Eval(fullName);
}
}
if (defaultValue != null) {
IEnumerable defaultValues = (allowMultiple) ? defaultValue as IEnumerable : new[] { defaultValue };
IEnumerable values = from object value in defaultValues select Convert.ToString(value, CultureInfo.CurrentCulture);
HashSet selectedValues = new HashSet(values, StringComparer.OrdinalIgnoreCase);
List newSelectList = new List();
foreach (SelectListItem item in selectList) {
item.Selected = (item.Value != null) ? selectedValues.Contains(item.Value) : selectedValues.Contains(item.Text);
newSelectList.Add(item);
}
selectList = newSelectList;
}
// Convert each ListItem to an