2008-10-07 10 views
27

J'ai un MVC View Control fortement typé qui est responsable de l'interface utilisateur où les utilisateurs peuvent créer et modifier des éléments Client. Je voudrais qu'ils soient en mesure de définir le ClientId à la création, mais pas éditer, et cela à refléter dans l'interface utilisateur.Html.TextBox attribut conditionnel avec ASP.NET MVC Preview 5

À cette fin, j'ai la ligne suivante:

<%= Html.TextBox("Client.ClientId", ViewData.Model.ClientId, new 
{ @readonly = 
    (ViewData.Model.ClientId != null && ViewData.Model.ClientId.Length > 0 
     ? "readonly" : "false") 
}) 
%> 

Il semble que peu importe quelle valeur je donne l'attribut lecture seule (même « faux » et « »), Firefox et IE7 font l'entrée lire -seulement, ce qui est énormément contre-intuitif. Existe-t-il une manière agréable, basée sur l'opérateur ternaire, de supprimer complètement l'attribut si ce n'est pas nécessaire?

Répondre

35

problème difficile ... Cependant, si vous souhaitez définir uniquement l'attribut readonly, vous pouvez le faire comme ceci:

<%= Html.TextBox("Client.ClientId", ViewData.Model.ClientId, 
    ViewData.Model.ClientId != null && ViewData.Model.ClientId.Length > 0 
    ? new { @readonly = "readonly" } 
    : null) 
%> 

Si vous souhaitez définir plusieurs attributs, vous devez définir deux types anonymes et avoir plusieurs copies des attributs. Par exemple, quelque chose comme ça (que je ne l'aime pas de toute façon):

ClientId.Length > 0 
    ? (object)new { @readonly = "readonly", @class = "myCSS" } 
    : (object)new { @class = "myCSS" } 
+0

+1 Mon premier coup a été le deuxième extrait de code sans la distribution à l'objet.C'est facilement négligé mais vraiment nécessaire. –

4

Et alternative est simplement d'émettre comme bon vieux HTML. Oui, l'éditeur vous fera penser que vous avez tort, mais cela semble se produire assez souvent avec VS2008SP1. Cet exemple est spécifiquement pour les cases à cocher qui semblent être complètement perdues dans CTP5, mais il vous donne une idée de comment émettre des attributs conditionnels.

<input type="checkbox" name="roles" value='<%# Eval("Name") %>' 
    <%# ((bool) Eval("InRole")) ? "checked" : "" %> 
    <%# ViewData.Model.IsInRole("Admin") ? "" : "disabled" %> /> 
1

Je pense qu'il devrait être

<%= ((bool) Eval("InRole")) ? "checked" : "" %> 

au lieu de cela dans leppies répondre.

<%# ((bool) Eval("InRole")) ? "checked" : "" %> 

Au moins cela n'a pas fonctionné pour moi aveC# mais cela a fonctionné avec =. Ai-je fait quelque chose de mal? Merci pour la pointe de toute façon :)

0
$ (function() {$ ( "[= readonly 'false']") removeAttr ("lecture seule"). });
21

Si vous souhaitez définir plusieurs attributs, et en lecture seule condition sans dupliquer les autres attributs, vous pouvez utiliser le dictionnaire au lieu de types anonymes pour les attributs.

par exemple.

Dictionary<string, object> htmlAttributes = new Dictionary<string, object>(); 
htmlAttributes.Add("class", "myCSS"); 
htmlAttributes.Add("data-attr1", "val1"); 
htmlAttributes.Add("data-attr2", "val2"); 
if (Model.LoggedInData.IsAdmin == false) 
{ 
    htmlAttributes.Add("readonly", "readonly"); 
} 


@:User: @Html.TextBoxFor(
    m => m.User, 
    htmlAttributes) 
+1

Devrait être la réponse, car elle évite la répétition. –

-2

J'ai essayé la plupart des suggestions ci-dessus et maintenant je suis arrivé au plus simple avec une seule ligne. Combinez 2 attributs html anonymes en déclarant l'un d'entre eux comme type "object".

@Html.TextBoxFor(m => m.Email, !isEdit ? new { id = "email_box" } : new { id = "email_box", @readonly = isEdit ? "readonly" : "false" } as object) 
+0

Cela ne fonctionne pas pour moi; '@readonly = false' est toujours interprété comme' readonly' –

2

Conseil: Son la simple présence de l'attribut readonly/désactivé qui fait l'élément en lecture seule ou désactivé dans le navigateur.

@Html.TextBoxFor(x => x.Name, isReadonly ?(object) new { @readonly = true } : new { /*Some other attributes*/ }) 
+0

Pourquoi la classe anonyme doit-elle être convertie en objet pour la première condition de l'op ternaire? Ne pas le contester, juste essayer de le comprendre. Merci! – eaglei22

0

i utiliser ceci:

@Html.TextAreaFor(model => model.ComentarioGestor, comentarioGestor? new { @class = "form-control" } : new { @class = "form-control", @readonly = "readonly" } as object) 
Questions connexes