How to create a readonly textbox in ASP.NET MVC3 Razor

C#asp.net Mvc-3RazorHtml HelperReadonly Attribute

C# Problem Overview


How do I create a readonly textbox in ASP.NET MVC3 with the Razor view engine?

Is there an HTMLHelper method available to do that?

Something like the following?

@Html.ReadOnlyTextBoxFor(m => m.userCode)

C# Solutions


Solution 1 - C#

@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })

You are welcome to make an HTML Helper for this, but this is simply just an HTML attribute like any other. Would you make an HTML Helper for a text box that has other attributes?

Solution 2 - C#

UPDATE: Now it's very simple to add HTML attributes to the default editor templates. It neans instead of doing this:

@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly" })

you simply can do this:

@Html.EditorFor(m => m.userCode, new { htmlAttributes = new { @readonly="readonly" } })

Benefits: You haven't to call .TextBoxFor, etc. for templates. Just call .EditorFor.


While @Shark's solution works correctly, and it is simple and useful, my solution (that I use always) is this one: Create an editor-template that can handles readonly attribute:

  1. Create a folder named EditorTemplates in ~/Views/Shared/

  2. Create a razor PartialView named String.cshtml

  3. Fill the String.cshtml with this code:

     @if(ViewData.ModelMetadata.IsReadOnly) {
         @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
             new { @class = "text-box single-line readonly", @readonly = "readonly", disabled = "disabled" })
     } else {
         @Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue,
             new { @class = "text-box single-line" })
     }
    
  4. In model class, put the [ReadOnly(true)] attribute on properties which you want to be readonly.

For example,

public class Model {
    // [your-annotations-here]
    public string EditablePropertyExample { get; set; }

    // [your-annotations-here]
    [ReadOnly(true)]
    public string ReadOnlyPropertyExample { get; set; }
}

Now you can use Razor's default syntax simply:

@Html.EditorFor(m => m.EditablePropertyExample)
@Html.EditorFor(m => m.ReadOnlyPropertyExample)

The first one renders a normal text-box like this:

<input class="text-box single-line" id="field-id" name="field-name" />

And the second will render to;

<input readonly="readonly" disabled="disabled" class="text-box single-line readonly" id="field-id" name="field-name" />

You can use this solution for any type of data (DateTime, DateTimeOffset, DataType.Text, DataType.MultilineText and so on). Just create an editor-template.

Solution 3 - C#

The solution with TextBoxFor is OK, but if you don't want to see the field like EditBox stylish (it might be a little confusing for the user) involve changes as follows:

  1. Razor code before changes

     <div class="editor-field">
          @Html.EditorFor(model => model.Text)
          @Html.ValidationMessageFor(model => model.Text)
     </div>
    
  2. After changes

     <!-- New div display-field (after div editor-label) -->
     <div class="display-field">
         @Html.DisplayFor(model => model.Text)
     </div>
    
     <div class="editor-field">
         <!-- change to HiddenFor in existing div editor-field -->
         @Html.HiddenFor(model => model.Text)
         @Html.ValidationMessageFor(model => model.Text)
     </div>
    

Generally, this solution prevents field from editing, but shows value of it. There is no need for code-behind modifications.

Solution 4 - C#

With credits to the previous answer by @Bronek and @Shimmy:

This is like I have done the same thing in ASP.NET Core:

<input asp-for="DisabledField" disabled="disabled" />
<input asp-for="DisabledField" class="hidden" />

The first input is readonly and the second one passes the value to the controller and is hidden. I hope it will be useful for someone working with ASP.NET Core.

Solution 5 - C#

 @Html.TextBox("Receivers", Model, new { @class = "form-control", style = "width: 300px", @readonly = "readonly" })

Solution 6 - C#

@Html.TextBoxFor(model => model.IsActive, new { readonly= "readonly" })

This is just fine for text box. However, if you try to do same for the checkbox then try using this if you are using it:

@Html.CheckBoxFor(model => model.IsActive, new { onclick = "return false" })

But don't use disable, because disable always sends the default value false to the server - either it was in the checked or unchecked state. And the readonly does not work for checkbox and radio button. readonly only works for text fields.

Solution 7 - C#

You can use the below code for creating a TextBox as read-only.

Method 1

 @Html.TextBoxFor(model => model.Fields[i].TheField, new { @readonly = true })

Method 2

@Html.TextBoxFor(model => model.Fields[i].TheField, new { htmlAttributes = new {disabled = "disabled"}})

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionShyjuView Question on Stackoverflow
Solution 1 - C#user596075View Answer on Stackoverflow
Solution 2 - C#amiry jdView Answer on Stackoverflow
Solution 3 - C#BronekView Answer on Stackoverflow
Solution 4 - C#Adithya BaddulaView Answer on Stackoverflow
Solution 5 - C#Hossein DahrView Answer on Stackoverflow
Solution 6 - C#gdmanandamohonView Answer on Stackoverflow
Solution 7 - C#Krishan Dutt SharmaView Answer on Stackoverflow