¿Cómo manejar casillas de verificación en formularios ASP.NET MVC?
Precaución: ¡Esta pregunta tiene más de nueve años!
Su mejor opción es buscar preguntas más nuevas o buscar las respuestas a continuación buscando su versión específica de MVC, ya que muchas respuestas aquí están obsoletas ahora.
Si encuentra una respuesta que funcione para su versión, asegúrese de que la respuesta contenga la versión de MVC que está utilizando.
(La pregunta original comienza a continuación)
Esto me parece un poco extraño, pero hasta donde sé, así es como se hace.
Tengo una colección de objetos y quiero que los usuarios seleccionen uno o más de ellos. Esto me dice "formulario con casillas de verificación". Mis objetos no tienen ningún concepto de "seleccionado" (son POCO rudimentarios formados al deserializar una llamada wcf). Entonces, hago lo siguiente:
public class SampleObject{
public Guid Id {get;set;}
public string Name {get;set;}
}
En la vista:
<%
using (Html.BeginForm())
{
%>
<%foreach (var o in ViewData.Model) {%>
<%=Html.CheckBox(o.Id)%> <%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
Y, en el controlador, esta es la única manera que puedo ver para averiguar qué objetos marcó el usuario:
public ActionResult ThisLooksWeird(FormCollection result)
{
var winnars = from x in result.AllKeys
where result[x] != "false"
select x;
// yadda
}
En primer lugar, es extraño y, en segundo lugar, para los elementos que el usuario marcó, FormCollection enumera su valor como "verdadero falso" en lugar de solo verdadero.
Obviamente me estoy perdiendo algo. Creo que esto se creó con la idea en mente de que los objetos de la colección sobre los que se actúa dentro del formulario html se actualizan UpdateModel()
mediante ModelBinder.
Pero mis objetos no están configurados para esto; ¿Eso significa que esta es la única manera? ¿Hay otra manera de hacerlo?
Html.CheckBox está haciendo algo extraño: si ve la fuente en la página resultante, verá que se <input type="hidden" />
genera un mensaje junto a cada casilla de verificación, lo que explica los valores "verdaderos falsos" que está viendo para cada elemento del formulario.
Pruebe esto, que definitivamente funciona en ASP.NET MVC Beta porque lo acabo de probar.
Pon esto en la vista en lugar de usar Html.CheckBox():
<% using (Html.BeginForm("ShowData", "Home")) { %>
<% foreach (var o in ViewData.Model) { %>
<input type="checkbox" name="selectedObjects" value="<%=o.Id%>">
<%= o.Name %>
<%}%>
<input type="submit" value="Submit" />
<%}%>
Todas sus casillas de verificación se llaman selectedObjects
, y el value
de cada casilla de verificación es el GUID del objeto correspondiente.
Luego publique en la siguiente acción del controlador (o algo similar que haga algo útil en lugar de Response.Write())
public ActionResult ShowData(Guid[] selectedObjects) {
foreach (Guid guid in selectedObjects) {
Response.Write(guid.ToString());
}
Response.End();
return (new EmptyResult());
}
Este ejemplo simplemente escribirá los GUID de las casillas que marcó; ASP.NET MVC asigna los valores GUID de las casillas de verificación seleccionadas al Guid[] selectedObjects
parámetro por usted e incluso analiza las cadenas de la colección Request.Form en objetos GUID instanciados, lo cual creo que es bastante bueno.
HtmlHelper agrega una entrada oculta para notificar al controlador sobre el estado Sin marcar. Entonces, para tener el estado verificado correcto:
bool bChecked = form[key].Contains("true");
En caso de que se pregunte POR QUÉ pusieron un campo oculto con el mismo nombre que la casilla de verificación, el motivo es el siguiente:
Comentario del código fuente MVCBetaSource\MVC\src\MvcFutures\Mvc\ ButtonsAndLinkExtensions.cs
Representa un adicional
<input type="hidden".../>
para las casillas de verificación. Esto soluciona escenarios en los que las casillas de verificación no marcadas no se envían en la solicitud. Enviar una entrada oculta permite saber que la casilla de verificación estaba presente en la página cuando se envió la solicitud.
Supongo que detrás de escena necesitan saber esto para vincular los parámetros en los métodos de acción del controlador. Supongo que entonces podría tener un booleano de tres estados (vinculado a un parámetro booleano que acepta valores NULL). No lo he probado pero espero que sea lo que hicieron.