2015-11-19 2 views
4

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

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

Посмотреть

<table> 
    <tr> 
     <th> 
      <a href="@Url.Action("Dispatch", "Calls", new { userName = Session["UserName"], new { sortOrder = "Name_desc" })">Name</a> 
     </th> 
    </tr> 
</table> 

Контроллер

public ActionResult Index(string userName, string sortOrder) 
{ 
    string userName = Session["UserName"].ToString(); 

    var model = from t in db.Users 
       where t.UserName == userName 
       select t; 

    switch(sortOrder) 
    { 
     case "Name_desc": 
      model = model.OrderByDescending(t => t.UserName); 
      break; 
    } 
} 

ответ

7

Поместите свой порядок сортировки в значении ViewBag. Проверьте встроенные (Viewbag.NameSort):

Вид:

<th> 
    <a href="@Url.Action("Dispatch", "Calls", new { userName = Session["UserName"], new { sortOrder = ViewBag.NameSort })">Name</a> 
</th> 

Контроллер:

public ActionResult Index(string userName, string sortOrder) 
{ 
    string userName = Session["UserName"].ToString(); 

    // Convert sort order 
    ViewBag.NameSort = sortOrder == "Name" ? "Name_desc" : "Name"; 

    var model = from t in db.Users 
       where t.UserName == userName 
       select t; 

    switch(sortOrder) 
    { 
     case "Name_desc": 
      model = model.OrderByDescending(t => t.UserName); 
      break; 
     case "Name": 
      model = modelOrderBy(t => t.UserName); 
      break; 
    } 
} 
+0

Итак, для каждого дополнительного заголовка я бы создал новое значение ViewBag и добавил его в оператор switch? –

+0

Правильно, до сих пор все это использовалось в моих проектах и ​​работало как шарм. Надеюсь, это поможет вам встать на вашем пути. –

2

Я не хотел использовать значение ViewBag, так что я вместо этого использовал атрибуты скрытых элементов, чтобы сохранить отслеживать выбор сортировки пользователя.

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

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

Объяснение использования кода в нижней части сообщения.

Мой индексный указатель (где находятся скрытые элементы).Атрибут sort основной интерес здесь:

<div class="hidden"> 
    <span id="act-user-sort" sort=""></span> 
    <span id="act-type-sort" sort=""></span> 
    <span id="act-level-sort" sort=""></span> 
    <span id="act-date-sort" sort=""></span> 
</div> 
<section id="partial_Activity"> 
    @Html.Action("_Activity", "Home") 
</section> 

ActionResult «_Activity», который первоначально возвращает частичный вид _Activity в вышеприведенном зрения Index:

public ActionResult _Activity() 
{ 
    using (var context = new ApplicationDbContext()) 
    { 
     //create new LogModel object. this holds all that will be returned to the view 
     LogModel logModel = new LogModel(); 

     //create new LogSelect object. this is the list of drop downs for the activity log table. 
     LogSelect logSelect = new LogSelect(); 

     //query to get initial set 
     var result = from log in context.Logs 
        join user in context.Users on log.UserId equals user.Id into userlog 
        from user in userlog.DefaultIfEmpty() 
        orderby log.LogDate descending 
        select new Models.UserActivity { Log = log, User = user }; //this could bring back null user objects 

     //populate items for drop down lists 
     logSelect.LogUsers = result.Select(u => new LogUser { Name = u.User.FirstName + " " + u.User.LastName, Id = u.User.Id }).Distinct().ToList(); 
     logSelect.LogTypes = result.Select(t => t.Log.Type).Distinct().ToList(); 
     logSelect.LogLevels = result.Select(t => t.Log.Level).Distinct().ToList(); 

     //initial page for pagination is 1, default page size is 10. 
     int pageIndex = 1; 
     int pageSize = 10; 

     //return view with paginated list. 
     PaginatedList<UserActivity> pgList = PaginatedList<UserActivity>.Create(result.AsNoTracking(), pageIndex, pageSize); 

     //fill view model. 
     logModel.LogSelect = logSelect; 
     logModel.UserActivity = pgList; 

     return PartialView(logModel); 
    } 
} 

Мои «_Activity» Действие Частичный вид внутренностей (где кнопки таблицы и сортировок проживают):

@model Utils.Models.LogModel 
<style> 
... 
</style> 
<div> 
    <h3>Recent Activity</h3> 
