Question

I'm currently building the Admin back-end for a website in ASP.NET MVC.

In an ASP.NET MVC application, I've started using the 'EditorFor' helper method like so:

<div id="content-edit" class="data-form">
    <p>
        <%= Html.LabelFor(c => c.Title) %>
        <%= Html.TextBoxFor(c => c.Title)%>
    </p>
    <p>
        <%= Html.LabelFor(c => c.Biography) %>
        <%= Html.EditorFor(c => c. Biography)%>
    </p>
</div>

In the model, the 'Biography' field has been decorated with: [UIHelper("Html")].

I have an 'Html' partial view (under Views/Shared/EditorTemplates):

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<System.XML.Linq.XElement>" %>

<textarea class="html">
    <%= Model.ToString() %>
</textarea>

Now I'd like to have the 'ID' attribute of the 'textarea' set to the name of the field, like this:

<textarea id="Biography" class="html">
    ...
</textarea>

But I can't see a way to do that with the current set up.

All I can think of is creating an 'Html' ViewModel that contains a 'Value' property and a 'ControlID' property.

But if I based the view off that, rather than 'System.XML.Linq.XElement', it would no longer be compatible with the 'EditorFor' helper method and I'd have to do everything manually.

Has anyone had a similar problem yet?

Was it helpful?

Solution

You should be able to pull out the desired ID from the ViewData.TemplateInfo.HtmlFieldPrefix property of the view. Like this:

<%@ Control Language="C#"
      Inherits="System.Web.Mvc.ViewUserControl<System.XML.Linq.XElement>" %>
<textarea id="<%= ViewData.TemplateInfo.HtmlFieldPrefix %>" class="html">
    <%= Model.ToString() %>
</textarea>

To show why this works, here's the place in TemplateHelpers.cs (of MVC2 Preview 1 source) where ViewData is initialized for the Editor template control:

ViewDataDictionary viewData = new ViewDataDictionary(html.ViewDataContainer.ViewData) {
    Model = modelValue,
    TemplateInfo = new TemplateInfo {
        FormattedModelValue = formattedModelValue,
        ModelType = modelType,
        HtmlFieldPrefix = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(expression),
        IsNullableValueType = (underlyingNullableType != null),
    }
};

In the call above, "expression" is initialized (further up the call stack) with the name of the property being edited.

BTW, @Sperling below caught a detail I originally missed: if you're using (or might use) a non-default HtmlHelper.IdAttributeDotReplacement, then you'll want to replace the dots in the HtmlPrefix property with HtmlHelper.IdAttributeDotReplacement.

OTHER TIPS

Have been using this to generate id(with model prefix). Skip the .Replace() part if you want the name attribute.

<%=Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(String.Empty).Replace(".", HtmlHelper.IdAttributeDotReplacement) %>

In our case we had to use Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName with ExpressionHelper.GetExpressionText

which in razor was used like this:

           // hiddenFor was caching the value of this html input, and the value alone, nothing else on the page!
            Expression<Func<Web.ViewModels.ApiSettingsViewModel, int>> expression = (m => m.OrgApiLoginCredentials[i].OrgApiLoginId); 
        }
        <input type="hidden" value="@Model.OrgApiLoginCredentials[i].OrgApiLoginId" name="@Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(ExpressionHelper.GetExpressionText(expression))" class="data-org-api-login-id"/>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top