2010-05-10 12 views
32

Parece que el defecto ASP.NET MVC2 HTML ayudante genera identificadores duplicados HTML al usar un código como éste (EditorTemplates/UserType.ascx):del botón de radio genera duplicado id-s HTML

<%@ 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) %> 

El HTML produce es:

<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" /> 

Eso muestra claramente un problema. Así que debo estar haciendo mal uso del Ayudante o algo así.

Puedo especificar manualmente el atributo id como html pero entonces no puedo garantizar que sea único.

Así que la pregunta es cómo asegúrese de que los ID generados por RadioButton ayudante son únicos para cada valor y aún conservan las convenciones para generar los identificadores (se respetan los modelos de manera anidados? (Preferiblemente no generar los ID manualmente .)

Respuesta

12

Me enfrenté al mismo problema. Specyfying IDs parece ser la única solución manualmente. Si no necesitas los identificadores para nada (como javascript), pero quieres que sea único, puedes generar Guids para ellos :

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

Una solución más elegante sería crear su propio método de extensión en HtmlHelper para separar la lógica de creación de ID de la vista. Algo así como:

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

El método de ayuda podría usar datos de ViewContext y de modelo para crear identificaciones más significativas.

ACTUALIZACIÓN:

Si utiliza EditorTemplates para representar el control como éste

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

A continuación, dentro de la MyUserControl.ascx (colocado en ~/Views/Shared/EditorTemplates) se puede utilizar ViewData.TemplateInfo.HtmlFieldPrefix propiedad para acceder al ID de control principal o Html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId("MyPostfixPart") para generar el ID prefijado. Estos métodos podrían usarse en la extensión auxiliar anterior. Lo mismo funciona con controles representados con Html.Editor(...) y Html.EditorForModel(...). En el helper Html.Editor también puede especificar htmlFiledName manualmente si lo desea.

Al incrustar el control con

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

generación de identificadores de meaningfull es más difícil debido a que el Html.Partial no proporcionará información sobre el prefijo - la ViewData.TemplateInfo.HtmlFieldPrefix habrá siempre vacía. Entonces, la única solución sería pasar el prefijo manualmente al control ascx en forma de una clave ViewData como un campo modelo que no es una solución tan elegante como la anterior.

+0

Tal vez también puede sugerir cómo generar identificadores teniendo en cuenta el nombre actual del modelo de manera que los identificadores se pueden generar correctamente y ¿Tiene IDs como: 'UserType_Primary',' Company_User_UserType_Primary' y más? –

+0

@Dmitriy: Acabo de actualizar mi respuesta. ViewData.TemplateInfo.HtmlFieldPrefix debería ayudarlo. – PanJanek

+0

Muchas gracias. Eso debería hacer el trabajo por mí. –

14

Además de la respuesta de PanJanek:
Si realmente no necesita los elementos a tener un id, también puede especificar id="" en los htmlAttributes (es decir new { id="" }) parámetro de ayudantes. Esto dará como resultado que el atributo id se omita por completo en el html generado.

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

0

Si necesita acceder a los botones de radio a través de jQuery, me parece que a menudo el mejor lugar para establecer el ID de estarán en la página, cerca de su uso previsto. Así es como yo hice lo mismo:

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

Entonces mi jQuery:

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