Question

Les versions d’aperçu Asp.Net MVC 2.0 fournissent des aides telles que

Html.EditorFor(c => c.propertyname)

Si le nom de la propriété est string, le code ci-dessus restitue une texbox.

Et si je souhaite transmettre les propriétés MaxLength et Size à la zone de texte ou à ma propre propriété de classe css?

Dois-je créer un modèle pour chaque combinaison de taille et de longueur de mon application? Si tel est le cas, cela ne rend pas les modèles par défaut utilisables.

Était-ce utile?

La solution 11

J'ai écrit une entrée de blog pour répondre à ma propre question

Ajout de la prise en charge des attributs html pour les modèles - Beta ASP.Net MVC 2.0

Autres conseils

Dans MVC3, vous pouvez définir la largeur comme suit:

@Html.TextBoxFor(c => c.PropertyName, new { style = "width: 500px;" })

J'ai résolu ce problème en créant un EditorTemplate nommé String.ascx dans mon dossier / Views / Shared / EditorTemplates:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>
<% int size = 10;
   int maxLength = 100;
   if (ViewData["size"] != null)
   {
       size = (int)ViewData["size"];
   }
   if (ViewData["maxLength"] != null)
   {
       maxLength = (int)ViewData["maxLength"];
   }
%>
<%= Html.TextBox("", Model, new { Size=size, MaxLength=maxLength }) %>

À mon avis, j'utilise

<%= Html.EditorFor(model => model.SomeStringToBeEdited, new { size = 15, maxLength = 10 }) %>

Fonctionne comme un charme pour moi!

Aucune des réponses de ce fil, ni d'aucun autre, sur la définition des attributs HTML pour @ Html.EditorFor ne m'aide beaucoup. Cependant, j'ai trouvé une excellente réponse à

Styliser une aide @ Html.EditorFor

J'ai utilisé la même approche et cela a fonctionné à merveille sans écrire beaucoup de code supplémentaire. Notez que l'attribut id de la sortie html de Html.EditorFor est défini. Le code de vue

<style type="text/css">
#dob
{
   width:6em;
}
</style>

@using (Html.BeginForm())
{
   Enter date: 
   @Html.EditorFor(m => m.DateOfBirth, null, "dob", null)
}

Propriété du modèle avec annotation de données et formatage de la date sous la forme & "; jj MMM aaaa &";

[Required(ErrorMessage= "Date of birth is required")]
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd MMM yyyy}")]
public DateTime DateOfBirth { get; set; }

Travaillé comme un charme sans écrire beaucoup de code supplémentaire. Cette réponse utilise ASP.NET MVC 3 Razor C #.

Peut-être voudrez-vous consulter Le blog de Kiran Chand , il utilise des métadonnées personnalisées sur le modèle d'affichage, telles que:

[HtmlProperties(Size = 5, MaxLength = 10)]
public string Title { get; set; }

Ceci est combiné à des modèles personnalisés qui utilisent les métadonnées. Une approche simple et propre à mon avis, mais j'aimerais voir ce cas d'utilisation commun intégré à mvc.

Je suis surpris que personne n'ait mentionné le transmettre à & "additionalViewData &"; et le lire de l'autre côté.

Afficher (avec des sauts de ligne, pour plus de clarté):

<%= Html.EditorFor(c => c.propertyname, new
    {
        htmlAttributes = new
        {
            @class = "myClass"
        }
    }
)%>

Modèle d'éditeur:

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<string>" %>

<%= Html.TextBox("", Model, ViewData["htmlAttributes"])) %>

Le problème est que votre modèle peut contenir plusieurs éléments HTML. Par conséquent, MVC ne saura pas à qui appliquer votre taille / classe. Vous devrez le définir vous-même.

Faites en sorte que votre modèle dérive de votre propre classe appelée TextBoxViewModel:

public class TextBoxViewModel
{
  public string Value { get; set; }
  IDictionary<string, object> moreAttributes;
  public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
  {
    // set class properties here
  }
  public string GetAttributesString()
  {
     return string.Join(" ", moreAttributes.Select(x => x.Key + "='" + x.Value + "'").ToArray()); // don't forget to encode
  }

}

Dans le modèle, vous pouvez faire ceci:

<input value="<%= Model.Value %>" <%= Model.GetAttributesString() %> />

Selon vous, vous faites:

<%= Html.EditorFor(x => x.StringValue) %>
or
<%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue, new IDictionary<string, object> { {'class', 'myclass'}, {'size', 15}}) %>

Le premier formulaire rendra le modèle par défaut pour string. Le second formulaire rendra le modèle personnalisé.

La syntaxe alternative utilise une interface fluide:

public class TextBoxViewModel
{
  public string Value { get; set; }
  IDictionary<string, object> moreAttributes;
  public TextBoxViewModel(string value, IDictionary<string, object> moreAttributes)
  {
    // set class properties here
    moreAttributes = new Dictionary<string, object>();
  }

  public TextBoxViewModel Attr(string name, object value)
  {
     moreAttributes[name] = value;
     return this;
  }

}

   // and in the view
   <%= Html.EditorFor(x => new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) %>

