// Returns the html for all hidden inputs associated with the model private static string HiddenInput(ModelMetadata metadata, string propertyName, bool includeDefault) { StringBuilder html = new StringBuilder(); if (metadata.ModelType.IsArray && metadata.Model != null) { // Primarily for database time stamps, this need to called before checking IsComplexType // otherwise an endless loop is created html.Append(HiddenInput(propertyName, Convert.ToBase64String(metadata.Model as byte[]))); } else if (metadata.IsComplexType) { foreach (ModelMetadata propertyMetadata in metadata.Properties) { if (propertyMetadata.IsCollection() && !propertyMetadata.ModelType.IsArray) { // This would just render the Count and Capacity property of List<T> continue; } if (propertyMetadata.Model == null && propertyMetadata.ModelType != typeof(string) && !propertyMetadata.IsRequired) { // Ignore complex types that are null and do not have the RequiredAttribute continue; } // Recursive call to render a hidden input for the property string prefix = null; if (String.IsNullOrEmpty(propertyName)) { prefix = propertyMetadata.PropertyName; } else { prefix = string.Format("{0}.{1}", propertyName, propertyMetadata.PropertyName); } html.Append(HiddenInput(propertyMetadata, prefix, true)); } } else { object value = metadata.Model; if (value == null && includeDefault) { value = metadata.DefaultValue(); } html.Append(HiddenInput(propertyName, value)); } return(html.ToString()); }
/// <summary> /// Returns the html for a numeric input that formats the display of values. /// </summary> /// <param name="metaData"> /// The metadata of the property. /// </param> /// <param name="fieldName"> /// The fully qualified name of the property. /// </param> /// <param name="attributes"> /// The validation attributes to rendered in the input. /// </param> /// <param name="includeID"> /// A value indicating the the 'id' attribute should be rendered for the input. /// </param> private static string NumericInput(ModelMetadata metaData, string fieldName, IDictionary <string, object> attributes, bool includeID) { string defaultFormat = "{0:N}"; StringBuilder html = new StringBuilder(); // Build formatted display text TagBuilder display = new TagBuilder("div"); // Add essential styles display.MergeAttribute("style", "position:absolute;"); // Add class names display.AddCssClass("numeric-text"); if (Convert.ToDouble(metaData.Model) < 0) { display.AddCssClass("negative"); } if (metaData.IsCurrency()) { defaultFormat = "{0:C}"; display.AddCssClass("currency"); } else if (metaData.IsPercent()) { defaultFormat = "{0:P}"; display.AddCssClass("percent"); } else { display.AddCssClass("number"); } if (Type.GetTypeCode(metaData.ModelType) == TypeCode.Int32) { defaultFormat = "{0:N0}"; } // Format text defaultFormat = metaData.DisplayFormatString ?? defaultFormat; display.InnerHtml = string.Format(defaultFormat, metaData.Model ?? metaData.DefaultValue()); // TODO: What about nullable types //metaData.NullDisplayText; html.Append(display.ToString()); // Build input TagBuilder input = new TagBuilder("input"); input.AddCssClass("numeric-input"); input.MergeAttribute("autocomplete", "off"); input.MergeAttribute("type", "text"); if (includeID) { input.MergeAttribute("id", HtmlHelper.GenerateIdFromName(fieldName)); } input.MergeAttribute("name", fieldName); input.MergeAttribute("value", string.Format("{0}", metaData.Model ?? metaData.DefaultValue())); // Remove the data-val-number attribute (the client script ensures its a number and jquery // validation generates an error message if the first character is a decimal point which // disappears as soon as the next digit is entered - PITA when entering percentage values) // TODO: Still happens if a Range attribute is added! if (attributes != null && attributes.ContainsKey("data-val-number")) { attributes.Remove("data-val-number"); } input.MergeAttributes(attributes); html.Append(input.ToString()); // Build container TagBuilder container = new TagBuilder("div"); container.AddCssClass("numeric-container"); // Add data attributes for use by client script if (metaData.IsCurrency()) { //container.MergeAttributes(GetCurrencyDataAttributes(metaData.DisplayFormatString)); container.MergeAttributes(GetCurrencyDataAttributes(defaultFormat)); } else if (metaData.IsPercent()) { //container.MergeAttributes(GetPercentDataAttributes(metaData.DisplayFormatString)); container.MergeAttributes(GetPercentDataAttributes(defaultFormat)); } else { //container.MergeAttributes(GetNumberDataAttributes(metaData.DisplayFormatString)); container.MergeAttributes(GetNumberDataAttributes(defaultFormat)); } // Add essential styles container.MergeAttribute("style", "position:relative;margin:0;padding:0;"); container.InnerHtml = html.ToString(); // Return the html return(container.ToString()); }