tags:

views:

363

answers:

4

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?

A: 
<%= Html.TextBox ("myTextBox", "", 
         new { @class="redText", title="Enter red text here"})%>

results in:

<input type="text" id="myTextBox" class="redText" title="Enter red text here" />

I'm not sure what your issue is. Might have something to do with the "-" in your anonymous type's property name.


Yeah, the compiler doesn't like your attribute name. From the comments, in order to add html5 data- attributes, you'll have to use the dictionary or create another extension that simplifies construction of the dictionaries.

Will
How does this code define "data-myid" attribute on text box?
Hemant
Why do you *want* to put an invalid attribute on your html?
Will
the compiler does not like the hyphen in an object key
redsquare
Yes! The problem is because of "-" in the attribute name. Is there anyway to define that attribute since as per HTML 5, any custom attribute must take the shape of "data-XXX"
Hemant
@will it is a html5 spec attribute
redsquare
Aaaaaah, 5, my bad.
Will
Looks like the 5 specs are completely incompatible with anonymous type declarations.
Will
yup, looks that way
redsquare
A: 

I believe if you take out the dash you will not get a syntax error.

Something like:

<%= Html.TextBox ("textBox", "Value", new { datamyid = m.ID })%>

Kindness,

Dan

Daniel Elliott
But as per HTML 5, any custom attribute must take the shape of "data-XXX"
Hemant
So taking the dash out is **NOT** an option.
Hemant
You'll have to use the dictionary route as the compiler won't accept "-"s in anonymous type declarations.
Will
A: 

I think you will have to create your own helper to do this for you. I cannot find a way to do this directly in the view.

redsquare
+1  A: 

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 } ) ) %>
stevemegson