ASP.NET MVC 3 Razor-ajout de classe à EditorFor

J'essaie d'ajouter une classe à une entrée.

Cela ne fonctionne pas:

@Html.EditorFor(x => x.Created, new { @class = "date" })
170
demandé sur Peter Mortensen 2011-01-02 01:59:31

16 réponses

Ajouter une classe à Html.EditorFor n'a pas de sens car à l'intérieur de son modèle, vous pourriez avoir beaucoup de balises différentes. Vous devez donc attribuer la classe dans le modèle de l'éditeur:

@Html.EditorFor(x => x.Created)

Et dans le modèle personnalisé:

<div>
    @Html.TextBoxForModel(x => x.Created, new { @class = "date" })
</div>
168
répondu Darin Dimitrov 2014-12-30 16:55:19

À partir de ASP.NET MVC 5.1, ajouter une classe à un EditorFor est possible (la question d'origine spécifiée ASP.NET MVC 3, et la réponse acceptée est toujours la meilleure avec cela considéré).

@Html.EditorFor(x=> x.MyProperty,
    new { htmlAttributes = new { @class = "MyCssClass" } })

Voir: Quoi de neuf dans ASP.NET MVC 5.1, prise en charge de Bootstrap pour les modèles d'éditeur

123
répondu EF0 2016-01-30 20:33:58

Vous ne pouvez pas définir de classe pour l'EditorFor Générique. Si vous savez l'éditeur que vous voulez, vous pouvez l'utiliser tout de suite, là, vous pouvez définir la classe. Vous n'avez pas besoin de créer des modèles personnalisés.

@Html.TextBoxFor(x => x.Created, new { @class = "date" }) 
100
répondu TuomasK 2011-06-09 05:39:32

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.)

33
répondu przno 2016-01-31 17:58:36

J'ai eu 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 calendrier déroulantjQuery UI ). Dans Mes recherches, les problèmes fondamentaux que je suis tombé sur étaient:

  • l'Assistant standard TextBoxFor m'a permis d'appliquer une classe personnalisée de "Date-picker" pour rendre le calendrier discret de L'interface utilisateur jQuery, mais TextBoxFor ne formaterait pas une DateTime sans l'heure, provoquant ainsi l'échec du rendu du calendrier.
  • la norme EditorFor afficherait la DateTime comme une chaîne formatée (lorsqu'elle est décorée avec les attributs appropriés tels que [DisplayFormat(ApplyFormatInEditMode = true, DataFormatString = "{0:dd/MM/yyyy}")], mais cela ne me permettrait pas 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:

  • la méthode convertit automatiquement le DateTime en ShortDateString nécessaire au calendrier jQuery (jQuery échouera si le temps est présent).
  • par défaut, l'Assistant appliquera les attributs htmlat requis pour afficher un calendrier jQuery, mais ils peuvent être remplacés si nécessaire.
  • Si la date est nulle, ASP.NET MVC mettra une date de 1/1/0001 comme valeur.

Cette méthode remplace cela 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 la classe date-picker pour ensuite rendre le calendrier, ici est:

$(document).ready(function () {
    $('.date-picker').datepicker({ inline: true, maxDate: 0, changeMonth: true, changeYear: true });
    $('.date-picker').datepicker('option', 'showAnim', 'slideDown');
});
29
répondu bigmac 2018-02-09 16:09:19

Il est possible de fournir une classe ou d'autres informations via AdditionalViewData - Je l'utilise où je permet à 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>
15
répondu Brett 2016-01-30 20:29:07

Il n'y a pas de EditorFor override qui vous permet de transmettre un objet anonyme dont les propriétés seraient ajoutées en tant qu'attributs sur une balise, en particulier pour les modèles d'éditeur intégrés. Vous devez écrire votre propre modèle d'éditeur personnalisé et transmettre la valeur que vous voulez en tant que viewdata supplémentaire.

8
répondu marcind 2016-01-30 20:23:31
@Html.EditorFor(m=>m.Created ...) 

Ne permet pas de transmettre des arguments pour la zone de texte

Voici comment vous pouvez appliquer des attributs.

@Html.TextBoxFor(m=>m.Created, new { @class= "date", Name ="myName", id="myId" })
2
répondu Jayant Varshney 2014-12-08 20:03:52

En utilisant jQuery, vous pouvez le faire facilement:

$("input").addClass("class-name")

Voici votre balise d'entrée

@Html.EditorFor(model => model.Name)

Pour DropDownlist vous pouvez utiliser celui-ci:

$("select").addClass("class-name")

Pour Dropdownlist:

@Html.DropDownlistFor(model=>model.Name)
2
répondu Praveen M P 2016-01-30 20:31:12

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 à votre avis

@Html.EditorFor(model => model.StartDate, new { @class = "required" })

Notez que dans mon exemple, je code en dur deux classes css et le format de date. Vous pouvez, bien sûr, de changer. Vous pouvez également faire la même chose avec d'autres attributs html, comme readonly, handicapés, etc.

1
répondu Alexandre 2014-06-09 20:10:28

J'ai utilisé une autre solution en utilisant des sélecteurs d'attributs CSS pour obtenir ce dont vous avez besoin.

Indiquez l'attribut HTML que vous connaissez et mettez dans le style relatif que vous voulez.

Comme ci-dessous:

input[type="date"]
{
     width: 150px;
}
1
répondu Max Clapton 2016-01-30 20:36:35

Pas besoin 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 devrait prendre en charge MVC 4, Je ne connais pas d'autre version.

@Html.TextBox("test", "", new { @id = "signupform", @class = "form-control", @role = "form",@placeholder="Name" })
1
répondu Merbin Jo 2016-12-16 05:11:26

Alors que la question était ciblée sur MVC 3.0, nous trouvons que le problème persiste également dans MVC 4.0. MVC 5.0 inclut maintenant nativement 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;
        }
    }
}

