New test.
[mono.git] / mcs / class / System.Web.Mvc2 / System.Web.Mvc / Html / DefaultEditorTemplates.cs
1 /* ****************************************************************************\r
2  *\r
3  * Copyright (c) Microsoft Corporation. All rights reserved.\r
4  *\r
5  * This software is subject to the Microsoft Public License (Ms-PL). \r
6  * A copy of the license can be found in the license.htm file included \r
7  * in this distribution.\r
8  *\r
9  * You must not remove this notice, or any other, from this software.\r
10  *\r
11  * ***************************************************************************/\r
12 \r
13 namespace System.Web.Mvc.Html {\r
14     using System;\r
15     using System.Collections;\r
16     using System.Collections.Generic;\r
17     using System.Data;\r
18     using System.Data.Linq;\r
19     using System.Globalization;\r
20     using System.Linq;\r
21     using System.Text;\r
22     using System.Web.Mvc.Resources;\r
23     using System.Web.UI.WebControls;\r
24 \r
25     internal static class DefaultEditorTemplates {\r
26         internal static string BooleanTemplate(HtmlHelper html) {\r
27             bool? value = null;\r
28             if (html.ViewContext.ViewData.Model != null) {\r
29                 value = Convert.ToBoolean(html.ViewContext.ViewData.Model, CultureInfo.InvariantCulture);\r
30             }\r
31 \r
32             return html.ViewContext.ViewData.ModelMetadata.IsNullableValueType\r
33                         ? BooleanTemplateDropDownList(html, value)\r
34                         : BooleanTemplateCheckbox(html, value ?? false);\r
35         }\r
36 \r
37         private static string BooleanTemplateCheckbox(HtmlHelper html, bool value) {\r
38             return html.CheckBox(String.Empty, value, CreateHtmlAttributes("check-box")).ToHtmlString();\r
39         }\r
40 \r
41         private static string BooleanTemplateDropDownList(HtmlHelper html, bool? value) {\r
42             return html.DropDownList(String.Empty, TriStateValues(value), CreateHtmlAttributes("list-box tri-state")).ToHtmlString();\r
43 \r
44         }\r
45 \r
46         internal static string CollectionTemplate(HtmlHelper html) {\r
47             return CollectionTemplate(html, TemplateHelpers.TemplateHelper);\r
48         }\r
49 \r
50         internal static string CollectionTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {\r
51             object model = html.ViewContext.ViewData.ModelMetadata.Model;\r
52             if (model == null) {\r
53                 return String.Empty;\r
54             }\r
55 \r
56             IEnumerable collection = model as IEnumerable;\r
57             if (collection == null) {\r
58                 throw new InvalidOperationException(\r
59                     String.Format(\r
60                         CultureInfo.CurrentCulture,\r
61                         MvcResources.Templates_TypeMustImplementIEnumerable,\r
62                         model.GetType().FullName\r
63                     )\r
64                 );\r
65             }\r
66 \r
67             Type typeInCollection = typeof(string);\r
68             Type genericEnumerableType = TypeHelpers.ExtractGenericInterface(collection.GetType(), typeof(IEnumerable<>));\r
69             if (genericEnumerableType != null) {\r
70                 typeInCollection = genericEnumerableType.GetGenericArguments()[0];\r
71             }\r
72             bool typeInCollectionIsNullableValueType = TypeHelpers.IsNullableValueType(typeInCollection);\r
73 \r
74             string oldPrefix = html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix;\r
75 \r
76             try {\r
77                 html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = String.Empty;\r
78 \r
79                 string fieldNameBase = oldPrefix;\r
80                 StringBuilder result = new StringBuilder();\r
81                 int index = 0;\r
82 \r
83                 foreach (object item in collection) {\r
84                     Type itemType = typeInCollection;\r
85                     if (item != null && !typeInCollectionIsNullableValueType) {\r
86                         itemType = item.GetType();\r
87                     }\r
88                     ModelMetadata metadata = ModelMetadataProviders.Current.GetMetadataForType(() => item, itemType);\r
89                     string fieldName = String.Format(CultureInfo.InvariantCulture, "{0}[{1}]", fieldNameBase, index++);\r
90                     string output = templateHelper(html, metadata, fieldName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */);\r
91                     result.Append(output);\r
92                 }\r
93 \r
94                 return result.ToString();\r
95             }\r
96             finally {\r
97                 html.ViewContext.ViewData.TemplateInfo.HtmlFieldPrefix = oldPrefix;\r
98             }\r
99         }\r
100 \r
101         internal static string DecimalTemplate(HtmlHelper html) {\r
102             if (html.ViewContext.ViewData.TemplateInfo.FormattedModelValue == html.ViewContext.ViewData.ModelMetadata.Model) {\r
103                 html.ViewContext.ViewData.TemplateInfo.FormattedModelValue = String.Format(CultureInfo.CurrentCulture, "{0:0.00}", html.ViewContext.ViewData.ModelMetadata.Model);\r
104             }\r
105 \r
106             return StringTemplate(html);\r
107         }\r
108 \r
109         internal static string HiddenInputTemplate(HtmlHelper html) {\r
110             string result;\r
111 \r
112             if (html.ViewContext.ViewData.ModelMetadata.HideSurroundingHtml) {\r
113                 result = String.Empty;\r
114             }\r
115             else {\r
116                 result = DefaultDisplayTemplates.StringTemplate(html);\r
117             }\r
118 \r
119             object model = html.ViewContext.ViewData.Model;\r
120 \r
121             Binary modelAsBinary = model as Binary;\r
122             if (modelAsBinary != null) {\r
123                 model = Convert.ToBase64String(modelAsBinary.ToArray());\r
124             }\r
125             else {\r
126                 byte[] modelAsByteArray = model as byte[];\r
127                 if (modelAsByteArray != null) {\r
128                     model = Convert.ToBase64String(modelAsByteArray);\r
129                 }\r
130             }\r
131 \r
132             result += html.Hidden(String.Empty, model).ToHtmlString();\r
133             return result;\r
134         }\r
135 \r
136         internal static string MultilineTextTemplate(HtmlHelper html) {\r
137             return html.TextArea(String.Empty,\r
138                                  html.ViewContext.ViewData.TemplateInfo.FormattedModelValue.ToString(),\r
139                                  0 /* rows */, 0 /* columns */,\r
140                                  CreateHtmlAttributes("text-box multi-line")).ToHtmlString();\r
141         }\r
142 \r
143         private static IDictionary<string, object> CreateHtmlAttributes(string className) {\r
144             return new Dictionary<string, object>() {\r
145                 { "class", className }\r
146             };\r
147         }\r
148 \r
149         internal static string ObjectTemplate(HtmlHelper html) {\r
150             return ObjectTemplate(html, TemplateHelpers.TemplateHelper);\r
151         }\r
152 \r
153         internal static string ObjectTemplate(HtmlHelper html, TemplateHelpers.TemplateHelperDelegate templateHelper) {\r
154             ViewDataDictionary viewData = html.ViewContext.ViewData;\r
155             TemplateInfo templateInfo = viewData.TemplateInfo;\r
156             ModelMetadata modelMetadata = viewData.ModelMetadata;\r
157             StringBuilder builder = new StringBuilder();\r
158 \r
159             if (templateInfo.TemplateDepth > 1) {    // DDB #224751\r
160                 return modelMetadata.Model == null ? modelMetadata.NullDisplayText : modelMetadata.SimpleDisplayText;\r
161             }\r
162 \r
163             foreach (ModelMetadata propertyMetadata in modelMetadata.Properties.Where(pm => ShouldShow(pm, templateInfo))) {\r
164                 if (!propertyMetadata.HideSurroundingHtml) {\r
165                     string label = LabelExtensions.LabelHelper(html, propertyMetadata, propertyMetadata.PropertyName).ToHtmlString();\r
166                     if (!String.IsNullOrEmpty(label)) {\r
167                         builder.AppendFormat(CultureInfo.InvariantCulture, "<div class=\"editor-label\">{0}</div>\r\n", label);\r
168                     }\r
169 \r
170                     builder.Append("<div class=\"editor-field\">");\r
171                 }\r
172 \r
173                 builder.Append(templateHelper(html, propertyMetadata, propertyMetadata.PropertyName, null /* templateName */, DataBoundControlMode.Edit, null /* additionalViewData */));\r
174 \r
175                 if (!propertyMetadata.HideSurroundingHtml) {\r
176                     builder.Append(" ");\r
177                     builder.Append(html.ValidationMessage(propertyMetadata.PropertyName));\r
178                     builder.Append("</div>\r\n");\r
179                 }\r
180             }\r
181 \r
182             return builder.ToString();\r
183         }\r
184 \r
185         internal static string PasswordTemplate(HtmlHelper html) {\r
186             return html.Password(String.Empty,\r
187                                  html.ViewContext.ViewData.TemplateInfo.FormattedModelValue,\r
188                                  CreateHtmlAttributes("text-box single-line password")).ToHtmlString();\r
189         }\r
190 \r
191         private static bool ShouldShow(ModelMetadata metadata, TemplateInfo templateInfo) {\r
192             return\r
193                 metadata.ShowForEdit\r
194 #if false
195                 && metadata.ModelType != typeof(EntityState)\r
196 #endif
197                 && !metadata.IsComplexType\r
198                 && !templateInfo.Visited(metadata);\r
199         }\r
200 \r
201         internal static string StringTemplate(HtmlHelper html) {\r
202             return html.TextBox(String.Empty,\r
203                                 html.ViewContext.ViewData.TemplateInfo.FormattedModelValue,\r
204                                 CreateHtmlAttributes("text-box single-line")).ToHtmlString();\r
205         }\r
206 \r
207         internal static List<SelectListItem> TriStateValues(bool? value) {\r
208             return new List<SelectListItem> {\r
209                 new SelectListItem { Text = MvcResources.Common_TriState_NotSet, Value = String.Empty, Selected = !value.HasValue },\r
210                 new SelectListItem { Text = MvcResources.Common_TriState_True, Value = "true", Selected = value.HasValue && value.Value },\r
211                 new SelectListItem { Text = MvcResources.Common_TriState_False, Value = "false", Selected = value.HasValue && !value.Value },\r
212             };\r
213         }\r
214     }\r
215 }\r