Радиокнопка генерирует дубликаты HTML-идентификаторов - PullRequest
35 голосов
/ 10 мая 2010

Похоже, что ASP.NET MVC2 Html-помощник генерирует дубликаты HTML-идентификаторов при использовании кода, подобного этому (EditorTemplates / UserType.ascx):

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

<%: Html.RadioButton("", UserType.Primary, Model == UserType.Primary) %>
<%: Html.RadioButton("", UserType.Standard, Model == UserType.Standard) %>
<%: Html.RadioButton("", UserType.ReadOnly, Model == UserType.ReadOnly) %>

HTML-код, который он создает:

<input checked="checked" id="UserType" name="UserType" type="radio" value="Primary" /> 
<input id="UserType" name="UserType" type="radio" value="Standard" /> 
<input id="UserType" name="UserType" type="radio" value="ReadOnly" /> 

Это ясно показывает проблему. Поэтому я, должно быть, неправильно использую Помощника или что-то в этом роде.

Я могу вручную указать id как атрибут html, но тогда я не могу гарантировать, что он будет уникальным.

Таким образом, вопрос заключается в том, как убедиться, что идентификаторы, сгенерированные помощником RadioButton, уникальны для каждого значения и все еще сохраняют соглашения для генерации этих идентификаторов (поэтому соблюдаются вложенные модели ? (Желательно не генерировать идентификаторы вручную.)

Ответы [ 3 ]

15 голосов
/ 08 декабря 2011

В дополнение к ответу PanJanek:
Если вам действительно не нужно, чтобы элементы имели идентификатор, вы также можете указать id="" в параметре помощников htmlAttributes (т.е. new { id="" }). Это приведет к тому, что атрибут id будет полностью исключен из сгенерированного html.

источник: https://stackoverflow.com/a/2398670/210336

12 голосов
/ 10 мая 2010

Я столкнулся с той же проблемой. Задание идентификаторов вручную, похоже, является единственным решением. Если вам не нужны идентификаторы для чего-либо (например, javascript), но вы хотите, чтобы они были уникальными, вы можете сгенерировать для них Guids:

<%: Html.RadioButton("", UserType.Primary, Model == UserType.Primary, new { id="radio" + Guid.NewGuid().ToString()}) %>

Более элегантное решение - создать собственный метод расширения на HtmlHelper, чтобы отделить логику создания идентификатора от представления. Что-то вроде:

public static class HtmlHelperExtensions
{

    public static MvcHtmlString MyRadioButtonFor<TModel, TValue>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TValue>> expression, bool value)
    {
        string myId = // generate id...
        return htmlHelper.RadioButtonFor(expression, value, new {id=myId});
    }
}

Вспомогательный метод может использовать данные ViewContext и Model для создания более значимых идентификаторов.

UPDATE:

Если вы используете EditorTemplates для рендеринга элемента управления следующим образом

<%= Html.EditorFor(m=>m.User, "MyUserControl") %>

Затем внутри MyUserControl.ascx (помещается в ~ / Views / Shared / EditorTemplates) вы можете использовать свойство ViewData.TemplateInfo.HtmlFieldPrefix для доступа к идентификатору родительского элемента управления или Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId("MyPostfixPart") для создания идентификатора с префиксом. Эти методы могут быть использованы в расширении помощника выше. То же самое работает с элементами управления, отображаемыми с Html.Editor(...) и Html.EditorForModel(...). В помощнике Html.Editor вы также можете указать htmlFiledName вручную, если хотите.

Когда вы вставляете элемент управления с помощью

<%= Html.Partial("UserControl", Model.User) %>

генерация значимых идентификаторов сложнее, поскольку Html.Partial не будет предоставлять информацию о префиксе - ViewData.TemplateInfo.HtmlFieldPrefix всегда будет пустым. Тогда единственное решение состоит в том, чтобы передать префикс вручную в элемент управления ascx в качестве ключа ViewData в качестве поля модели, что не такое элегантное решение, как предыдущее.

0 голосов
/ 25 сентября 2015

Если вам нужен доступ к переключателям через jQuery, я обнаружил, что часто лучшее место для установки идентификаторов будет на странице, близкой к их предполагаемому использованию. Вот как я сделал то же самое:

@Html.Label(Resource.Question)
@Html.RadioButtonFor(m => m.Question, true, new {id = "QuestionYes"}) Yes
@Html.RadioButtonFor(m => m.Question, false, new {id = "QuestionNo"}) No

Тогда мой JQuery:

if ($("input[id='QuestionNo']").is(":checked")) {
        $('#YesOptionalBlock').removeClass('showDiv');
        $('#YesOptionalBlock').addClass('hideDiv');
}
...