14

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));
    }

3 Answers 3

14

It's also valid to pass the name of the attribute as the value:

input.Attributes.Add("required", "required");
Sign up to request clarification or add additional context in comments.

Comments

5

I've tested on MVC 5, not sure about older versions but the following does what you want.

tagBuilder.MergeAttribute("required", string.Empty);

1 Comment

Might be a bit nit-picking but this results in <input required="" /> not <input required /> So yes, it works, but I'd still like to be able to add the plain attribute with no value.
0

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);
        }
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.