I learned few minutes ago that adding data attributes is a nice way to add custom information to html elements. So I tried to do like this:
<%= Html.TextBox ("textBox", "Value", new { data-myid = m.ID })%>
But it ends up as a syntax error. How can I define custom data attributes?
EDIT:
I see that I can achieve this effect using:
<%= Html.TextBox ("textBox", "Value", new Dictionary<string, object> {{ "data-myid", m.ID }})%>
But that doesn't look...umm...clean! Is there any better way to do this?
Adding a data attribute is easy. Any HTML element can have any number of data attributes added to its opening tag. We simply type data- followed by the name of our attribute into the element's opening tag alongside any other attributes we're already using.
HTML | data-* AttributesCustom Data Attributes allow you to add your own information to tags in HTML. Even though the name suggests otherwise, these are not specific to HTML5 and you can use the data-* attribute on all HTML elements. The data-* attributes can be used to define our own custom data attributes.
These attributes are used to define metadata for ASP.NET MVC and ASP.NET data controls. You can apply these attributes to the properties of the model class to display appropriate validation messages to the users.
A data-* attribute on a <nav> tag attaches additional data to the navigation element. To create a custom attribute, replace * with a lowercase string, such as data-id , data-status , or data-location .
Use an underscore instead of a dash.
new { data_myid = m.ID }
This definitely works in MVC3 (haven't checked other versions). The underscore will be converted to a dash when the HTML is rendered.
EDIT
This works in the latest versions of MVC too.
I can't see any way to get an anonymous type declaration to accept data-myid
, since that's not a valid property name in C#. One option would be to create a new overload that takes an extra dataAttributes
parameter, and prepends data-
to the names for you...
using System.ComponentModel; using System.Web.Mvc; using System.Web.Mvc.Html; using System.Web.Routing; static class TextBoxExtensions { public static string TextBox(this HtmlHelper htmlHelper, string name, object value, object htmlAttributes, object dataAttributes) { RouteValueDictionary attributes = new RouteValueDictionary(htmlAttributes); attributes.AddDataAttributes(dataAttributes); return htmlHelper.TextBox( name, value, ((IDictionary<string, object>)attributes); } private static void AddDataAttributes(this RouteValueDictionary dictionary, object values) { if (values != null) { foreach (PropertyDescriptor descriptor in TypeDescriptor.GetProperties(values)) { object obj2 = descriptor.GetValue(values); dictionary.Add("data-" + descriptor.Name, obj2); } } } }
Then you can add a data-myid
attribute with
<%= Html.TextBox ("textBox", "Value", new { title = "Some ordinary attribute" }, new { myid = m.ID }) %>
However, that leaves you to create that overload on any other methods that you want to accept data attributes, which is a pain. You could get around that by moving the logic to a
public static IDictionary<string,object> MergeDataAttributes( this HtmlHelper htmlHelper, object htmlAttributes, object dataAttributes)
and call it as
<%= Html.TextBox ("textBox", "Value", Html.MergeDataAttributes( new { title = "Some ordinary attribute" }, new { myid = m.ID } ) ) %>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With