asp.net-mvc - for - radiobutton asp net mvc
Forma correcta de codificar un grupo de botones de radio utilizando RadioButtonFor (2)
En mi opinión, no creo que se haga nada por parte de Microsoft para manejar el caso del que está hablando.
comenzando desde el código Html, ¿cómo en html, se mostrarán los botones de radio múltiples?
<form action="">
<input type="radio" name="sex" value="male">Male<br>
<input type="radio" name="sex" value="female">Female
</form>
arriba hay una muestra que traje de W3cSchools ,
si desea alternar el botón de opción haciendo clic en la etiqueta, esto se puede hacer de dos maneras en html
La primera forma es usar la etiqueta for en la etiqueta
<input type="radio" id="myId" name="MyName" value="MyValue" />
<label for="myId">Display Name</label>
La segunda forma es colocar la entrada de la radio dentro de una etiqueta
<label>
<input type="radio" id="myId" name="MyName" value="MyValue"/>
Display Name
</label>
como puede ver, su combinación de etiquetas para hacer que el botón de radio se alterne al hacer clic en la etiqueta, Microsoft creo que lo mantuvo simple y flexible para que el desarrollador elija qué hacer y en la forma en que le gusta.
ahora, para obtener el mismo resultado en Mvc, ya sea que codifique cada botón de radio que tiene en uno de estos 2 métodos mencionados anteriormente, o para hacerlo más fácil, escriba su propia extensión Mvc Html, y recomiendo el segundo método.
Espero que esto te ayudará
Según mi investigación, la forma correcta de codificar una casilla de verificación en MVC es la siguiente.
@Html.CheckBoxFor(m => m.RememberMe)
@Html.LabelFor(m => m.RememberMe)
Esto generará una casilla de verificación, mostrará una etiqueta para la casilla de verificación y hará que la etiqueta se pueda hacer clic , lo que significa que al hacer clic en la etiqueta también se alterna la casilla de verificación.
Pero, ¿qué pasa con el caso donde hay múltiples casillas de verificación para un solo campo de modelo de vista? (Por ejemplo, tal vez cada casilla de verificación representa un bit dentro de un valor entero.) O, mejor aún, ¿qué pasa con los botones de opción, donde siempre hay varias opciones asociadas con el mismo campo?
En estos casos, parece haber problemas con el código anterior. O bien no todos los elementos se asociarían con el mismo campo, o se representarían múltiples elementos con la misma ID.
He estado investigando esto por un tiempo ahora. He encontrado muchas soluciones; sin embargo, parece que ninguno de ellos tiene una etiqueta en la que se puede hacer clic, o requieren un montón de codificación personalizada y / o no estándar. Algunos evitan por completo el uso de RadioButtonFor / LabelFor, eligiendo en su lugar codificar el HTML sin formato.
La codificación del HTML sin formato está bien, pero ¿los diseñadores de MVC no anticiparon que podríamos necesitar varios botones de opción para el mismo campo? Y, si lo hicieran, ¿cómo pensaban que fuera codificado?
EDITAR:
Después de investigar esto un poco más, el siguiente código es la mejor forma que he encontrado para codificar botones de radio. Este código supone que he definido una enumeración para cada una de mis opciones de radio.
@Html.RadioButtonFor(m => m.Gender, Gender.Male, new { id = "gender-male" })
@Html.LabelFor(m => m.Gender, Gender.Male.ToString(), new { @for = "gender-male" })
@Html.RadioButtonFor(m => m.Gender, Gender.Female, new { id = "gender-female" })
@Html.LabelFor(m => m.Gender, Gender.Female.ToString(), new { @for = "gender-female" })
Tal vez esto es lo mejor que puedo esperar, pero aún me preocupa un poco.
¿Por qué se requiere tanta personalización para cosas básicas como ID? Nuevamente, ¿Microsoft no anticipó que quisiéramos tener múltiples botones de radio asociados con el mismo campo?
si el nombre de la enumeración no es el mismo que la descripción que deseo para la etiqueta del botón de opción, este enfoque no parece ser compatible con los atributos de campo, como
[Display(Name = "")]
.
(Supongo que el manejo correcto de varias casillas de verificación se pospondrá a otra pregunta).
Ok, investiguemos. En primer lugar, no necesita una identificación única para alternar casilla de verificación / radio haciendo clic en una etiqueta. ¡De hecho, no necesitas identificación ! Todo lo que tienes que hacer es ajustar tu entrada dentro de la <label>
:
<label>
<input type="radio" name="radio" value="1" /> Radio 1
</label>
Hasta ahora todo bien, ASP.NET MVC le brinda la capacidad de codificar sus propios helpers html, ¡escribamos uno para el campo de modelos Enum
!
Imagínese, tenemos algún modelo de registro:
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
¡Maldita sea! Acabo de copiar el modelo tutorial pegado o_O. Lo que queremos ahora es obtener el género del usuario, así que agregamos una enumeración de Gender
:
public enum Gender
{
Iamparanoic = 0,
Male = 1,
Female = 2,
}
y agregue el campo Gender
tipo de Gender
a nuestro modelo (¡deseo, c # tuvo un modificador de acceso de Gender
!)
public Gender Gender { get; set; }
Ahora, es el momento de usar algo de magia asp.net y escribir nuestro helper html:
public static MvcHtmlString RadioButtonsListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
var sb = new StringBuilder();
sb.Append("<ul>"); //we want it to look cool, dont'' we?
foreach (var value in Enum.GetValues(typeof(TEnum)))
{
var radio = htmlHelper.RadioButtonFor(expression, value).ToHtmlString(); //you can generage any id and pass it to helper, or use a tagbuilder
sb.AppendFormat(
"<li><label>{0} {1}</label></li>",
radio,
((Enum)value).GetEnumName() //instead of it you can grab e.g. Display/Description attribute value or w/e else
);
}
sb.Append("</ul");
return MvcHtmlString.Create(sb.ToString());
}
y el uso de eso se verá así:
@Html.RadioButtonsListForEnum(m => m.Gender)
Tan lindo, ¿verdad? Por supuesto, puede agregar la gran cantidad de personalizaciones de Hella, como renderizar botones de radio con identificadores exclusivos de estilo mvc, todos los kindes de atributos html, etc., pero esto es solo una muestra, patada en el culo hacia la derecha.
A continuación, ¡también queremos presentar checkboxlist!
public static MvcHtmlString CheckBoxListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, IDictionary<string, object> htmlAttributes = null)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var enumValue = Convert.ToInt32(metadata.Model);
var sb = new StringBuilder();
foreach (var value in Enum.GetValues(typeof (TEnum)))
{
var val = Convert.ToInt32(value);
var checkbox = new TagBuilder("input");
checkbox.MergeAttribute("type", "checkbox");
checkbox.MergeAttribute("value", value.ToString());
checkbox.MergeAttribute("name", htmlHelper.NameFor(expression).ToString());
if ((enumValue & val) == val)
checkbox.MergeAttribute("checked", "checked");
if (htmlAttributes != null)
checkbox.MergeAttributes(htmlAttributes);
var label = new TagBuilder("label") { InnerHtml = checkbox + ((Enum)value).GetEnumName() };
sb.Append(label);
sb.Append("<br/>");
}
return new MvcHtmlString(sb.ToString());
}
Y de nuevo, uso simple:
@Html.CheckBoxListForEnum(m => m.Gender)
Por cierto, tiene sentido solo para las enumeraciones marcadas con el atributo Flags
, y por supuesto tendrá problemas con el enlace del modelo; requiere un encuadernado personalizado. Pero es otra pregunta, y espero que Jon Skeet pueda responderla :)