9

I am trying to dynamically set the disabled attribute on the html textbox and having issues

I tried this in my view:

 string disabledString = "";
 if (SomeLogic)
 {
      disabledString = "disabled";
 }

 Html.Textbox()...new Dictionary<string, object> { { "maxlength", 50 }, { "disabled", readOnlyState } })%>

As you can see I am setting the disabled attribute to "" or disabled but when I test, it seems to be disabled in either case. Am I missing something?

THelper
  • 15,333
  • 6
  • 64
  • 104
leora
  • 188,729
  • 360
  • 878
  • 1,366
  • the HTML spec says to disable if it sees an attribute of "disabled" (with any value) in the element. See my workaround below. – Robaticus Aug 09 '10 at 19:49
  • I hope you aren't depending on only the disabled attribute to prevent data from being changed? A little bit of form tampering would allow them to change a "readonly" value if your bindings allow it. – Nathan Taylor Aug 09 '10 at 19:55
  • @Nathan Taylor - can you clarify what you mean here? – leora Aug 09 '10 at 19:58
  • Well, if you tell MVC to bind a property like "Title" at a code level but "disable" the property using the disabled attribute, the user could still make a form request with a value assigned to Title by circumventing the disabled attribute. – Nathan Taylor Aug 09 '10 at 22:01
  • Agree with @Nathan, but it depends on the type of app you're creating. For an intranet app, it's probably ok. To make a bulletproof Internet app, I would only count on the disabled attribute to discourage entry from the front-end, but still check the field on the back end to make sure it didn't change. – Robaticus Aug 10 '10 at 22:57

3 Answers3

17

This was ugly for us, due to the fact that the HTML spec is lousy here.

Basically in our view code we had some logic like this:

bool isPlatformOwner = false;

object disabledAttributes = new { @disabled="disabled", @readonly="readonly" };

//omitted code setting isPlatformOwner    

    if (isPlatformOwner)
    {
        disabledAttributes = new { };
    }

Then, for our controls, we had this:

<%=Html.CheckBoxFor(f => f.AddToReleaseIndicator, disabledAttributes)%>

Anonymous types saved us here, but, like I said, it got a little ugly.

Robaticus
  • 22,857
  • 5
  • 54
  • 63
3

Actually it is possible to write an Extension class to the HtmlHelper to do this but you have to implement many overrides so the quickest solution I found was to write a dictionary extension.

You can use below class for this:

public static class DictionaryExtensions
{
    public static Dictionary<string, object> WithAttrIf(this Dictionary<string,object> dictionary,bool condition, string attrname, object value)
    {
        if (condition)
            dictionary[attrname] = value;

        return dictionary;
    }

    public static Dictionary<string, object> WithAttr(this Dictionary<string, object> dictionary, string attrname, object value)
    {

        dictionary[attrname] = value;

        return dictionary;
    }
}

To use it, import the class in your view and your view code looks like this:

@Html.TextBoxFor(m => m.FirstName,  new Dictionary<string, object>().WithAttr("class","input-large").WithAttrIf(!string.IsNullOrWhiteSpace(Model.FirstName),"readonly","yes"))

You can add as many attributes as you wish since the extension method adds the value to the dictionary and returns the dictionary itself

Cagatay Kalan
  • 4,066
  • 1
  • 30
  • 23
1

I think you want to omit the disabled attribute altogether when you want it to be enabled. Older browsers would look at the following and disable the text boxes:

<input type="text" disabled></input>

In other words in older HTML the ="disabled" was not necessary so for compatibility reasons you should just omit the attribute if you want it to render right. I'm not sure what happens if you try a strict DOCTYPE, though.

Dismissile
  • 32,564
  • 38
  • 174
  • 263
  • i need to use the above format. that is where i am getting stuck on how to add conditional attribute using this html.textbox format ? – leora Aug 09 '10 at 19:43