views:

438

answers:

3

I have a textbox that I am defining as

<%= Html.TextBox("Username", Model.Form.Username, 
        new { @class = "textbox", @disabled = "disabled" })%>

In my action

    [AcceptVerbs(HttpVerbs.Post)]
    [ValidateAntiForgeryToken]
    public ActionResult EditLogin(LoginForm post) {

        ...

        return View(model);
    }

post.Username will be blank, all other properties bind correctly, but if I change @disabled="disabled to @readonly="readonly" the username binds properly and everything works.

It looks like model binding ignores values in disabled fields. Is their a way around this? I still need the field's value to bind to the model. I can use readonly but would prefer to use disabled so it is visually apparent to the user that they cannot edit the value of the field.

+4  A: 

I believe a form field that is disabled does not submit anything. if you have a form and disable the foo field in that form, when you post the post will not have the value for the foo field. This is simply the nature of disabling a field in HTML and is not a MVC issue.

John Hartsock
Wow, I can't believe I haven't run into this before, either that or completely forgot about it. Thanks.
modernzombie
Its an easy thing to overlook but Dan Diplo is right, in many cases a hidden field is a good way to go. Out of curiousity why are you disabling a username field?
John Hartsock
I am creating a form where an administrator can create new logins for the system. I was disabling the username when the administrator was editing the login (first and last name and emails are editable) because the username cannot be changed. I have decided to use readonly and can use some CSS to color the field differently.
modernzombie
<%= Html.Hidden("Username", Model.Form.Username)%> <%= Html.Label(Model.Form.Username)%> This would probably be a better usage
John Hartsock
+2  A: 

If you want the value to be sent back, but not be editable, consider placing it in a hidden field. Obviously, don't do this for anything that requires a degree of security, since a user can tamper with it.

Dan Diplo
A: 

I think that extention methods would be the way to go, here is my implementation:

Usage:

var disabled = true;
Html.TextBox("Name", "Value", disabled.DAttrib( new { @class="text" } ));

Definition:

public static object DAttrib( this bool disabled )
{
    return (disabled ? (object)new { disabled = true} : null);
}

public static object DAttrib(this bool disabled, string cssClass)
{
    return (disabled? (object) new { disabled = true, @class = cssClass } : 
                      (object) new { @class = cssClass } );
}

public static IDictionary<string, Object> DAttrib( this bool disabled, object attribs )
{
    var attribList = new RouteValueDictionary( attribs );
    if (disabled) {
        attribList.Add( "disabled", "true" );
    }
    return attribList;
}

Something like that..

Lavinski