Comment créer une zone de texte en lecture seule dans ASP.NET MVC3 Razor


118

Comment créer une zone de texte en lecture seule dans ASP.NET MVC3 avec le moteur de vue Razor?

Existe-t-il une méthode HTMLHelper disponible pour cela?

Quelque chose comme ce qui suit?

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

Réponses:


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

Vous êtes invités à créer un HTML Helper pour cela, mais il ne s'agit que d'un attribut HTML comme les autres. Feriez-vous un HTML Helper pour une zone de texte qui a d'autres attributs?


1
@Shyju Désolé, il me manquait le @préfixe de la readonlypropriété. Voir ma modification.

7
À l'avenir, si vous rencontrez des erreurs lors de l'ajout de propriétés à l'argument d'objet dynamique, vous pouvez les préfixer avec l'extension @. Vous ne le verrez généralement qu'avec des mots clés qui correspondent aux attributs HTML (comme lecture seule, classe, etc.)
Brad Christie

10
@BradChristie: Non; vous n'avez besoin que d'un @pour utiliser les attributs qui correspondent aux mots clés C # .
SLaks

1
@BradChristie: J'ai mal lu votre commentaire ("mots clés" était ambigu)
SLaks

1
Si vous avez plusieurs attributs html, vous pouvez faire quelque chose comme:@Html.TextBoxFor(m => m.userCode, new { @readonly="readonly", @class="form-control" })
benscabbia

32

MISE À JOUR: Il est maintenant très simple d'ajouter des attributs HTML aux modèles d'éditeur par défaut. Cela signifie au lieu de faire ceci:

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

vous pouvez simplement faire ceci:

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

Avantages: vous n'avez pas besoin d'appeler .TextBoxFor, etc. pour les modèles. Appelez .EditorFor.


Bien que la solution de @ Shark fonctionne correctement, et qu'elle soit simple et utile, ma solution (que j'utilise toujours) est celle-ci: créer un attribut editor-templatequi peut gérerreadonly :

  1. Créez un dossier nommé EditorTemplatesdans~/Views/Shared/
  2. Créez un rasoir PartialViewnomméString.cshtml
  3. Remplissez le String.cshtmlavec ce 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. Dans la classe de modèle, placez l' [ReadOnly(true)]attribut sur les propriétés que vous souhaitez être readonly.

Par exemple,

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

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

Vous pouvez maintenant utiliser la syntaxe par défaut de Razor simplement:

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

Le premier rend un normal text-boxcomme ceci:

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

Et le second rendra à;

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

Vous pouvez utiliser cette solution pour tout type de données ( DateTime, DateTimeOffset, DataType.Text, DataType.MultilineTextetc.). Créez simplement un fichier editor-template.


2
+1 car vous avez utilisé "ViewData.ModelMetadata.IsReadOnly". Je m'attendais à ce que MVC tienne compte de ces éléments dans la version 4.
cleftheris

@cleftheris et bien nous sommes en version 5 maintenant, et MVC ne les a toujours pas pris;)
ravy amiry

2
@Javad_Amiry - excellente réponse - Je l'ai implémenté et cela a semblé très bien fonctionner jusqu'à ce que je clique sur Enregistrer sur une page d'édition échafaudée. Ensuite, il s'avère que Propriétés avec [ReadOnly (true)] entraînera l'envoi de NULL à la base de données au lieu de la valeur de la propriété réelle - Avez-vous rencontré cela?
Percy

5

La solution avec TextBoxFor est OK, mais si vous ne voulez pas voir le champ comme EditBox élégant (cela peut être un peu déroutant pour l'utilisateur), impliquez les modifications suivantes:

  1. Code Razor avant les modifications

    <div class="editor-field">
         @Html.EditorFor(model => model.Text)
         @Html.ValidationMessageFor(model => model.Text)
    </div>
  2. Après les changements

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

En général, cette solution empêche la modification du champ, mais en montre la valeur. Il n'est pas nécessaire de modifier le code-behind.


1
Je pense qu'avoir le CSS pour le champ d'éditeur de classes et le champ d'affichage ici pourrait être vraiment utile.
DOK

Qu'entendez-vous par «cette solution désactive les fichiers contre l'édition» (cela semble incompréhensible)? Veuillez répondre en modifiant votre réponse , pas ici dans les commentaires (le cas échéant).
Peter Mortensen

3

Avec les crédits à la réponse précédente de @Bronek et @Shimmy:

C'est comme si j'avais fait la même chose dans ASP.NET Core:

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

La première entrée est en lecture seule et la seconde transmet la valeur au contrôleur et est masquée. J'espère que cela sera utile pour quelqu'un qui travaille avec ASP.NET Core.


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

1
Une explication s'impose.
Peter Mortensen

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

C'est très bien pour la zone de texte. Cependant, si vous essayez de faire de même pour le, checkboxessayez de l'utiliser si vous l'utilisez:

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

Mais ne l'utilisez pas disable, car disable envoie toujours la valeur par défaut falseau serveur - qu'il soit à l'état coché ou non coché. Et le readonlyne fonctionne pas pour la case à cocher et radio button. readonlyne fonctionne que pour les textchamps.


Qu'en est-il des listes déroulantes?
user3020047

J'espère que cela pourrait aider stackoverflow.com/questions/1636103
...

0

Vous pouvez utiliser le code ci-dessous pour créer une zone de texte en lecture seule.

Méthode 1

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

Méthode 2

@Html.TextBoxFor(model => model.Fields[i].TheField, new { htmlAttributes = new {disabled = "disabled"}})
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.