如何使用ASP.NET MVC中的复选框创建选择列表?

时间:2010-03-27 21:43:34

标签: asp.net-mvc data-binding asp.net-mvc-2 viewmodel

我有一个数据库表,记录了允许用户访问的出版物。该表非常简单 - 它只存储用户ID /发布ID对:

CREATE TABLE UserPublication (UserId INTEGER, PublicationID INTEGER)

存在给定用户的记录&发布意味着用户有权访问;没有记录意味着无法访问。

我想向管理员用户提供一个简单的屏幕,允许他们配置用户可以访问的出版物。我想为每个可能的出版物显示一个复选框,并检查用户当前可以访问的出版物。然后,管理员用户可以检查或取消检查任意数量的出版物并提交表格。

有各种各样的出版物类型,我想将类似类型的出版物组合在一起 - 所以我确实需要控制出版物的呈现方式(我不想只是有一个单一的列表)。

我的视图模型显然需要有一个所有出版物的列表(因为无论当前选择如何,我都需要显示它们),而且我还需要用户当前有权访问的出版物列表。 (我不确定我是否会更好地使用单个列表,其中每个项目包含发布ID和是/否字段?)。

但就我而言。我真的不知道如何将它绑定到一些复选框。我从哪里开始?

1 个答案:

答案 0 :(得分:19)

您的问题的Linq to SQL 模型看起来像这样:

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

首先,我们需要在数据模型中使用一些辅助对象

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

现在让我们创建一个如下所示的存储库

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

控制器,如下所示:

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

索引视图如下所示:

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

选择视图如下所示:

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

以下是一些屏幕截图。

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

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

左上角的复选框是全选/选择无复选框。