单选按钮生成重复的HTML id-s

时间:2022-11-25 12:07:49

It seems that the default ASP.NET MVC2 Html helper generates duplicate HTML IDs when using code like this (EditorTemplates/UserType.ascx):

似乎是默认的ASP。当使用这样的代码时,NET MVC2 Html helper生成重复的Html id (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) %>

The HTML it produces is:

它产生的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" /> 

That clearly shows a problem. So I must be misusing the Helper or something.

这清楚地表明了一个问题。所以我一定是误用了助手什么的。

I can manually specify the id as html attribute but then I cannot guarantee it will be unique.

我可以手动指定id为html属性,但是我不能保证它是唯一的。

So the question is how to make sure that the IDs generated by RadioButton helper are unique for each value and still preserve the conventions for generating those IDs (so nested models are respected? (Preferably not generating IDs manually.)

所以问题是如何确保RadioButton helper生成的id对于每个值都是唯一的,并且仍然保留生成这些id的约定(因此嵌套模型是受尊重的?(最好不要手工生成id。)

3 个解决方案

#1


12  

I faced the same problem. Specyfying IDs manually seems to be the only solution. If you don't need the ids for anything (like javascript), but want it only to be unique you could generate Guids for them:

我也遇到了同样的问题。人工指定id似乎是唯一的解决方案。如果您不需要任何id(比如javascript),但是希望它是唯一的,您可以为它们生成gui:

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

A more elegant solution would be to create your own extension method on HtmlHelper to separate ID creation logic from the view. Something like:

更优雅的解决方案是在HtmlHelper上创建自己的扩展方法,以将ID创建逻辑与视图分离。喜欢的东西:

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});
    }
}

The helper method could use ViewContext and Model data to create more meaningfull IDs.

helper方法可以使用ViewContext和模型数据创建更有意义的id。

UPDATE:

更新:

If you use EditorTemplates to render the control like this

如果您使用editortemplate来像这样显示控件

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

Then inside the MyUserControl.ascx (placed in ~/Views/Shared/EditorTemplates) you can use ViewData.TemplateInfo.HtmlFieldPrefix property to access the parent control ID or Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId("MyPostfixPart") to generate prefixed id. Theese methods could be used in the helper extension above. The same works with controls rendered with Html.Editor(...) and Html.EditorForModel(...). In the Html.Editor helper you can also specify htmlFiledName manually if you want.

然后在MyUserControl。ascx(放在~/ view /Shared/ editortemplate中)可以使用ViewData.TemplateInfo。HtmlFieldPrefix属性访问父控件ID或Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(“MyPostfixPart”)来生成前缀ID,可以在上面的辅助扩展中使用Theese方法。使用Html.Editor(…)和Html.EditorForModel(…)呈现的控件也是如此。在Html。如果需要,还可以手动指定htmlFiledName。

When you embed the control with

当你嵌入控件时

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

generation of meaningfull IDs is harder because the Html.Partial will not provide information about the prefix - the ViewData.TemplateInfo.HtmlFieldPrefix will be always empty. Then, the only solution would be to pass the prefix manually to the ascx control in as ViewData key of as a model field which is not as elegant a solution as the previous one.

生成有意义的id比较困难,因为Html。分部将不会提供有关前缀——ViewData.TemplateInfo的信息。HtmlFieldPrefix将始终为空。然后,唯一的解决方案将是将前缀手工传递给ascx控件中的as模型字段的ViewData key,这并不像前面的解决方案那样优雅。

#2


14  

In addition to PanJanek's answer:
If you don't really need the elements to have an id, you can also specify id="" in the htmlAttributes (i.e. new { id="" }) parameter of helpers. This will result in the id attribute being left out completely in the generated html.

除了PanJanek的答案之外:如果您实际上不需要元素具有id,您还可以在helper的htmlAttributes(即new {id="})参数中指定id="" "。这将导致在生成的html中完全忽略id属性。

source: https://*.com/a/2398670/210336

来源:https://*.com/a/2398670/210336

#3


0  

If you do need to access the radio buttons via jQuery, I find that often the better place to set the id's will be on the page, close to their intended usage. This is how I did the same:

如果您确实需要通过jQuery访问单选按钮,我发现通常设置id的最佳位置是在页面上,接近它们的预期用途。我也是这样做的:

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

Then my jQuery:

然后我的jQuery:

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

#1


12  

I faced the same problem. Specyfying IDs manually seems to be the only solution. If you don't need the ids for anything (like javascript), but want it only to be unique you could generate Guids for them:

我也遇到了同样的问题。人工指定id似乎是唯一的解决方案。如果您不需要任何id(比如javascript),但是希望它是唯一的,您可以为它们生成gui:

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

A more elegant solution would be to create your own extension method on HtmlHelper to separate ID creation logic from the view. Something like:

更优雅的解决方案是在HtmlHelper上创建自己的扩展方法,以将ID创建逻辑与视图分离。喜欢的东西:

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});
    }
}

The helper method could use ViewContext and Model data to create more meaningfull IDs.

helper方法可以使用ViewContext和模型数据创建更有意义的id。

UPDATE:

更新:

If you use EditorTemplates to render the control like this

如果您使用editortemplate来像这样显示控件

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

Then inside the MyUserControl.ascx (placed in ~/Views/Shared/EditorTemplates) you can use ViewData.TemplateInfo.HtmlFieldPrefix property to access the parent control ID or Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId("MyPostfixPart") to generate prefixed id. Theese methods could be used in the helper extension above. The same works with controls rendered with Html.Editor(...) and Html.EditorForModel(...). In the Html.Editor helper you can also specify htmlFiledName manually if you want.

然后在MyUserControl。ascx(放在~/ view /Shared/ editortemplate中)可以使用ViewData.TemplateInfo。HtmlFieldPrefix属性访问父控件ID或Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(“MyPostfixPart”)来生成前缀ID,可以在上面的辅助扩展中使用Theese方法。使用Html.Editor(…)和Html.EditorForModel(…)呈现的控件也是如此。在Html。如果需要,还可以手动指定htmlFiledName。

When you embed the control with

当你嵌入控件时

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

generation of meaningfull IDs is harder because the Html.Partial will not provide information about the prefix - the ViewData.TemplateInfo.HtmlFieldPrefix will be always empty. Then, the only solution would be to pass the prefix manually to the ascx control in as ViewData key of as a model field which is not as elegant a solution as the previous one.

生成有意义的id比较困难,因为Html。分部将不会提供有关前缀——ViewData.TemplateInfo的信息。HtmlFieldPrefix将始终为空。然后,唯一的解决方案将是将前缀手工传递给ascx控件中的as模型字段的ViewData key,这并不像前面的解决方案那样优雅。

#2


14  

In addition to PanJanek's answer:
If you don't really need the elements to have an id, you can also specify id="" in the htmlAttributes (i.e. new { id="" }) parameter of helpers. This will result in the id attribute being left out completely in the generated html.

除了PanJanek的答案之外:如果您实际上不需要元素具有id,您还可以在helper的htmlAttributes(即new {id="})参数中指定id="" "。这将导致在生成的html中完全忽略id属性。

source: https://*.com/a/2398670/210336

来源:https://*.com/a/2398670/210336

#3


0  

If you do need to access the radio buttons via jQuery, I find that often the better place to set the id's will be on the page, close to their intended usage. This is how I did the same:

如果您确实需要通过jQuery访问单选按钮,我发现通常设置id的最佳位置是在页面上,接近它们的预期用途。我也是这样做的:

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

Then my jQuery:

然后我的jQuery:

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