Notez qu'au lieu de faire cela dans la vue, vous pouvez également le faire dans le contrôleur, ou bien mieux dans le ViewModel:

public ActionResult Action()
{
  // now you can Html.EditorFor(x => x.StringValue) and it will pick attributes
  return View(new { StringValue = new TextBoxViewModel(x.StringValue).Attr("class", "myclass").Attr("size", 15) });
}

Notez également que vous pouvez créer une classe de base TemplateViewModel - un sol commun pour tous vos modèles de vue - qui contiendra un support de base pour les attributs / etc.

Mais en général, je pense que MVC v2 a besoin d’une meilleure solution. C'est toujours Beta - allez le demander ;-)

Je pense que l'utilisation de CSS est la voie à suivre. J'aimerais pouvoir faire plus avec le codage .NET, comme en XAML, mais dans le navigateur CSS est roi.

Site.css

#account-note-input { 
  width:1000px; 
  height:100px; 
} 

.cshtml

<div class="editor-label"> 
  @Html.LabelFor(model => model.Note) 
</div> 
<div class="editor-field"> 
  @Html.EditorFor(model => model.Note, null, "account-note-input", null) 
  @Html.ValidationMessageFor(model => model.Note) 
</div>

Joe

À partir de MVC 5, si vous souhaitez ajouter des attributs, vous pouvez simplement le faire

.
 @Html.EditorFor(m => m.Name, new { htmlAttributes = new { @required = "true", @anotherAttribute = "whatever" } })

Informations trouvées dans ce blog

Vous pouvez définir des attributs pour vos propriétés.

[StringLength(100)]
public string Body { get; set; }

Ceci est appelé System.ComponentModel.DataAnnotations. Si vous ne trouvez pas le ValidationAttribute dont vous avez besoin, vous pouvez toujours définir des attributs personnalisés.

Cordialement, Carlos

Ce n’est peut-être pas la solution la plus simple, mais c’est simple. Vous pouvez écrire une extension à la classe HtmlHelper.EditorFor. Dans cette extension, vous pouvez fournir un paramètre d'options qui écrira les options dans ViewData pour l'aide. Voici du code:

Tout d'abord, la méthode d'extension:

public static MvcHtmlString EditorFor<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression, TemplateOptions options)
{
    return helper.EditorFor(expression, options.TemplateName, new
    {
        cssClass = options.CssClass
    });
}

Ensuite, l'objet options:

public class TemplateOptions
{
    public string TemplateName { get; set; }
    public string CssClass { get; set; }
    // other properties for info you'd like to pass to your templates,
    // and by using an options object, you avoid method overload bloat.
}

Et enfin, voici la ligne du modèle String.ascx:

<%= Html.TextBox("", ViewData.TemplateInfo.FormattedModelValue, new { @class = ViewData["cssClass"] ?? "" }) %>

Franchement, je pense que cela est clair et clair pour le pauvre esprit qui doit maintenir votre code plus tard. Et il est facile d'étendre d'autres informations que vous souhaitez transmettre à vos modèles. Cela fonctionne bien jusqu'à présent pour moi dans un projet où j'essaye d'envelopper autant que possible dans un ensemble de modèles pour aider à normaliser le code HTML environnant, à la http://bradwilson.typepad.com/blog/2009/10/ aspnet-mvc-2-templates-part-5-master-page-templates.html .

Je ne sais pas pourquoi cela ne fonctionne pas pour Html.EditorFor mais j'ai essayé TextBoxFor et cela a fonctionné pour moi.

@Html.TextBoxFor(m => m.Name, new { Class = "className", Size = "40"})

... et la validation fonctionne également.

Dans ma pratique, j’ai trouvé qu’il était préférable d’utiliser EditorTemplates avec un seul HtmlHelper, TextBox, dans la plupart des cas. Si je veux un modèle pour une structure HTML plus complexe, j'écrirai un HtmlHelper séparé.

Etant donné que nous pouvons coller tout l’objet ViewData à la place de htmlAttributes de la zone de texte. De plus, nous pouvons écrire du code de personnalisation pour certaines propriétés de ViewData si elles nécessitent un traitement particulier:

@model DateTime?
@*
    1) applies class datepicker to the input;
    2) applies additionalViewData object to the attributes of the input
    3) applies property "format" to the format of the input date.
*@
@{
    if (ViewData["class"] != null) { ViewData["class"] += " datepicker"; }
    else { ViewData["class"] = " datepicker"; }
    string format = "MM/dd/yyyy";
    if (ViewData["format"] != null)
    {
        format = ViewData["format"].ToString();
        ViewData.Remove("format");
    }
}

@Html.TextBox("", (Model.HasValue ? Model.Value.ToString(format) : string.Empty), ViewData)

Vous trouverez ci-dessous des exemples de syntaxe dans la vue et le code HTML généré:

@Html.EditorFor(m => m.Date)
<input class="datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="01/08/2012">
@Html.EditorFor(m => m.Date, new { @class = "myClass", @format = "M/dd" })
<input class="myClass datepicker" data-val="true" data-val-required="&amp;#39;Date&amp;#39; must not be empty." id="Date" name="Date" type="text" value="1/08">

