2010-07-20 13 views
8

Tengo una clase llamada "PropertyFeature" que simplemente contiene PropertyFeatureID y descripción. Es un modelo adecuado creado a través de LINQ to SQL mapeado a una tabla de base de datos de SQL Server. Un ejemplo instancia/fila sería:Mantener el estado de una lista dinámica de casillas de verificación en ASP.NET MVC

PropertyFeatureID: 2 
Description: "Swimming Pool" 

el número de filas (PropertyFeatures) puede, por supuesto, aumentar y disminuir, y por eso quiero rendir dinámicamente una lista de casillas de verificación de manera que el usuario puede seleccionar cualquiera de ellos. puedo hacer dinámicamente las casillas de verificación con bastante facilidad, con algo como:

<%foreach (var Feature in (ViewData["Features"] as IEnumerable<MySolution.Models.PropertyFeature>)) { %> 
<%=Html.CheckBox("Features", new { @id = Feature.PropertyFeatureID, @value = Feature.PropertyFeatureID })%><label for="Feature<%=Feature.PropertyFeatureID%>"><%=Feature.Description%></label> 
<%}%> 

se especifica la ID de cada casilla y representar la etiqueta del juego de modo que el usuario puede hacer clic intuitivamente la etiqueta y cambiar la casilla de verificación - que funciona muy bien .

puse "nombre" de la casilla de verificación de "características" por lo que todas las casillas de verificación hacen con el mismo nombre, y el modelo MVC Carpeta les piles en una sola colección denominada "Características" cuando el formulario se ha publicado. Esto funciona bien

Una vez que se envía el formulario, utilizo los valores comprobados y los almaceno, por lo que necesito los valores enteros reales para saber qué propiedadFeature se selecciona, no solo una pila de booleanos y nombres de campo. Entonces, idealmente, lo quiero como una matriz o una colección con la que sea fácil trabajar.

Soy capaz de recuperar los valores seleccionados desde mi método de controlador cuando se hace clic en el botón porque he especificado el parámetro como int [] Características.

Pero el problema es que no mantiene el estado. Es decir, cuando hago clic en el botón de enviar y la página se vuelve a cargar (con el formulario nuevamente visualizado) quiero que todas las casillas de verificación dinámicas conserven su estado verificado (o no). Todos los otros campos que he creado con Html.DropDownList y Html.TextBox mantienen todos sus estados sin problemas en la misma página en la misma forma.

He pasado horas leyendo todos los otros hilos y artículos sobre temas similares y no hay mucho que hablar sobre el uso de ICollection y IDictionary para agrupar las cosas e incluir un valor booleano para cada elemento para que pueda mantener la casilla de verificación estado. Pero no entiendo al 100% cómo usar eso en el contexto de mi propio ejemplo personal. Me gustaría mantener la solución realmente simple y no tener que codificar páginas de nuevas clases solo para mantener el estado de mi casilla de verificación.

¿Cuál es la forma más limpia y adecuada de hacerlo?

+0

El problema es que al volver a representar la vista después de una publicación. La carpeta busca el valor publicado para la entrada denominada "Características". Como esto sería una matriz, me pregunto si eso solo funcionaría para el primer índice. ¿Puedes probar si la primera casilla de verificación puede mantener el estado? Si ese es el caso, es probable que tengas que buscar un enlace de lista un poco más complicado. – dotjoe

+0

Sí correcto. En realidad, creo que no funciona para nada, ni siquiera para la primera casilla de verificación. He jugado un poco más con el enfoque vinculante de la lista y parece mucho más prometedor. Pero todavía es un poco intrincado y no he podido bloquear la mejor solución hasta el momento. – Aaron

Respuesta

14

Lo tengo funcionando después de mucho jugar con los diferentes enfoques.

En la vista:

<%string[] PostFeatures = Request.Form.GetValues("Features");%> 
<% foreach (var Feature in (ViewData["AllPropertyFeatures"] as 
          IEnumerable<MySolution.Models.PropertyFeature>)) 
    { %> 
    <input type="checkbox" name="Features" 
     id="Feature<%=Feature.PropertyFeatureID.ToString()%>" 
     value="<%=Feature.PropertyFeatureID%>" 
     <%if(PostFeatures!=null) 
      { 
      if(PostFeatures.Contains(Feature.PropertyFeatureID.ToString())) 
      { 
       Response.Write("checked=\"checked\""); 
      } 
      } 
     %> /> 
    <label for="Feature<%=Feature.PropertyFeatureID%>"> 
      <%=Feature.Description%></label> <% 
    } %> 

En el método de controlador de recepción:

public ActionResult SearchResults(int[] Features) 

Este método tiene una serie de ventajas:

  • Permite etiquetas que se clickeado para alternar la correspondencia ding checkboxes (usabilidad).
  • Permite que el método del controlador reciba una matriz súper ordenada de entradas, que SOLAMENTE contiene las entradas que se han seleccionado, y no una pila entera de elementos que no se seleccionaron o contenían falso/nulo/en blanco/0 etc.
  • Conserva el estado marcado de la casilla cuando la página vuelve a cargar con el formulario, es decir, se retiene la selección del usuario.
  • No random/stray type = campos de entrada ocultos creados desde el ASP.Net MVC Html.CheckBox ayudante predeterminado - Sé que los hace por una buena razón, pero en este caso, no los necesito porque solo quiero para saber qué identificaciones se han seleccionado y para que estén en una sola, ordenar int [].
  • No se necesita una gran cantidad de clases adicionales hinchadas del lado del servidor, ayudantes y otros desordenados felices para lograr algo tan simple.

Recomendaría este enfoque a cualquiera que desee la solución más limpia y libre de burbujas para una lista de casillas dinámicas donde necesita los ID y ¡solo quiere ponerse a trabajar!

0

El problema es que cuando está renderizando su lista de casillas de verificación, no está configurando ninguna de ellas como seleccionada. Tendrá que configurar su int[] Features en ViewData, y luego en su bucle foreach, verifique si el ID de esa Característica está en la matriz en ViewData.

algo como:

<%=Html.CheckBox("Features", 
    ((int[])ViewData["SelectedFeatures"]).Contains(Feature.PropertyFeatureID), 
    new { @id = Feature.PropertyFeatureID, @value = Feature.PropertyFeatureID })% 

aunque no he probado, así que puede que no sea 100%.

+0

Gracias. Lo siento, para aclarar más. No necesito que se marquen las casillas de verificación inicialmente. Está solo en un formulario de búsqueda. Siempre deben estar en blanco, luego el usuario simplemente selecciona cuáles desean buscar. Pero luego quiero que esos seleccionados se retengan cuando la página se recarga. – Aaron

+0

derecha. la primera vez que se carga la página, su matriz SelectedFeatures estará vacía, por lo que no se marcarán las casillas de verificación. luego, en su devolución de datos, mostrará la matriz SelectedFeatures en ViewData, y se usará cuando se cargue la Vista. –

+0

Sí exactamente. Saludos por tu ayuda Dave. – Aaron

Cuestiones relacionadas