Utilisation du balisage HTML:

@Html.EditorFor(expression: x => x.MyTestProperty).AddHtmlAttributes(new { @class = "form-control" })

(assurez-vous d'inclure l'extension l'espace de noms de la méthode dans la vue razor)

Explication: L'idée est d'injecter dans le HTML existant. J'ai choisi d'analyser L'élément courant en utilisant Linq-to-XML en utilisant XDocument.Parse(). Je passe les htmlAttributes en tant que type object. J'utilise MVC RouteValueDictionary pour analyser les htmlAttributes transmis. Je fusionne les attributs là où ils existent déjà, ou 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 retourne l'entrée d'origine chaîne.

Maintenant, je peux utiliser L'avantage de DisplayFor (rendre les types de données tels que currency de manière appropriée) mais aussi avoir la possibilité de spécifier des classes css (et tout autre attribut d'ailleurs). Peut être utile pour ajouter des attributs tels que data-*, ou ng-* (angulaire).

1
répondu barrypicker 2017-08-08 18:07:22

Vous pouvez également le faire via jQuery:

$('#x_Created').addClass(date);
0
répondu ScottRFrost 2013-08-02 19:07:39

J'ai juste besoin de définir la taille d'une zone de texte sur une page. Les attributs de codage sur le modèle et la création de modèles d'éditeur personnalisés étaient exagérés, donc je viens d'envelopper le @ Html.EditorFor appel avec une balise span qui a appelé une classe qui spécifie la taille de la zone de texte.

Déclaration de classe CSS:

.SpaceAvailableSearch input
{
    width:25px;
}

Code D'affichage:

<span class="SpaceAvailableSearch">@Html.EditorFor(model => model.SearchForm.SpaceAvailable)</span>
0
répondu Earl 2016-01-30 20:30:39

Une meilleure façon d'appliquer la 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 ajoutera le style ci-dessus à votre EditorFor()

Cela fonctionne pour MVC3.

0
répondu Bilal 2016-12-09 12:26:12