Come creare una casella di testo di sola lettura in ASP.NET MVC3 Razor


118

Come si crea una casella di testo di sola lettura in ASP.NET MVC3 con il motore di visualizzazione Razor?

È disponibile un metodo HTMLHelper per farlo?

Qualcosa di simile al seguente?

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

Risposte:


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

Sei libero di creare un Helper HTML per questo, ma questo è semplicemente un attributo HTML come qualsiasi altro. Realizzereste un Helper HTML per una casella di testo che ha altri attributi?


1
@Shyju Scusa, mi mancava il @prefisso della readonlyproprietà. Vedi la mia modifica.

7
In futuro, se si verificano errori di qualsiasi tipo aggiungendo proprietà all'argomento dell'oggetto dinamico, è possibile anteporre loro il carattere @. Di solito lo vedrai solo con parole chiave che corrispondono agli attributi HTML (come readonly, class, ecc.)
Brad Christie

10
@BradChristie: No; hai solo bisogno di un @per utilizzare attributi che corrispondono alle parole chiave C # .
SLaks

1
@BradChristie: Ho letto male il tuo commento ("parole chiave" erano ambigue)
SLaks

1
Se hai più attributi html puoi fare qualcosa come:@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly", @class="form-control" })
benscabbia

32

AGGIORNAMENTO: ora è molto semplice aggiungere attributi HTML ai modelli di editor predefiniti. Neans invece di fare questo:

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

puoi semplicemente fare questo:

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

Vantaggi: non devi chiamare .TextBoxFor, ecc. Per i modelli. Chiama e basta .EditorFor.


Mentre la soluzione di @ Shark funziona correttamente, ed è semplice e utile, la mia soluzione (che uso sempre) è questa: Crea un attributo editor-templateche possa gestirereadonly :

  1. Crea una cartella denominata EditorTemplatesin~/Views/Shared/
  2. Crea un rasoio PartialViewdenominatoString.cshtml
  3. Compila String.cshtmlcon questo codice:

    @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. Nella classe del modello, metti l' [ReadOnly(true)]attributo sulle proprietà che vuoi essere readonly.

Per esempio,

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

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

Ora puoi usare semplicemente la sintassi predefinita di Razor:

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

Il primo rende una normale text-boxcome questa:

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

E il secondo renderà a;

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

È possibile utilizzare questa soluzione per qualsiasi tipo di dati ( DateTime, DateTimeOffset, DataType.Text, DataType.MultilineTexte così via). Basta creare un file editor-template.


2
+1 perché hai utilizzato "ViewData.ModelMetadata.IsReadOnly". Mi aspettavo che MVC tenesse conto di queste cose nella versione 4.
Cleftheris

@leftheris, beh, ora siamo nella versione 5 e MVC non li ha ancora presi;)
ravy amiry

2
@Javad_Amiry - ottima risposta - L'ho implementato e sembrava funzionare alla grande finché non ho fatto clic su Salva in una pagina di modifica con scaffolding. Quindi si scopre che Proprietà con [ReadOnly (true)] risulterà nell'invio di NULL al database invece del valore reale della proprietà - Hai trovato questo?
Percy

5

La soluzione con TextBoxFor è OK, ma se non vuoi vedere il campo come EditBox alla moda (potrebbe essere un po 'di confusione per l'utente) coinvolgi le modifiche come segue:

  1. Codice Razor prima delle modifiche

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

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

In genere, questa soluzione impedisce la modifica del campo, ma ne mostra il valore. Non sono necessarie modifiche code-behind.


1
Penso che avere il CSS per il campo dell'editor delle classi e del campo di visualizzazione qui potrebbe essere davvero utile.
DOK

Cosa intendi con "questa soluzione disattiva il deposito contro la modifica" (sembra incomprensibile)? Si prega di rispondere modificando la tua risposta , non qui nei commenti (a seconda dei casi).
Peter Mortensen

3

Con i crediti alla risposta precedente di @Bronek e @Shimmy:

È come se avessi fatto la stessa cosa in ASP.NET Core:

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

Il primo input è di sola lettura e il secondo passa il valore al controller e viene nascosto. Spero che sia utile per qualcuno che lavora con ASP.NET Core.


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

1
Sarebbe necessaria una spiegazione.
Peter Mortensen

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

Questo va bene per la casella di testo. Tuttavia, se provi a fare lo stesso per il, checkboxprova a usarlo se lo stai usando:

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

Ma non usare disable, perché disable invia sempre il valore predefinito falseal server - sia nello stato selezionato che non selezionato. E readonlynon funziona per la casella di controllo e radio button. readonlyfunziona solo per i textcampi.


E gli elenchi a discesa?
user3020047

Spero che questo potrebbe aiutare stackoverflow.com/questions/1636103/...
gdmanandamohon

0

È possibile utilizzare il codice seguente per creare una casella di testo in sola lettura.

Metodo 1

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

Metodo 2

@Html.TextBoxFor(model => model.Fields[i].TheField, new { htmlAttributes = new {disabled = "disabled"}})
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.