J'essaie d'ajouter une classe à une entrée.
Cela ne fonctionne pas:
@Html.EditorFor(x => x.Created, new { @class = "date" })
Ajouter une classe à Html.EditorFor
n'a pas de sens, car dans son modèle, vous pourriez avoir beaucoup de balises différentes. Vous devez donc assigner la classe dans le modèle d’éditeur:
@Html.EditorFor(x => x.Created)
et dans le modèle personnalisé:
<div>
@Html.TextBoxForModel(x => x.Created, new { @class = "date" })
</div>
À partir d'ASP.NET MVC 5.1, il est possible d'ajouter une classe à un EditorFor
(la question d'origine spécifiait ASP.NET MVC 3 et la réponse acceptée demeurait la meilleure avec celle considérée).
@Html.EditorFor(x=> x.MyProperty,
new { htmlAttributes = new { @class = "MyCssClass" } })
Voir: Nouveautés de ASP.NET MVC 5.1, Prise en charge de Bootstrap pour les modèles d'éditeur
Vous ne pouvez pas définir la classe pour le EditorFor générique. Si vous connaissez l'éditeur que vous voulez, vous pouvez l'utiliser immédiatement, vous pouvez y définir la classe. Vous n'avez pas besoin de créer de modèles personnalisés.
@Html.TextBoxFor(x => x.Created, new { @class = "date" })
Vous pouvez utiliser:
@Html.EditorFor(x => x.Created, new { htmlAttributes = new { @class = "date" } })
(Au moins avec ASP.NET MVC 5, mais je ne sais pas comment c'était avec ASP.NET MVC 3.)
J'avais le même problème frustrant et je ne voulais pas créer un EditorTemplate qui s'appliquait à toutes les valeurs DateTime (il y avait des moments dans mon interface utilisateur où je voulais afficher l'heure et non un jQuery UI drop calendrier en bas). Dans mes recherches, les problèmes fondamentaux que j'ai rencontrés étaient les suivants:
[DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")]
, mais il ne permet pas moi d'appliquer la classe personnalisée "date-picker".Par conséquent, j'ai créé une classe HtmlHelper personnalisée qui présente les avantages suivants:
Cette méthode remplace celle-ci par une chaîne vide.
public static MvcHtmlString CalenderTextBoxFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, object htmlAttributes = null)
{
var mvcHtmlString = System.Web.Mvc.Html.InputExtensions.TextBoxFor(htmlHelper, expression, htmlAttributes ?? new { @class = "text-box single-line date-picker" });
var xDoc = XDocument.Parse(mvcHtmlString.ToHtmlString());
var xElement = xDoc.Element("input");
if (xElement != null)
{
var valueAttribute = xElement.Attribute("value");
if (valueAttribute != null)
{
valueAttribute.Value = DateTime.Parse(valueAttribute.Value).ToShortDateString();
if (valueAttribute.Value == "1/1/0001")
valueAttribute.Value = string.Empty;
}
}
return new MvcHtmlString(xDoc.ToString());
}
Et pour ceux qui veulent connaître la syntaxe JQuery qui recherche les objets avec la décoration de classe date-picker
pour ensuite afficher le calendrier, la voici:
$(document).ready(function () {
$('.date-picker').datepicker({ inline: true, maxDate: 0, changeMonth: true, changeYear: true });
$('.date-picker').datepicker('option', 'showAnim', 'slideDown');
});
Il est possible de fournir une classe ou d'autres informations via AdditionalViewData. J'utilise cette option pour permettre à un utilisateur de créer un formulaire basé sur des champs de base de données (propertyName, editorType et editorClass).
Basé sur votre exemple initial:
@Html.EditorFor(x => x.Created, new { cssClass = "date" })
et dans le modèle personnalisé:
<div>
@Html.TextBoxFor(x => x.Created, new { @class = ViewData["cssClass"] })
</div>
Aucune substitution EditorFor
ne vous permet de transmettre un objet anonyme dont les propriétés seraient en quelque sorte ajoutées aux attributs de certaines balises, en particulier pour les modèles d'éditeur intégrés. Vous devrez écrire votre propre modèle d'éditeur personnalisé et transmettre la valeur souhaitée en tant que viewdata supplémentaire.
@Html.EditorFor(m=>m.Created ...)
n'autorise aucun argument à être transmis pour la zone de texte
Voici comment vous pouvez appliquer des attributs.
@Html.TextBoxFor(m=>m.Created, new { @class= "date", Name ="myName", id="myId" })
Avec jQuery, vous pouvez le faire facilement:
$("input").addClass("class-name")
Voici votre tag d'entrée
@Html.EditorFor(model => model.Name)
Pour DropDownlist, vous pouvez utiliser celui-ci:
$("select").addClass("class-name")
Pour la liste déroulante:
@Html.DropDownlistFor(model=>model.Name)
J'ai utilisé une autre solution utilisant des sélecteurs d'attributs CSS pour obtenir ce dont vous avez besoin.
Indiquez l'attribut HTML que vous connaissez et indiquez le style relatif souhaité.
Comme ci-dessous:
input[type="date"]
{
width: 150px;
}
Il n'est pas nécessaire de créer un modèle personnalisé pour MVC 4. Utilisez TextBox au lieu de EditFor ici, les attributs HTML spéciaux ne sont pas pris en charge. Ils ne sont pris en charge que par MVC 5. TextBox doit prendre en charge MVC 4, je ne sais pas pour une autre version.
@Html.TextBox("test", "", new { @id = "signupform", @class = "form-control", @role = "form",@placeholder="Name" })
Alors que la question visait MVC 3.0, nous constatons que le problème persiste également dans MVC 4.0. MVC 5.0 inclut maintenant de manière native une surcharge pour htmlAttributes.
Je suis obligé d'utiliser MVC 4.0 sur mon lieu de travail actuel et j'ai besoin d'ajouter une classe CSS pour l'intégration JQuery. J'ai résolu ce problème en utilisant une seule méthode d'extension ...
Méthode d'extension:
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using System.Xml.Linq;
namespace MyTest.Utilities
{
public static class MVCHelperExtensionMethods
{
public static MvcHtmlString AddHtmlAttributes(this MvcHtmlString input, object htmlAttributes)
{
// WE WANT TO INJECT INTO AN EXISTING ELEMENT. IF THE ATTRIBUTE ALREADY EXISTS, ADD TO IT, OTHERWISE
// CREATE THE ATTRIBUTE WITH DATA VALUES.
// USE XML PARSER TO PARSE HTML ELEMENT
var xdoc = XDocument.Parse(input.ToHtmlString());
var rootElement = (from e in xdoc.Elements() select e).FirstOrDefault();
// IF WE CANNOT PARSE THE INPUT USING XDocument THEN RETURN THE ORIGINAL UNMODIFIED.
if (rootElement == null)
{
return input;
}
// USE RouteValueDictionary TO PARSE THE NEW HTML ATTRIBUTES
var routeValueDictionary = new RouteValueDictionary(htmlAttributes);
foreach (var routeValue in routeValueDictionary)
{
var attribute = rootElement.Attribute(routeValue.Key);
if (attribute == null)
{
attribute = new XAttribute(name: routeValue.Key, value: routeValue.Value);
rootElement.Add(attribute);
}
else
{
attribute.Value = string.Format("{0} {1}", attribute.Value, routeValue.Value).Trim();
}
}
var elementString = rootElement.ToString();
var response = new MvcHtmlString(elementString);
return response;
}
}
}
HTML Markup Usage:
@Html.EditorFor(expression: x => x.MyTestProperty).AddHtmlAttributes(new { @class = "form-control" })
(Assurez-vous d'inclure l'espace de nom de la méthode d'extension dans la vue rasoir)
Explication: L'idée est d'injecter dans le code HTML existant. J'ai choisi d'analyser l'élément actuel à l'aide de Linq-to-XML à l'aide de XDocument.Parse()
. Je passe les htmlAttributes comme type object
. J'utilise MVC RouteValueDictionary
pour analyser les htmlAttributes transmis. Je fusionne les attributs là où ils existent déjà, ou j'ajoute un nouvel attribut s'il n'existe pas encore.
Dans le cas où l'entrée n'est pas analysable par XDocument.Parse()
j'abandonne tout espoir et renvoie la chaîne d'entrée d'origine.
Maintenant, je peux utiliser les avantages de DisplayFor (types de données de rendu tels que la devise, de manière appropriée), mais aussi avoir la possibilité de spécifier des classes CSS (et tout autre attribut). Cela pourrait être utile pour ajouter des attributs tels que data-*
ou ng-*
(Angulaire).
Vous pouvez créer le même comportement en créant un éditeur personnalisé simple appelé DateTime.cshtml, en l'enregistrant dans Views/Shared/EditorTemplates.
@model DateTime
@{
var css = ViewData["class"] ?? "";
@Html.TextBox("", (Model != DateTime.MinValue? Model.ToString("dd/MM/yyyy") : string.Empty), new { @class = "calendar medium " + css});
}
et dans vos vues
@Html.EditorFor(model => model.StartDate, new { @class = "required" })
Notez que dans mon exemple, je codifie en dur deux classes CSS et le format de date. Vous pouvez bien sûr changer cela. Vous pouvez également faire la même chose avec d'autres attributs HTML, tels que readonly, disabled, etc.
Un meilleur moyen d’appliquer une classe à @Html.EditorFor()
dans MVC3 RAzor est
@Html.EditorFor(x => x.Created)
<style type="text/css">
#Created
{
background: #EEE linear-gradient(#EEE,#EEE);
border: 1px solid #adadad;
width:90%;
}
</style>
Il va ajouter du style ci-dessus à votre EditorFor()
Cela fonctionne pour MVC3.
Je devais simplement définir la taille d'un champ de texte sur une page. Le codage des attributs sur le modèle et la création de modèles d'éditeur personnalisés étaient excessifs. Je viens donc d'encapsuler l'appel @ Html.EditorFor avec une balise span qui appelle une classe qui spécifie la taille de la zone de texte.
.SpaceAvailableSearch input
{
width:25px;
}
<span class="SpaceAvailableSearch">@Html.EditorFor(model => model.SearchForm.SpaceAvailable)</span>
Vous pouvez aussi le faire via jQuery:
$('#x_Created').addClass(date);