Étant donné que la question concerne EditorFor , la suggestion de TextBoxFor pour WEFX ne fonctionne pas.

Pour modifier des zones de saisie individuelles, vous pouvez traiter la sortie de la méthode EditorFor:

<%: new HtmlString(Html.EditorFor(m=>m.propertyname).ToString().Replace("class=\"text-box single-line\"", "class=\"text-box single-line my500pxWideClass\"")) %>

Il est également possible de modifier TOUS vos EditorFors, car il s'avère que MVC définit la classe des zones de texte EditorFor avec .text-box , vous pouvez donc simplement remplacer ce style, dans votre feuille de style ou la page.

.text-box {
    width: 80em;
}

De plus, vous pouvez définir le style pour

input[type="text"] {
    width: 200px;
}
  • ceci remplace la .text-box et modifiera toutes les zones de saisie, EditorFor ou autre.

J'ai également eu un problème avec la définition de la largeur de TextBox dans MVC3, alors que la définition de l'attribut Clsss fonctionnait pour le contrôle TextArea mais pas pour le contrôle TextBoxFor ou EditorFor:

J'ai essayé de suivre & amp; cela a fonctionné pour moi:

 @ Html.TextBoxFor (model = & Gt; model.Title, new {Class = & "; TextBox &" ;, style = & "; Width: 90%; &";}} )

également dans ce cas, les validations fonctionnent parfaitement.

Une façon de contourner le problème est d’avoir des délégués sur le modèle de vue pour gérer l’impression de rendu spécial comme celui-ci. Je l’ai fait pour une classe de pagination, j’expose une propriété publique sur le modèle Func<int, string> RenderUrl pour la gérer.

Définissez donc comment le bit personnalisé sera écrit:

Model.Paging.RenderUrl = (page) => { return string.Concat(@"/foo/", page); };

Afficher la vue pour la Paging classe:

@Html.DisplayFor(m => m.Paging)

... et pour la vue <=> actuelle:

@model Paging
@if (Model.Pages > 1)
{
    <ul class="paging">
    @for (int page = 1; page <= Model.Pages; page++)
    {
        <li><a href="@Model.RenderUrl(page)">@page</a></li>
    }
    </ul>
}

Cela peut sembler excessif, mais j’utilise ces téléavertisseurs un peu partout et ne supporte pas de voir le même code standard pour les obtenir restitués.

UPDATE: hm, évidemment, cela ne fonctionnera pas car le modèle est passé par valeur, ainsi les attributs ne sont pas conservés; mais je laisse cette réponse comme une idée.

Une autre solution, je pense, consisterait à ajouter vos propres assistants TextBox / etc, qui vérifieront vos propres attributs sur le modèle.

public class ViewModel
{
  [MyAddAttribute("class", "myclass")]
  public string StringValue { get; set; }
}

public class MyExtensions
{
  public static IDictionary<string, object> GetMyAttributes(object model)
  {
     // kind of prototype code...
     return model.GetType().GetCustomAttributes(typeof(MyAddAttribute)).OfType<MyAddAttribute>().ToDictionary(
          x => x.Name, x => x.Value);
  }
}

<!-- in the template -->
<%= Html.TextBox("Name", Model, MyExtensions.GetMyAttributes(Model)) %>

Celui-ci est plus facile mais pas aussi pratique / flexible.

C’est le moyen le plus propre et le plus élégant / simple d’obtenir une solution ici.

Brilliant blog et pas de folie dans la rédaction de méthodes d'extension / helper personnalisées comme un professeur fou.

http: // geekswithblogs.net/michelotti/archive/2010/02/05/mvc-2-editor-template-with-datetime.aspx

J'ai vraiment aimé la réponse @tjeerdans qui utilise le EditorTemplate nommé String.ascx dans le dossier / Views / Shared / EditorTemplates. Cela semble être la réponse la plus directe à cette question. Cependant, je voulais un modèle utilisant la syntaxe Razor. En outre, il semble que MVC3 utilise le modèle String par défaut (voir la question StackOverflow & Quot; le modèle d'affichage mvc pour les chaînes est utilisé pour les entiers "). définissez le modèle sur objet plutôt que sur chaîne. Mon modèle semble fonctionner jusqu'à présent:

@model object 

@{  int size = 10; int maxLength = 100; }

@if (ViewData["size"] != null) {
    Int32.TryParse((string)ViewData["size"], out size); 
} 

@if (ViewData["maxLength"] != null) {
    Int32.TryParse((string)ViewData["maxLength"], out maxLength); 
}

@Html.TextBox("", Model, new { Size = size, MaxLength = maxLength})

Je l'ai résolu !!
Pour Razor, la syntaxe est la suivante:
@Html.TextAreaFor(m=>m.Address, new { style="Width:174px" }) Ceci ajuste la largeur de la zone de texte à la largeur que j’ai définie dans le paramètre style.
Pour ASPx, la syntaxe est la suivante:
<%=Html.TextAreaFor(m => m.Description, new { cols = "20", rows = "15", style="Width:174px" })%>
cela fera l'affaire

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top