/// <inheritdoc /> public virtual TagBuilder GenerateSelect( ViewContext viewContext, string fullHtmlFieldName, Column column, string optionLabel, IEnumerable <SelectListItem> selectList, ICollection <string> currentValues, bool allowMultiple, object htmlAttributes) { if (viewContext == null) { throw new ArgumentNullException(nameof(viewContext)); } if (string.IsNullOrEmpty(fullHtmlFieldName)) { throw new ArgumentNullException(nameof(fullHtmlFieldName)); } if (selectList == null) { throw new ArgumentNullException(nameof(selectList)); } var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes); // Convert each ListItem to an <option> tag and wrap them with <optgroup> if requested. var listItemBuilder = GenerateGroupsAndOptions(optionLabel, selectList, currentValues); var tagBuilder = new TagBuilder("select"); tagBuilder.InnerHtml.SetHtmlContent(listItemBuilder); tagBuilder.MergeAttributes(htmlAttributeDictionary); NameAndIdProvider.GenerateId(viewContext, tagBuilder, fullHtmlFieldName, IdAttributeDotReplacement); tagBuilder.MergeAttribute("name", fullHtmlFieldName, replaceExisting: true); if (allowMultiple) { tagBuilder.MergeAttribute("multiple", "multiple"); } // If there are any errors for a named field, we add the css attribute. if (viewContext.ViewData.ModelState.TryGetValue(fullHtmlFieldName, out var entry)) { if (entry.Errors.Count > 0) { tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); } } AddValidationAttributes(viewContext, tagBuilder, fullHtmlFieldName, column); return(tagBuilder); }
/// <inheritdoc /> public virtual TagBuilder GenerateTextArea( ViewContext viewContext, string fullHtmlFieldName, Column column, object dataValue, int rows, int columns, object htmlAttributes) { if (viewContext == null) { throw new ArgumentNullException(nameof(viewContext)); } if (string.IsNullOrEmpty(fullHtmlFieldName)) { throw new ArgumentNullException(nameof(fullHtmlFieldName)); } if (column == null) { throw new ArgumentNullException(nameof(column)); } if (rows < 0) { throw new ArgumentOutOfRangeException(nameof(rows)); } if (columns < 0) { throw new ArgumentOutOfRangeException(nameof(columns)); } var value = string.Empty; if (dataValue != null) { value = dataValue.ToString(); } var tagBuilder = new TagBuilder("textarea"); NameAndIdProvider.GenerateId(viewContext, tagBuilder, fullHtmlFieldName, IdAttributeDotReplacement); var htmlAttributeDictionary = GetHtmlAttributeDictionaryOrNull(htmlAttributes); tagBuilder.MergeAttributes(htmlAttributeDictionary, replaceExisting: true); if (rows > 0) { tagBuilder.MergeAttribute("rows", rows.ToString(CultureInfo.InvariantCulture), replaceExisting: true); } if (columns > 0) { tagBuilder.MergeAttribute("cols", columns.ToString(CultureInfo.InvariantCulture), replaceExisting: true); } tagBuilder.MergeAttribute("name", fullHtmlFieldName, replaceExisting: true); AddPlaceholderAttribute(tagBuilder, column); if (AllowRenderingMaxLengthAttribute) { AddMaxLengthAttribute(tagBuilder, column); } AddValidationAttributes(viewContext, tagBuilder, fullHtmlFieldName, column); viewContext.ViewData.ModelState.TryGetValue(fullHtmlFieldName, out var entry); // If there are any errors for a named field, we add this CSS attribute. if (entry != null && entry.Errors.Count > 0) { tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); } // 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.InnerHtml.AppendLine(); tagBuilder.InnerHtml.Append(value); return(tagBuilder); }
/// <summary> /// Generates <input...> element. /// </summary> /// <param name="viewContext">The view context.</param> /// <param name="inputType">The input type.</param> /// <param name="fullHtmlFieldName">The full html field name.</param> /// <param name="column">The column.</param> /// <param name="value">The data value.</param> /// <param name="isChecked">Indicates whether this input is checked.</param> /// <param name="setId">Indicates whether id should be set.</param> /// <param name="isExplicitValue">Indicates whether this value is explicit.</param> /// <param name="format">The string format.</param> /// <param name="htmlAttributes">The HTML attributes dictionary.</param> /// <returns>The tag builder.</returns> protected virtual TagBuilder GenerateInput(ViewContext viewContext, InputType inputType, string fullHtmlFieldName, Column column, object value, bool isChecked, bool setId, bool isExplicitValue, string format, IDictionary <string, object> htmlAttributes) { if (viewContext == null) { throw new ArgumentNullException(nameof(viewContext)); } if (string.IsNullOrEmpty(fullHtmlFieldName)) { throw new ArgumentNullException(nameof(fullHtmlFieldName)); } var inputTypeString = GetInputTypeString(inputType); var tagBuilder = new TagBuilder("input") { TagRenderMode = TagRenderMode.SelfClosing, }; tagBuilder.MergeAttributes(htmlAttributes); tagBuilder.MergeAttribute("type", inputTypeString); tagBuilder.MergeAttribute("name", fullHtmlFieldName, replaceExisting: true); var suppliedTypeString = tagBuilder.Attributes["type"]; if (_placeholderInputTypes.Contains(suppliedTypeString)) { AddPlaceholderAttribute(tagBuilder, column); } if (AllowRenderingMaxLengthAttribute && _maxLengthInputTypes.Contains(suppliedTypeString)) { AddMaxLengthAttribute(tagBuilder, column); } var valueParameter = FormatValue(value, format ?? string.Empty); var usedModelState = false; switch (inputType) { case InputType.CheckBox: var modelStateWasChecked = GetModelStateValue(viewContext, fullHtmlFieldName, typeof(bool)) as bool?; if (modelStateWasChecked.HasValue) { isChecked = modelStateWasChecked.Value; usedModelState = true; } goto case InputType.Radio; case InputType.Radio: if (!usedModelState) { if (GetModelStateValue(viewContext, fullHtmlFieldName, typeof(string)) is string modelStateValue) { isChecked = string.Equals(modelStateValue, valueParameter, StringComparison.Ordinal); usedModelState = true; } } if (isChecked) { tagBuilder.MergeAttribute("checked", "checked"); } tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue); break; case InputType.Password: if (value != null) { tagBuilder.MergeAttribute("value", valueParameter, isExplicitValue); } break; case InputType.Text: default: // The following lines causes problem when valueParameter is a formatted datetime // It can be different from the value get from ModelState. To reproduce, remove // the [SqlDate] attribute of Movie.ReleaseDate property, then Movies/Edit page // will not display ReleaseDate correctly. // Not sure the side effect of bypassing GetModelStateValue though. /* * var attributeValue = (string)GetModelStateValue(viewContext, fullHtmlFieldName, typeof(string)); * if (attributeValue == null) * attributeValue = valueParameter; */ var attributeValue = valueParameter; var addValue = true; object typeAttributeValue; if (htmlAttributes != null && htmlAttributes.TryGetValue("type", out typeAttributeValue)) { var typeAttributeString = typeAttributeValue.ToString(); if (string.Equals(typeAttributeString, "file", StringComparison.OrdinalIgnoreCase) || string.Equals(typeAttributeString, "image", StringComparison.OrdinalIgnoreCase)) { addValue = false; // 'value' attribute is not needed for 'file' and 'image' input types. } } if (addValue) { tagBuilder.MergeAttribute("value", attributeValue, replaceExisting: isExplicitValue); } break; } if (setId) { NameAndIdProvider.GenerateId(viewContext, tagBuilder, fullHtmlFieldName, IdAttributeDotReplacement); } // If there are any errors for a named field, we add the CSS attribute. if (viewContext.ViewData.ModelState.TryGetValue(fullHtmlFieldName, out var entry) && entry.Errors.Count > 0) { tagBuilder.AddCssClass(HtmlHelper.ValidationInputCssClassName); } AddValidationAttributes(viewContext, tagBuilder, fullHtmlFieldName, column); return(tagBuilder); }