internal static IHtmlString ObjectTemplate(HtmlHelper html, object formattedValue, string htmlFieldName, ModelMetadata modelMetadata, IDictionary<string, object> htmlAttributes) { var viewData = html.ViewContext.ViewData; var templateInfo = viewData.TemplateInfo; var containerData = html.ViewDataContainer.ViewData; var formContext = html.ViewContext.FormContext; var isHorisontalForm = (formContext is CarcassMvcFormContext) && ((formContext as CarcassMvcFormContext).FormClass ?? String.Empty).HasCssClass (CarcassMvcSettings.BootsrapFormClassHorisontal); var sb = new StringBuilder(); if (templateInfo.TemplateDepth > 1) { if (modelMetadata.Model != null) return MvcHtmlString.Create(modelMetadata.SimpleDisplayText); else return MvcHtmlString.Create(modelMetadata.NullDisplayText); } var inlineValidation = htmlAttributes.Get("InlineValidation", true); var validationClass = htmlAttributes.Get("ValidationClass", CarcassMvcSettings.ValidationMessageClass); var validationAttrs = new Dictionary<string, object>() { { "class", validationClass } }; var editorAttributes = new Dictionary<string, object>(); if (htmlAttributes.ContainsKey("EditorClass")) editorAttributes.Add("class", htmlAttributes["EditorClass"]); var content = new TagBuilder("div"); if (htmlAttributes.ContainsKey("CssClass")) content.AddCssClass(htmlAttributes["CssClass"] as string); sb.Append(content.ToString(TagRenderMode.StartTag)); // setup controls hierarchy var initHtmlFieldPrefix = templateInfo.HtmlFieldPrefix; if (!String.IsNullOrEmpty(htmlFieldName)) templateInfo.HtmlFieldPrefix = templateInfo.GetFullHtmlFieldName(htmlFieldName); try { foreach (var metadata in modelMetadata.Properties.Where(pm => EditorTemplates.ShouldShow(pm, templateInfo))) { var fieldType = metadata.TemplateHint ?? metadata.DataTypeName; var isHidden = fieldType == "HiddenInput"; var itemFieldName = metadata.PropertyName; if (!isHidden && !metadata.HideSurroundingHtml) { var labelAttributes = isHorisontalForm ? new Dictionary<string, object> { { "class", CarcassMvcSettings.BootsrapFormLabelClass } } : null; var label = LabelExtensions.FormatCarcassLabel(html, metadata, itemFieldName, null, labelAttributes); if (isHorisontalForm) sb.AppendFormat("<div class=\"{0}\">", CarcassMvcSettings.BootsrapFormFieldClass); sb.Append(label.ToHtmlString()); if (isHorisontalForm) sb.AppendFormat("<div class=\"{0}\">", CarcassMvcSettings.BootsrapFormFieldControlsClass); } // Reset ViewBag values if (containerData.ContainsKey(itemFieldName)) containerData.Remove(itemFieldName); var controlAttributes = editorAttributes.Clone(); var fullHtmlFieldName = templateInfo.GetFullHtmlFieldName(itemFieldName); var validationAttributes = html.GetUnobtrusiveValidationAttributes(itemFieldName, metadata); formContext.RenderedField(fullHtmlFieldName, false); foreach (var attr in validationAttributes) { if(!controlAttributes.ContainsKey(attr.Key)) controlAttributes.Add(attr); } sb.Append("\r\n"); sb.Append(html.RenderCarcassEditor(metadata, null, itemFieldName, controlAttributes).ToHtmlString()); sb.Append("\r\n"); if (!isHidden && !metadata.HideSurroundingHtml) { if (inlineValidation) { var typeName = metadata.ModelType.Name; if (metadata.IsNullableValueType && metadata.ModelType.GenericTypeArguments.Length > 0) typeName = metadata.ModelType.GenericTypeArguments[0].Name; sb.Append(" "); if (typeName == "DateTime") { sb.Append( ValidationExtensions.FieldValidationMessage(html, metadata, itemFieldName + DateControlPostfix, null, validationAttrs.Clone()) .ToHtmlString()).Append(" "); sb.Append( ValidationExtensions.FieldValidationMessage(html, metadata, itemFieldName + TimeControlPostfix, null, validationAttrs.Clone()) .ToHtmlString()).Append(" "); sb.Append( ValidationExtensions.FieldValidationMessage(html, metadata, itemFieldName, null, validationAttrs.Clone()) .ToHtmlString()); } else { sb.Append( ValidationExtensions.FieldValidationMessage(html, metadata, itemFieldName, null, validationAttrs.Clone()) .ToHtmlString()); } } if (isHorisontalForm) sb.Append("</div></div>\r\n"); } } } finally { templateInfo.HtmlFieldPrefix = initHtmlFieldPrefix; } sb.Append(content.ToString(TagRenderMode.EndTag)); return MvcHtmlString.Create(sb.ToString()); }
internal static IHtmlString CollectionTemplate(HtmlHelper html, object formattedValue, string htmlFieldName, ModelMetadata modelMetadata, IDictionary<string, object> htmlAttributes) { var viewData = html.ViewContext.ViewData; var templateInfo = viewData.TemplateInfo; object model = modelMetadata.Model; if (model == null) { return MvcHtmlString.Empty; } IEnumerable enumerable = model as IEnumerable; if (enumerable == null) { throw new InvalidOperationException( String.Format("Type {0} must implement System.Collections.IEnumerable", model.GetType().FullName)); } var itemType = typeof(string); var genericInterface = TypeHelper.ExtractGenericInterface(enumerable.GetType(), typeof(IEnumerable<>)); if (genericInterface != null) itemType = genericInterface.GetGenericArguments()[0]; bool isItemTypeNullable = TypeHelper.IsNullableValueType(itemType); var stringBuilder = new StringBuilder(); int num = 0; var htmlFieldNamePrefix = templateInfo.GetFullHtmlFieldName(htmlFieldName); if (!String.IsNullOrEmpty(htmlFieldNamePrefix)) htmlFieldNamePrefix += "."; IEnumerator enumerator = enumerable.GetEnumerator(); try { while (enumerator.MoveNext()) { if (num > 0) stringBuilder.Append("<hr />"); object item = enumerator.Current; var modelType = itemType; if (item != null && !isItemTypeNullable) modelType = item.GetType(); var metadataForType = ModelMetadataProviders.Current.GetMetadataForType(() => item, modelType); var itemFieldName = String.Format( (IFormatProvider) CultureInfo.InvariantCulture, "{0}[{1}]", htmlFieldNamePrefix, num++ ); var editor = html.RenderCarcassEditor(metadataForType, null, itemFieldName); stringBuilder.Append(editor.ToHtmlString()); } } finally { var disposable = enumerator as IDisposable; if (disposable != null) disposable.Dispose(); } return MvcHtmlString.Create(stringBuilder.ToString()); }