48

I have a textbox that I am defining as

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

The action is defined as

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

        ...

        return View(model);
    }

When I POST to this, 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 there 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.

user2246521
  • 83
  • 3
  • 12
modernzombie
  • 1,987
  • 7
  • 25
  • 44

7 Answers7

69

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
  • 85,422
  • 23
  • 131
  • 146
  • 3
    Wow, I can't believe I haven't run into this before, either that or completely forgot about it. Thanks. – modernzombie Apr 16 '10 at 14:30
  • 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 Apr 16 '10 at 14:51
  • 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 Apr 16 '10 at 14:55
  • 3
    <%= Html.Hidden("Username", Model.Form.Username)%> <%= Html.Label(Model.Form.Username)%> This would probably be a better usage – John Hartsock Apr 16 '10 at 18:19
  • See my answer. Disabled is sometimes the best case for the UI but it can still be passed if you change the property back on submit and this makes the idea of a hidden input unnecessary, which is better for reading and understanding the code. – tony.leo Jun 15 '17 at 15:19
62

use readonly - will disable input but you'll still have it in the binding. You could apply a style on the div to make it looked greyed out maybe?

<div class="editor-label">
  @Html.LabelFor(model => model.FileName)
</div>
<div class="editor-field-greyed-out">
  @Html.TextBoxFor(model => model.FileName, new { @readonly = true })
  @Html.ValidationMessageFor(model => model.FileName)
</div>
Peter Gluck
  • 8,168
  • 1
  • 38
  • 37
vincemcc79
  • 621
  • 5
  • 2
5

You can do a workaround by adding a hidden field with the same value ;)

<%= Html.Hidden("Username", Model.Form.Username)%>
Khaled Musaied
  • 2,513
  • 3
  • 25
  • 38
5

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
  • 25,076
  • 4
  • 67
  • 89
4

As suggested in the comments, readonly instead of disabled can be an option but it will not work for select boxes. Instead of creating a hidden input, you can keep the inputs or selects as disabled and still pass the data by changing the disabled property with JavaScript at the submit.

Using jQuery it'd look like this:

$('form').on('submit', function(){
    $('input, select').prop('disabled',false);
    return true;
});
tony.leo
  • 91
  • 1
1

Easiest way to submit disabled fields is to copy them over to an invisible, non disabled control before submit. Some people create those controls manually and hook up to the on change event in jQuery to copy them on demand, but this solution below is generic, easy and less chatty - although one rule: you must create (render) a clean page after postback (so

$('#submitBtn').closest('form').one('submit', function() {

    var $form = $(this);

    // input, textarea, select, option, ----- button, datalist, keygen, output, optgroup
    $form.find('input:disabled, textarea:disabled, select:disabled, option:disabled').each(function () {

        var $item = $(this);

        var hiddenItem = $item.clone();
        hiddenItem.removeAttr('id');
        hiddenItem.removeAttr('disabled');
        hiddenItem.attr('style', 'display: none');

        $item.after(hiddenItem);
    });

});
baHI
  • 1,510
  • 15
  • 20
  • ingenious dude! But you can also make some changes and put this methon on onload – clement Feb 07 '17 at 12:45
  • This works - but excessive. If you're using jQuery already, just change the disabled property to false at the submit. See my answer. – tony.leo Jun 15 '17 at 15:17
0

@readonly = true does not work on my page. I did additional research. Here is the article that explains it

ReadOnly attribute doesn't work in ASP.NET MVC Models

Community
  • 1
  • 1
user12345
  • 181
  • 1
  • 2
  • 18