129 votes

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

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

Y a-t-il une méthode HTMLHelper disponible pour faire cela ?

Quelque chose comme le suivant ?

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

263voto

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

Vous pouvez créer un HTML Helper pour cela, mais il s'agit simplement d'un attribut HTML comme un autre. Feriez-vous un HTML Helper pour une zone de texte ayant d'autres attributs ?

34voto

Javad_Amiry Points 9003

UPDATE : Il est maintenant très simple d'ajouter des attributs HTML aux modèles par défaut de l'éditeur. Il ne faut pas le faire au lieu de le faire :

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

vous pouvez tout simplement le faire :

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

Les avantages : Vous n'avez pas besoin d'appeler .TextBoxFor etc. pour les modèles. Il suffit d'appeler .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 editor-template qui peuvent manipuler readonly attribut :

  1. Créez un dossier nommé EditorTemplates en ~/Views/Shared/

  2. Créer un rasoir PartialView nommé String.cshtml

  3. Remplir le String.cshtml avec 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 du modèle, mettez le [ReadOnly(true)] sur les propriétés qui doivent ê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 en toute simplicité :

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

Le premier rend une image normale text-box comme ça :

<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.MultilineText et ainsi de suite). Il suffit de créer un editor-template .

2 votes

+1 parce que vous avez utilisé "ViewData.ModelMetadata.IsReadOnly". Je m'attendais à ce que MVC prenne en compte ces choses dans la version 4.

0 votes

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

2 votes

@Javad_Amiry - excellente réponse - Je l'ai implémentée et elle semblait fonctionner parfaitement jusqu'à ce que je clique sur Enregistrer sur une page d'édition échafaudée. Il s'avère alors que les propriétés avec [ReadOnly(true)] auront pour résultat que NULL sera envoyé à la base de données au lieu de la valeur réelle de la propriété - Avez-vous rencontré ce problème ?

5voto

Bronek Points 1476

La solution avec TextBoxFor est OK, mais si vous ne veulent pas voir le champ comme une EditBox stylée (cela pourrait être un peu confus pour l'utilisateur) implique les changements suivants :

  1. Code du rasoir avant les changements

    <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 le champ d'être édité, mais en montre la valeur. Il n'est pas nécessaire de modifier le code-behind.

1 votes

Je pense que le fait d'avoir les CSS pour les classes editor-field et display-field ici pourrait être vraiment utile.

0 votes

Que voulez-vous dire par "cette solution désactive le classement contre l'édition," (cela semble incompréhensible) ? Veuillez répondre par éditer votre réponse et non ici dans les commentaires (le cas échéant).

4voto

Adithya Baddula Points 65

Avec des crédits à la réponse précédente par @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 cachée. J'espère que cela sera utile pour quelqu'un qui travaille avec ASP.NET Core.

0voto

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X