web-dev-qa-db-ja.com

ラジオボタンは重複したHTMLIDを生成します

次のようなコード(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を生成しないでください。)

36

私も同じ問題に直面しました。 IDを手動で指定することが唯一の解決策のようです。 (javascriptなどの)何かのIDは必要ないが、一意にするだけにしたい場合は、それらの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およびModelデータを使用して、より意味のある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) %>
_

html.Partialはプレフィックスに関する情報を提供しないため、意味のあるIDの生成は難しくなります。_ViewData.TemplateInfo.HtmlFieldPrefix_は常に空になります。次に、唯一の解決策は、プレフィックスを手動でascxコントロールに渡し、モデルフィールドのViewDataキーとして、前のソリューションほど洗練されていないソリューションにすることです。

12
PanJanek

PanJanekの答えに加えて:
要素にIDを付ける必要が本当にない場合は、ヘルパーのhtmlAttributes(つまり、id="")パラメーターでnew { id="" }を指定することもできます。これにより、生成されたhtmlでid属性が完全に除外されます。

ソース: https://stackoverflow.com/a/2398670/210336

16

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');
}
0
Matthew