I am generating HTML textbox through the html helper and TagBuilder.
we have the method TagBuilder.Attributes.Add("key","value")
but for HTML5 required attribute does not need value to be passed, so if i pass empty string then the output with value of required = ""
So how do i add required attribute without passing the value?
public static IHtmlString AppTextBox(this HtmlHelper helper, string model)
{
var input = new TagBuilder("input");
input.Attributes.Add("class", "form-control");
input.Attributes.Add("ng-model", model);
input.Attributes.Add("required","");
return new MvcHtmlString(input.ToString(TagRenderMode.Normal));
}
It's also valid to pass the name of the attribute as the value:
input.Attributes.Add("required", "required");
I've tested on MVC 5, not sure about older versions but the following does what you want.
tagBuilder.MergeAttribute("required", string.Empty);
Not sure if you still need an answer to this, but in the end I ended up writing a new class that derives from the base MVC tag builder. It's nothing too complex and I suspect there may be a few edge cases that this doesn't handle too well, but from the unit tests I have so far, it's pretty solid.
internal class ValuelessAttributeTagBuilder : System.Web.Mvc.TagBuilder
{
public List<string> ValuelessAttributes { get; private set; }
public ValuelessAttributeTagBuilder(string tagName) : base(tagName)
{
ValuelessAttributes = new List<string>();
}
public void AddValuelessAttribute(string value)
{
if(ValuelessAttributes.Contains(value))
ValuelessAttributes.Add(value);
}
/// <summary>
/// Renders the HTML tag by using the specified render mode.
/// </summary>
///
/// <returns>
/// The rendered HTML tag.
/// </returns>
/// <param name="renderMode">The render mode.</param>
public string ToString(TagRenderMode renderMode)
{
var sb = new StringBuilder();
switch (renderMode)
{
case TagRenderMode.StartTag:
sb.Append('<').Append(this.TagName);
AppendAttributes(sb);
AppendValuelessAttributes(sb);
sb.Append('>');
break;
case TagRenderMode.EndTag:
sb.Append("</").Append(this.TagName).Append('>');
break;
case TagRenderMode.SelfClosing:
sb.Append('<').Append(this.TagName);
AppendAttributes(sb);
AppendValuelessAttributes(sb);
sb.Append(" />");
break;
default:
sb.Append('<').Append(this.TagName);
AppendAttributes(sb);
AppendValuelessAttributes(sb);
sb.Append('>').Append(this.InnerHtml).Append("</").Append(this.TagName).Append('>');
break;
}
return sb.ToString();
}
private void AppendAttributes(StringBuilder sb)
{
foreach (KeyValuePair<string, string> keyValuePair in (IEnumerable<KeyValuePair<string, string>>)this.Attributes)
{
string key = keyValuePair.Key;
if (!string.Equals(key, "id", StringComparison.Ordinal) || !string.IsNullOrEmpty(keyValuePair.Value))
{
string str = HttpUtility.HtmlAttributeEncode(keyValuePair.Value);
sb.Append(' ').Append(key).Append("=\"").Append(str).Append('"');
}
}
}
private void AppendValuelessAttributes(StringBuilder sb)
{
foreach (var v in ValuelessAttributes)
{
var str = HttpUtility.HtmlAttributeEncode(v);
sb.Append(' ').Append(str);
}
}
}