65

I use the HTML Helpers to render my fields:

<%=Html.EditorFor(m => m.User.Surname)%>

and the output would be something like this:

<input class="text-box single-line" id="User_Surname" 
          name="User.Surname" type="text" value="" />

The helper uses the className + '.' è fieldName to build the id.
I need to pass the id to a jQuery function. Is there a way to have it without hardcoding it? Maybe an helper which can use the ASP.NET MVC2 conventions?

4 Answers 4

144

ASP.NET MVC 4 has Html.IdFor() built in that can return this:

@Html.IdFor(m => m.User.Surname)
Sign up to request clarification or add additional context in comments.

Comments

44

See this question: get the generated clientid for a form field, this is my answer:

I use this helper:

public static partial class HtmlExtensions
{
    public static MvcHtmlString ClientIdFor<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression)
    {
        return MvcHtmlString.Create(
              htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(
                  ExpressionHelper.GetExpressionText(expression)));
    }
}

Use it just as you would any other helper: @Html.ClientIdFor(model=>model.client.email)

2 Comments

Per my answer, this is now built into ASP.NET 4 with Html.IdFor()
thanks so much i needed that. html.IdFor() didnt help me becouse im making a custom helper ,
10

I've followed the instructions of Mac's answer here and I've built my own custom extension:

public static class HtmlHelperExtensions
{
    public static string HtmlIdNameFor<TModel, TValue>(
        this HtmlHelper<TModel> htmlHelper,
        System.Linq.Expressions.Expression<Func<TModel, TValue>> expression)
    {
        return (GetHtmlIdNameFor(expression));
    }

    private static string GetHtmlIdNameFor<TModel, TValue>(Expression<Func<TModel, TValue>> expression)
    {
        if (expression.Body.NodeType == ExpressionType.Call)
        {
            var methodCallExpression = (MethodCallExpression)expression.Body;
            string name = GetHtmlIdNameFor(methodCallExpression);
            return name.Substring(expression.Parameters[0].Name.Length + 1).Replace('.', '_');

        }
        return expression.Body.ToString().Substring(expression.Parameters[0].Name.Length + 1).Replace('.', '_');
    }

    private static string GetHtmlIdNameFor(MethodCallExpression expression)
    {
        var methodCallExpression = expression.Object as MethodCallExpression;
        if (methodCallExpression != null)
        {
            return GetHtmlIdNameFor(methodCallExpression);
        }
        return expression.Object.ToString();
    }
}

I've imported my application's namespace

<%@ Import Namespace="MvcApplication2" %>

and finally I can use my code like this:

<%=Html.HtmlIdNameFor(m=>m.Customer.Name)%>

2 Comments

It's worth noting that you need a 'using System.Linq.Expressions;' for this to work. Sweet code anyway :)
I think you also need to replace '[' & ']' (if you are referencing array elements)
7

unless you create your own User.Surname EditorTemplate which you pass in some HTML attributes you won't be able to do this with EditorFor

However you can use TextBoxFor and set the id

<%= Html.TextBoxFor(m => m.User.Surname, new { id = "myNewId" })%>

On the topic of retrieving this element with a jQuery selector you can achieve this without having to hardcode by using some of the ends-with selector. Using that you could probably still use EditorFor and just select it with $("[id^='Surname]")`. If you're trying to select this specific element there's really no way to NOT hardcode SOMETHING in your jQuery code.

1 Comment

Adding the HTML attributes is the EASIEST way. Much easier than writing your own extension methods

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.