</div> 
<div style="height:20px"></div> 
@* the panel class rounds the corners of the table *@ 
<div class="panel panel-default table-responsive" style="font-size:.9em;"> 
    <table id="log-table" class="table table-striped table-bordered table-hover log-table" style="width:100%;"> 
     <thead> 
      <tr class="bg-primary"> 
       <th class="dropdown log-dropdown"> 
        <a href="#" data-toggle="dropdown" class="dropdown-toggle">User&nbsp;&nbsp;<b class="caret"></b></a> 
        <div class="log-dropdown-sort log-dropdown-sort-init"> 
         <a sort="" href="#" id="log-dropdown-user-sort"><img src="~/Images/ui/alpha-sort-white.png" /></a> 
        </div> 
        <ul id="log-dropdown-user" class="dropdown-menu log-dropdown"> 
         @foreach (var user in Model.LogSelect.LogUsers) 
         { 
          <li><a id="log-user" href="#">@user.Name</a><span id="log-user-id" class="hidden">@user.Id</span></li> 
         } 
        </ul> 
       </th> 
       <th>Action</th> 
       <th class="dropdown log-dropdown"> 
        <a href="#" data-toggle="dropdown" class="dropdown-toggle">Type&nbsp;&nbsp;<b class="caret"></b></a> 
        <div class="log-dropdown-sort log-dropdown-sort-init"> 
         <a sort="" href="#" id="log-dropdown-type-sort"><img src="~/Images/ui/alpha-sort-white.png" /></a> 
        </div> 
        <ul id="log-dropdown-type" class="dropdown-menu"> 
         @foreach (var log in Model.LogSelect.LogTypes) 
         { 
          <li><a id="log-type" href="#">@log</a><span class="hidden">@log</span></li> 
         } 
        </ul> 
       </th> 
       <th class="log-dropdown"> 
        Date 
        <div class="log-dropdown-sort log-dropdown-sort-init"> 
         <a sort="" href="#" id="log-dropdown-date-sort"><img src="~/Images/ui/alpha-sort-white.png" /></a> 
        </div> 
        <div class="log-dropdown-date log-dropdown-date-init"> 
         <a href="#" id="log-dropdown-date-range"><img src="~/Images/ui/calendar-white.png" /></a> 
        </div> 
       </th> 
      </tr> 
     </thead> 
     <tbody> 

      @foreach (var log in Model.UserActivity) 
      { 
       <tr> 
        <td>@log.User.FirstName @log.User.LastName</td> 
        <td class="log-message">@log.Log.Message</td> 
        <td>@log.Log.Type</td> 
        <td class="log-date">@log.Log.LogDate</td> 
       </tr> 
      } 
     </tbody> 
    </table> 

</div> 
<div> 
    <ul class="pagination"> 
     <li> 
      <a href="#" aria-label="Previous"> 
       <span aria-hidden="true">&laquo;</span> 
      </a> 
     </li> 
     @for (int pg = 1; pg <= Model.UserActivity.TotalPages; pg++) 
     { 
      if (pg == Model.UserActivity.PageIndex) 
      { 
       <li class="active"><a href="#">@pg</a></li> 
      } 
      else 
      { 
       <li><a href="#">@pg</a></li> 
      } 
     } 
     <li> 
      <a href="#" aria-label="Next"> 
       <span aria-hidden="true">&raquo;</span> 
      </a> 
     </li> 
    </ul> 
</div> 

Jquery для обработки событий:

/********************************************************************************************** 
_Activity.cshtml 

/*********************************************************************************************/ 

//activity log sort buttons. 
$('#partial_Activity').on('click', '#log-dropdown-user-sort', function (e) { 
    e.preventDefault(); 
    var data = {}; 
    data.sortOrder = setSort($("#act-user-sort"), "user"); 
    GetActivity(data); 
}); 

$('#partial_Activity').on('click', '#log-dropdown-type-sort', function (e) { 
    e.preventDefault(); 
    var data = {}; 
    data.sortOrder = setSort($("#act-type-sort"), "type"); 
    GetActivity(data); 
}); 

$('#partial_Activity').on('click', '#log-dropdown-level-sort', function (e) { 
    e.preventDefault(); 
    var data = {}; 
    data.sortOrder = setSort($("#act-level-sort"), "level"); 
    GetActivity(data); 
}); 

$('#partial_Activity').on('click', '#log-dropdown-date-sort', function (e) { 
    e.preventDefault(); 
    var data = {}; 
    data.sortOrder = setSort($("#act-date-sort"), "date"); 
    GetActivity(data); 
}); 


//this function checks and sets the "sort" attribute of the passed element. 
//then based on setting of the "sort" attribute, returns a string value that will be used by code-behind to sort values in the table. 
function setSort(element, sort) { 

    if (element.attr("sort") == "") { 
     element.attr("sort", "asc"); 
     sort = sort + "_asc"; 
    } 
    else { 
     if (element.attr("sort") == "asc") { 
      element.attr("sort", "desc") 
      sort = sort + "_desc"; 
     } 
     else { 
      element.attr("sort", "asc") 
      sort = sort + "_asc"; 
     } 
    } 
    return sort; 
} 

