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 162 163 164 165 166 167 168 169 170 171 172
|
/* ****************************************************************************
*
* Copyright (c) Microsoft Corporation. All rights reserved.
*
* This software is subject to the Microsoft Public License (Ms-PL).
* A copy of the license can be found in the license.htm file included
* in this distribution.
*
* You must not remove this notice, or any other, from this software.
*
* ***************************************************************************/
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;
using System.Web.Routing;
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 */, new RouteValueDictionary(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, new RouteValueDictionary(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, new RouteValueDictionary(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, new RouteValueDictionary(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, new RouteValueDictionary(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 expression, IDictionary<string, object> rowsAndColumns, IDictionary<string, object> htmlAttributes) {
string name = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(expression);
if (String.IsNullOrEmpty(name)) {
throw new ArgumentException(MvcResources.Common_NullOrEmpty, "name");
}
TagBuilder tagBuilder = new TagBuilder("textarea");
tagBuilder.GenerateId(name);
tagBuilder.MergeAttributes(htmlAttributes, true);
tagBuilder.MergeAttributes(rowsAndColumns, rowsAndColumns != implicitRowsAndColumns); // Only force explicit rows/cols
tagBuilder.MergeAttribute("name", name, true);
// If there are any errors for a named field, we add the CSS attribute.
ModelState modelState;
if (htmlHelper.ViewData.ModelState.TryGetValue(name, out modelState) && modelState.Errors.Count > 0) {
tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName);
}
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);
}
}
}
|