Cómo crear un cuadro de texto de solo lectura en ASP.NET MVC3 Razor

118

¿Cómo creo un cuadro de texto de solo lectura en ASP.NET MVC3 con el motor de vista Razor?

¿Hay un método HTMLHelper disponible para hacer eso?

¿Algo parecido a lo siguiente?

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

Respuestas:

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

Puede crear un HTML Helper para esto, pero esto es simplemente un atributo HTML como cualquier otro. ¿Haría un ayudante HTML para un cuadro de texto que tiene otros atributos?


fuente
1
@Shyju Lo siento, me faltaba el @prefijo de la readonlypropiedad. Ver mi edición.
7
En el futuro, si obtiene algún tipo de error al agregar propiedades al argumento del objeto dinámico, puede agregarles el prefijo @. Por lo general, solo lo verá con palabras clave que coincidan con atributos HTML (como solo lectura, clase, etc.)
Brad Christie
10
@BradChristie: No; solo necesita @usar atributos que coincidan con las palabras clave de C # .
SLaks
1
@BradChristie: Leí mal su comentario ("palabras clave" era ambiguo)
SLaks
1
Si tiene varios atributos html, puede hacer algo como:@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly", @class="form-control" })
benscabbia
32

ACTUALIZACIÓN: Ahora es muy sencillo agregar atributos HTML a las plantillas de editor predeterminadas. Neans en lugar de hacer esto:

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

simplemente puedes hacer esto:

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

Beneficios: no tienes que llamar .TextBoxFor , etc. para obtener plantillas. Solo llama .EditorFor.


Si bien la solución de @ Shark funciona correctamente, y es simple y útil, mi solución (que uso siempre) es esta: Crear un atributo editor-templateque pueda manejarreadonly :

  1. Crea una carpeta nombrada EditorTemplatesen~/Views/Shared/
  2. Crea una navaja PartialViewllamadaString.cshtml
  3. Complete el String.cshtmlcon este código:

    @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. En la clase de modelo, coloque el [ReadOnly(true)]atributo en las propiedades que desea ser readonly.

Por ejemplo,

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

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

Ahora puede usar la sintaxis predeterminada de Razor simplemente:

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

El primero hace un normal text-boxcomo este:

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

Y el segundo rendirá a;

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

Se puede utilizar esta solución para cualquier tipo de datos ( DateTime, DateTimeOffset, DataType.Text, DataType.MultilineTextetc.). Simplemente cree un editor-template.

ravy amiry
fuente
2
+1 porque usaste "ViewData.ModelMetadata.IsReadOnly". Esperaba que MVC tuviera en cuenta estas cosas en la versión 4.
cleftheris
@cleftheris así estamos en la versión 5 ahora, y MVC todavía no tomamos ellos;)
Amiry Ravy
2
@Javad_Amiry - gran respuesta - Lo he implementado y parecía funcionar muy bien hasta que hice clic en Guardar en una página de edición con Scaffolded. Entonces resulta que las propiedades con [ReadOnly (true)] darán como resultado que se envíe NULL a la base de datos en lugar del valor real de la propiedad. ¿Se ha encontrado con esto?
Percy
5

La solución con TextBoxFor está bien, pero si no desea ver el campo como EditBox con estilo (puede ser un poco confuso para el usuario), incluya los siguientes cambios:

  1. Código Razor antes de cambios

    <div class="editor-field">
         @Html.EditorFor(model => model.Text)
         @Html.ValidationMessageFor(model => model.Text)
    </div>
  2. Después de los cambios

    <!-- 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>

Generalmente, esta solución evita que el campo se edite, pero muestra su valor. No es necesario realizar modificaciones de código subyacente.

Bronek
fuente
1
Creo que tener el CSS para las clases editor-field y display-field aquí podría ser realmente útil.
DOK
¿Qué quiere decir con "esta solución deshabilita archivado contra edición" (parece incomprensible)? Responda editando su respuesta , no aquí en los comentarios (según corresponda).
Peter Mortensen
3

Con créditos a la respuesta anterior de @Bronek y @Shimmy:

Esto es como si hubiera hecho lo mismo en ASP.NET Core:

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

La primera entrada es de solo lectura y la segunda pasa el valor al controlador y está oculta. Espero que sea útil para alguien que trabaje con ASP.NET Core.

Adithya Baddula
fuente
0
 @Html.TextBox("Receivers", Model, new { @class = "form-control", style = "width: 300px", @readonly = "readonly" })
Hossein Dahr
fuente
1
Una explicación estaría en orden.
Peter Mortensen
0
@Html.TextBoxFor(model => model.IsActive, new { readonly= "readonly" })

Esto está bien para el cuadro de texto. Sin embargo, si intenta hacer lo mismo para el checkbox, intente usar esto si lo está usando:

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

Pero no lo use disable, porque deshabilitar siempre envía el valor predeterminado falseal servidor, ya sea en el estado marcado o no marcado. Y readonlyno funciona para la casilla de verificación y radio button. readonlysolo funciona para textcampos.

gdmanandamohon
fuente
¿Qué pasa con las listas desplegables?
user3020047
Espero que esto pueda ayudar a stackoverflow.com/questions/1636103/…
gdmanandamohon
0

Puede usar el siguiente código para crear un TextBox como de solo lectura.

Método 1

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

Método 2

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