function GetActivity(options) { 
    $.ajax({ 
     cache: false, 
     type: "GET", 
     url: "../Home/GetActivity", 
     data: options, 
     contentType: "application/json; charset=utf-8", 
     success: function (obj) { 
      $("#partial_Activity").html(obj); 
     } 
    }).done(function() { 
    }); 
} 

метод GET, который возвращает частичное представление, когда пользователь нажимает на кнопку сортировки:

[HttpGet] 
public PartialViewResult GetActivity(
    string sortOrder, 
    string userFilter, 
    string typeFilter, 
    string levelFilter, 
    DateTime? startDate, 
    DateTime? endDate, 
    int pageIndex = 1, 
    int pageSize = 10) 
{ 

    using (var context = new ApplicationDbContext()) 
    { 
     //create new LogModel object. this holds all that will be returned to the view 
     LogModel logModel = new LogModel(); 

     //create new LogSelect object. this is the list of drop downs for the activity log table. 
     LogSelect logSelect = new LogSelect(); 

     //query 
     var result = from log in context.Logs 
        join user in context.Users on log.UserId equals user.Id into userlog 
        from user in userlog.DefaultIfEmpty() 
        orderby log.LogDate descending 
        select new Models.UserActivity { Log = log, User = user }; //this could bring back null user objects. 

     //populate items for drop down lists 
     logSelect.LogUsers = result.Select(u => new LogUser { Name = u.User.FirstName + " " + u.User.LastName, Id = u.User.Id }).Distinct().ToList(); 
     logSelect.LogTypes = result.Select(t => t.Log.Type).Distinct().ToList(); 
     logSelect.LogLevels = result.Select(t => t.Log.Level).Distinct().ToList(); 

     //filters 
     if (!String.IsNullOrEmpty(userFilter)) { result = result.Where(r => r.User.UserName.Equals(userFilter)); } 
     if (!String.IsNullOrEmpty(typeFilter)) { result = result.Where(r => r.Log.Type.Equals(typeFilter)); } 
     if (!String.IsNullOrEmpty(levelFilter)) { result = result.Where(r => r.Log.Level.Equals(levelFilter)); } 
     if (startDate.HasValue) { result = result.Where(r => r.Log.LogDate >= startDate); } 
     if (endDate.HasValue) { result = result.Where(r => r.Log.LogDate <= endDate); } 

      //always default sorting by date desc 
      result = result.OrderByDescending(r => r.Log.LogDate); 

      //sorting (any selection other than date sorting will be sorted secondarily by date descending) 
      switch (sortOrder) 
      { 
       case "date_asc": 
        result = result.OrderBy(r => r.Log.LogDate); 
        break; 
       case "date_desc": 
        result = result.OrderByDescending(r => r.Log.LogDate); 
        break; 
       case "user_asc": 
        result = result.OrderBy(r => r.User.FirstName) 
            .ThenByDescending(r => r.Log.LogDate); 
        break; 
       case "user_desc": 
        result = result.OrderByDescending(r => r.User.FirstName) 
            .ThenByDescending(r => r.Log.LogDate); 
        break; 
       case "type_asc": 
        result = result.OrderBy(r => r.Log.Type) 
            .ThenByDescending(r => r.Log.LogDate); 
        break; 
       case "type_desc": 
        result = result.OrderByDescending(r => r.Log.Type) 
            .ThenByDescending(r => r.Log.LogDate); 
        break; 
       case "level_asc": 
        result = result.OrderBy(r => r.Log.Level) 
            .ThenByDescending(r => r.Log.LogDate); 
        break; 
       case "level_desc": 
        result = result.OrderByDescending(r => r.Log.Level) 
            .ThenByDescending(r => r.Log.LogDate); 
        break; 
       default: 
        break; 
      } 

     //turn result into paginated list 
     PaginatedList<UserActivity> pgList = PaginatedList<UserActivity>.Create(result.AsNoTracking(), pageIndex, pageSize); 

     //fill view model. 
     logModel.LogSelect = logSelect; 
     logModel.UserActivity = pgList; 

     //return model to the view 
     return PartialView("_Activity", logModel); 
    } 
} 

Пояснение:

При нажатии <a id="log-dropdown-user-sort"><img.../></a> в частичном виде _Activity, в яваскрипта нажмите событие $('#partial_Activity').on('click', '#log-dropdown-user-sort', function (e) {} срабатывает и вызывает функцию setSort(DOM element, string).

setSort() функция устанавливает атрибут переданного элемента "sort", переключая значение атрибута между 'asc' и 'desc', таким образом, влиять на будущее логического потока в пределах функции, и возвращает сцепленное строковое значение, которое будет использоваться в качестве параметра sortOrder в GetActivity GET, который называется следующим.

Метод GetActivity GET затем, разумеется, запрашивает и возвращает данные, отсортированные по аргументу sortOrder, вычисленному по инструкции switch.

Смежные вопросы