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

发布于 2024-09-01 02:42:04 字数 977 浏览 1 评论 0原文

当使用这样的代码(EditorTemplates/UserType.ascx)时,默认的 ASP.NET MVC2 Html 帮助程序似乎会生成重复的 HTML ID

<%@ 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 帮助程序生成的 ID 对于每个值都是唯一的,并且仍然保留生成这些 ID 的约定(因此嵌套模型受到尊重? (最好不要手动生成 ID。)

It seems that the default ASP.NET MVC2 Html helper generates duplicate HTML IDs when using code like this (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:

<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.

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.)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

随梦而飞# 2024-09-08 02:42:04

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

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

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.

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

浅唱ヾ落雨殇 2024-09-08 02:42:04

我遇到了同样的问题。手动指定 ID 似乎是唯一的解决方案。如果您不需要任何东西的 id(例如 javascript),但只希望它是唯一的,您可以为它们生成 Guid:

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

一个更优雅的解决方案是在 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});
    }
}

辅助方法可以使用 ViewContext 和模型数据来创建更有意义的 ID。

更新:

如果您使用 EditorTemplates 来呈现这样的控件

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

然后在 MyUserControl.ascx (放置在 ~/Views/Shared/EditorTemplates 中)内,您可以使用 ViewData.TemplateInfo.HtmlFieldPrefix 属性来访问父控件 ID 或 Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId("MyPostfixPart") 来生成前缀 id。这些方法可以在上面的帮助器扩展中使用。
对于使用 Html.Editor(...)Html.EditorForModel(...) 呈现的控件也是如此。如果需要,您还可以在 Html.Editor 帮助程序中手动指定 htmlFiledName。

当您嵌入控件并

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

生成有意义的 ID 时会更困难,因为 Html.Partial 不会提供有关前缀的信息 - ViewData.TemplateInfo.HtmlFieldPrefix 将始终为空。然后,唯一的解决方案是将前缀作为模型字段的 ViewData 键手动传递给 ascx 控件,这不像前一个解决方案那么优雅。

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:

<%: 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:

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.

UPDATE:

If you use EditorTemplates to render the control like this

<%= 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.

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.

南街女流氓 2024-09-08 02:42:04

如果您确实需要通过 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

然后我的 jQuery:

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

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:

@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:

if ($("input[id='QuestionNo']").is(":checked")) {
        $('#YesOptionalBlock').removeClass('showDiv');
        $('#YesOptionalBlock').addClass('hideDiv');
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文