2010-03-27 18 views
8

Tengo una tabla de base de datos que registra a qué publicaciones tiene acceso un usuario. La mesa es muy simple - es simplemente almacena pares de ID de usuario ID/publicación:¿Cómo creo una lista de selección usando casillas de verificación en ASP.NET MVC?

CREATE TABLE UserPublication (UserId INTEGER, PublicationID INTEGER) 

La presencia de un registro para un usuario dado significa & publicación que el usuario tiene acceso; la ausencia de un registro implica ningún acceso.

Quiero presentarles a mis usuarios administradores una pantalla simple que les permita configurar las publicaciones a las que puede acceder un usuario. Me gustaría mostrar una casilla de verificación para cada una de las publicaciones posibles y verificar las que el usuario puede acceder actualmente. El usuario administrador puede verificar o eliminar cualquier número de publicaciones y enviar el formulario.

Existen varios tipos de publicación, y quiero agrupar las publicaciones de tipo similar juntas, por lo que necesito control sobre cómo se presentan las publicaciones (no quiero simplemente tener una lista plana).

Mi modelo de vista obviamente necesita tener una lista de todas las publicaciones (ya que necesito mostrarlas independientemente de la selección actual), y también necesito una lista de las publicaciones a las que el usuario tiene acceso actualmente. (No estoy seguro de si estaría mejor con una lista única en la que cada elemento incluye el ID de publicación y un campo de sí/no?).

Pero eso es todo lo que tengo. Realmente no tengo idea de cómo enlazar esto con algunas casillas de verificación. ¿Dónde empiezo?

Respuesta

19

El LINQ a SQL modelo para su problema se ve algo como esto:

alt text http://i39.tinypic.com/m78d1y.jpg

En primer lugar, necesitamos objetos algunos ayudante en nuestro modelo de datos:

namespace SelectProject.Models 
{ 
    public class UserPublicationSelector 
    { 
     public int UserPublicationID { get; set; } 
     public int UserID { get; set; } 
     public int PublicationID { get; set; } 
     public string PublicationName { get; set; } 
     public bool IsSelected { get; set; } 
    } 

    public class UserPublicationSelectViewModel 
    { 
     public User User { get; set; } 
     public IQueryable Selections { get; set; } 
    } 
} 

Ahora creemos un repositorio que se ve así:

public class Repository 
{ 
    DataContext dc = new DataContext(); 

    public User GetUser(int userID) 
    { 
     return dc.Users.FirstOrDefault(u => u.UserID == userID); 
    } 

    public IQueryable GetUserPublications(int userID) 
    { 
     return from p in dc.Publications 
       join up in dc.UserPublications on p.PublicationID equals up.PublicationID 
       where up.UserID == userID 
       orderby p.PublicationName 
       select p; 
    } 
    public IQueryable GetUserPublicationSelectors(int userID) 
    { 
     return from p in dc.Publications 
       join up in dc.UserPublications on p.PublicationID equals up.PublicationID into selected 
       from s in selected.DefaultIfEmpty() 
       orderby p.PublicationName 
       select new UserPublicationSelector 
       { 
        UserPublicationID = (int?)s.UserPublicationID ?? 0, 
        UserID = userID, 
        PublicationID = p.PublicationID, 
        PublicationName = p.PublicationName, 
        IsSelected = s.UserID != null 
       }; 
    } 

    public void UpdateUserPublications(UserPublicationSelector[] selections) 
    { 
     // Insert records for new selections... 
     foreach (UserPublicationSelector selection in selections.Where(s => s.IsSelected == true)) 
     { 
      // ...where records do not yet exist in database. 
      if (selection.UserPublicationID == 0) 
      { 
       UserPublication up = new UserPublication 
       { 
        UserID = selection.UserID, 
        PublicationID = selection.PublicationID, 
       }; 
       dc.UserPublications.InsertOnSubmit(up); 
      } 
     } 
     // Delete records for unselected items... 
     foreach (UserPublicationSelector selection in selections.Where(s => s.IsSelected == false)) 
     { 
      // ...where record exists in database. 
      if (selection.UserPublicationID > 0) 
      { 
       UserPublication up = dc.UserPublications.FirstOrDefault(s => s.UserPublicationID == selection.UserPublicationID); 
       if (up.UserID == selection.UserID && up.PublicationID == selection.PublicationID) 
        dc.UserPublications.DeleteOnSubmit(up); 
      } 
     } 
     // Update the database 
     dc.SubmitChanges(); 
    } 
} 

Y un controlador que tiene este aspecto:

public class PublicationController : Controller 
{ 
    Repository repository = new Repository(); 

