Как создать список выбора, используя флажки в ASP.NET MVC? - PullRequest
8 голосов
/ 28 марта 2010

У меня есть таблица базы данных, которая записывает, к каким публикациям пользователь имеет доступ. Таблица очень проста - она ​​просто хранит пары идентификаторов пользователей / идентификаторов публикаций:

CREATE TABLE UserPublication (UserId INTEGER, PublicationID INTEGER)

Наличие записи для данного пользователя и публикации означает, что пользователь имеет доступ; отсутствие записи означает отсутствие доступа.

Я хочу представить своим администраторам простой экран, который позволяет им настраивать, к каким публикациям пользователь может получить доступ. Я хотел бы показать один флажок для каждой из возможных публикаций и отметить те, к которым у пользователя есть доступ. Пользователь-администратор может затем проверить или отменить проверку любого количества публикаций и отправить форму.

Существуют различные типы публикаций, и я хочу сгруппировать публикации одинакового типа - поэтому мне нужен контроль над тем, как публикуются публикации (я не хочу просто иметь плоский список).

Моей модели представления, очевидно, нужен список всех публикаций (поскольку мне нужно отображать их все независимо от текущего выбора), а также мне нужен список публикаций, к которым у пользователя есть доступ. (Я не уверен, что мне лучше иметь один список, в котором каждый элемент содержит идентификатор публикации и поле "да / нет"?).

Но это насколько я могу. Я действительно не знаю, как связать это с некоторыми флажками. С чего начать?

1 Ответ

19 голосов
/ 29 марта 2010

Модель Linq to SQL для вашей проблемы выглядит примерно так:

альтернативный текст 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>

Вот несколько снимков экрана.

альтернативный текст http://i43.tinypic.com/2yl07kw.jpg

альтернативный текст http://i44.tinypic.com/mhulua.jpg

Флажок в верхнем левом углу: Флажок Выбрать все / Выбрать Нет .

...