1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
namespace System.Web.Mvc.Html {
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Linq.Expressions;
using System.Web.Mvc.Resources;
public static class TextAreaExtensions {
// These values are similar to the defaults used by WebForms
// when using <asp:TextBox TextMode="MultiLine"> without specifying
// the Rows and Columns attributes.
private const int TextAreaRows = 2;
private const int TextAreaColumns = 20;
private static Dictionary<string, object> implicitRowsAndColumns = new Dictionary<string, object> {
{ "rows", TextAreaRows.ToString(CultureInfo.InvariantCulture) },
{ "cols", TextAreaColumns.ToString(CultureInfo.InvariantCulture) },
};
private static Dictionary<string, object> GetRowsAndColumnsDictionary(int rows, int columns) {
if (rows < 0) {
throw new ArgumentOutOfRangeException("rows", MvcResources.HtmlHelper_TextAreaParameterOutOfRange);
}
if (columns < 0) {
throw new ArgumentOutOfRangeException("columns", MvcResources.HtmlHelper_TextAreaParameterOutOfRange);
}
Dictionary<string, object> result = new Dictionary<string, object>();
if (rows > 0) {
result.Add("rows", rows.ToString(CultureInfo.InvariantCulture));
}
if (columns > 0) {
result.Add("cols", columns.ToString(CultureInfo.InvariantCulture));
}
return result;
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name) {
return TextArea(htmlHelper, name, null /* value */, null /* htmlAttributes */);
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, object htmlAttributes) {
return TextArea(htmlHelper, name, null /* value */, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, IDictionary<string, object> htmlAttributes) {
return TextArea(htmlHelper, name, null /* value */, htmlAttributes);
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value) {
return TextArea(htmlHelper, name, value, null /* htmlAttributes */);
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, object htmlAttributes) {
return TextArea(htmlHelper, name, value, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, IDictionary<string, object> htmlAttributes) {
ModelMetadata metadata = ModelMetadata.FromStringExpression(name, htmlHelper.ViewContext.ViewData);
if (value != null) {
metadata.Model = value;
}
return TextAreaHelper(htmlHelper, metadata, name, implicitRowsAndColumns, htmlAttributes);
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, int rows, int columns, object htmlAttributes) {
return TextArea(htmlHelper, name, value, rows, columns, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
public static MvcHtmlString TextArea(this HtmlHelper htmlHelper, string name, string value, int rows, int columns, IDictionary<string, object> htmlAttributes) {
ModelMetadata metadata = ModelMetadata.FromStringExpression(name, htmlHelper.ViewContext.ViewData);
if (value != null) {
metadata.Model = value;
}
return TextAreaHelper(htmlHelper, metadata, name, GetRowsAndColumnsDictionary(rows, columns), htmlAttributes);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) {
return TextAreaFor(htmlHelper, expression, (IDictionary<string, object>)null);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes) {
return TextAreaFor(htmlHelper, expression, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes) {
if (expression == null) {
throw new ArgumentNullException("expression");
}
return TextAreaHelper(htmlHelper,
ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
ExpressionHelper.GetExpressionText(expression),
implicitRowsAndColumns,
htmlAttributes);
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int columns, object htmlAttributes) {
return TextAreaFor(htmlHelper, expression, rows, columns, HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes));
}
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types")]
public static MvcHtmlString TextAreaFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, int rows, int columns, IDictionary<string, object> htmlAttributes) {
if (expression == null) {
throw new ArgumentNullException("expression");
}
return TextAreaHelper(htmlHelper,
ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData),
ExpressionHelper.GetExpressionText(expression),
GetRowsAndColumnsDictionary(rows, columns),
htmlAttributes);
}
[SuppressMessage("Microsoft.Usage", "CA2208:InstantiateArgumentExceptionsCorrectly", Justification = "If this fails, it is because the string-based version had an empty 'name' parameter")]
private static MvcHtmlString TextAreaHelper(HtmlHelper htmlHelper, ModelMetadata modelMetadata, string name, IDictionary<string, object> rowsAndColumns, IDictionary<string, object> htmlAttributes) {
string fullName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);
if (String.IsNullOrEmpty(fullName)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}
TagBuilder tagBuilder = new TagBuilder("textarea");
tagBuilder.GenerateId(fullName);
tagBuilder.MergeAttributes(htmlAttributes, true);
tagBuilder.MergeAttributes(rowsAndColumns, rowsAndColumns != implicitRowsAndColumns); // Only force explicit rows/cols
tagBuilder.MergeAttribute("name", fullName, true);
// If there are any errors for a named field, we add the CSS attribute.
ModelState modelState;
if (htmlHelper.ViewData.ModelState.TryGetValue(fullName, out modelState) && modelState.Errors.Count > 0) {
tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
}
tagBuilder.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));
string value;
if (modelState != null && modelState.Value != null) {
value = modelState.Value.AttemptedValue;
}
else if (modelMetadata.Model != null) {
value = modelMetadata.Model.ToString();
}
else {
value = String.Empty;
}
// The first newline is always trimmed when a TextArea is rendered, so we add an extra one
// in case the value being rendered is something like "\r\nHello".
tagBuilder.SetInnerText(Environment.NewLine + value);
return tagBuilder.ToMvcHtmlString(TagRenderMode.Normal);
}
}
}
|