    public ActionResult Index(int id) 
    { 
     User user = repository.GetUser(id); 
     var publications = repository.GetUserPublications(id); 
     ViewData["UserName"] = user.UserName; 
     ViewData["UserID"] = user.UserID; 
     return View("Index", publications); 
    } 

    [AcceptVerbs(HttpVerbs.Get)] 
    public ActionResult Select(int id) 
    { 
     var viewModel = new UserPublicationSelectViewModel() 
     { 
      User = repository.GetUser(id), 
      Selections = repository.GetUserPublicationSelectors(id) 
     }; 
     return View("Select", viewModel); 
    } 

    [AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Select(int userID, UserPublicationSelector[] selections) 
    { 
     repository.UpdateUserPublications(selections); 
     return RedirectToAction("Index", new { id = userID }); 
    } 
} 

La vista Índice se ve así:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Publication>>" %> 
<%@ Import Namespace="SelectProject.Models" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    List of Selected Publications for User 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

    <h2>Publications for <%= ViewData["UserName"] %></h2> 

     <table id="MyTable" style="width: 100%"> 
      <thead> 
       <tr> 
        <th> 
         Publication Name 
        </th> 
       </tr> 
      </thead> 

      <tbody> 
       <% int i = 0; 
        foreach (Publication item in Model) 
        { %> 

        <tr id="row<%= i.ToString() %>"> 
         <td> 
          <%= Html.Encode(item.PublicationName)%> 
         </td> 
        </tr> 

        <% i++; 
        } %> 
      </tbody> 
     </table> 
     <p> 
      <%= Html.ActionLink("Edit Selections", "Select", new { id = ViewData["UserID"] })%> 
     </p> 

</asp:Content> 

Y el Seleccionar vista se parece a esto:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<UserPublicationSelectViewModel>" %> 
<%@ Import Namespace="SelectProject.Models" %> 

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server"> 
    Select Publications 
</asp:Content> 

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server"> 

    <h2>Select Publications for <%= Model.User.UserName %></h2> 

    <% using (Html.BeginForm()) 
     { %> 

     <table id="MyTable" style="width: 100%"> 
      <thead> 
       <tr> 
        <th style="width: 50px; text-align:center"> 
         <input type="checkbox" id="SelectAll" /> 
        </th> 
        <th> 
         Publication Name 
        </th> 
       </tr> 
      </thead> 

      <tbody> 
       <% int i = 0; 
        foreach (UserPublicationSelector item in Model.Selections) 
        { %> 

        <tr id="row<%= i.ToString() %>"> 
         <td align="center" style="padding: 0 0 0 0"> 
          <%= Html.CheckBox("selections[" + i.ToString() + "].IsSelected", item.IsSelected)%> 
          <%= Html.Hidden("selections[" + i.ToString() + "].UserPublicationID", item.UserPublicationID)%> 
          <%= Html.Hidden("selections[" + i.ToString() + "].UserID", Model.User.UserID)%> 
          <%= Html.Hidden("selections[" + i.ToString() + "].PublicationID", item.PublicationID)%> 
         </td> 
         <td> 
          <%= Html.Encode(item.PublicationName)%> 
         </td> 
        </tr> 

        <% i++; 
        } %> 
      </tbody> 
     </table> 
     <p> 
      <%= Html.Hidden("userID", Model.User.UserID) %> 
      <input type="submit" value="save" /> 
     </p> 

    <% } // End Form %> 

    <script src="../../Scripts/jquery-1.4.1.js" type="text/javascript"></script> 

    <script type="text/javascript"> 
     // Select All Checkboxes 
     $(document).ready(function() { 
      $('#SelectAll').click(function() { 
       var newValue = this.checked; 
       $('input:checkbox').not('input:hidden').each(function() { 
        this.checked = newValue; 
       }); 
      }); 
     }); 
    </script> 

</asp:Content> 

Aquí hay algunas capturas de pantalla .

alt text http://i43.tinypic.com/2yl07kw.jpg

alt text http://i44.tinypic.com/mhulua.jpg

La casilla de verificación en la esquina superior izquierda es una Seleccionar todo/Seleccionar Ninguno casilla.

+0

Awesome answer, gracias. Me siento un poco sucio, como si te pagara para hacer los deberes :-) –

+0

Hola Robert, ¡Excelente respuesta en profundidad! Gracias ... ¿Cómo puedo publicar de nuevo (guardar) Casillas con los valores seleccionados? – TonyP

+1

@TonyP: esa funcionalidad se encuentra en la vista Seleccionar, el método del controlador 'Seleccionar' con el valor del atributo 'AcceptVerbs HttpVerbs.Post' y el método del repositorio UpdateUserPublications, ilustrado anteriormente. –

Cuestiones relacionadas