ASP.NET MVC 3 Razor - Adding class to EditorFor

后端 未结 16 2104
长情又很酷
长情又很酷 2020-11-27 11:09

I\'m trying to add a class to an input.

This is not working:

@Html.EditorFor(x => x.Created, new { @class = \"date\" })
16条回答
  •  星月不相逢
    2020-11-27 11:48

    While the question was targeted at MVC 3.0, we find the problem persists in MVC 4.0 as well. MVC 5.0 now includes natively an overload for htmlAttributes.

    I am forced to use MVC 4.0 at my current place of employment and needed to add a css class for JQuery integration. I solved this problem using a single extension method...

    Extension Method:

    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" })
    

    (Make sure to include the extension method's namespace in the razor view)

    Explanation: The idea is to inject into the existing HTML. I opted to parse the current element using Linq-to-XML using XDocument.Parse(). I pass the htmlAttributes as type object. I utilize MVC RouteValueDictionary to parse the htmlAttributes passed in. I merge the attributes where they already exist, or add a new attribute if it does not yet exist.

    In the event the input is not parsable by XDocument.Parse() I abandon all hope and return the original input string.

    Now I can use the benefit of the DisplayFor (rendering datatypes such as currency appropriately) but also have the ability to specify css classes (and any other attribute for that matter). Could be helpful for adding attributes such as data-*, or ng-* (Angular).

提交回复
热议问题