所以我有一个带有表格的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;
}
}
答案 0 :(得分:9)
将您的排序顺序放在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;
}
}
答案 1 :(得分: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局部视图返回到上面的索引视图中:
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 <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 <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">«</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">»</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
时,javascript点击事件$('#partial_Activity').on('click', '#log-dropdown-user-sort', function (e) {}
会触发并调用setSort(DOM element, string)
功能。
setSort()
函数设置传递元素的"sort"
属性,在'asc'
和'desc'
之间切换属性值,从而影响函数中的未来逻辑流,并返回连接字符串值,将用作sortOrder
GET方法中的GetActivity
参数,该方法将在下一个方法中调用。
然后GetActivity
GET方法查询并返回基于sortOrder
语句评估的switch
参数排序的数据。
答案 2 :(得分:0)
只需在您的.js文件中放置代码-“订单”:[[6,“ asc”]]。其中6代表列的placeNumber。例如1.id,2.name。等
答案 3 :(得分:0)
对于Razor页面,我只是在页面模型中添加了if-else语句以及“ CurrentSortDir”变量和“ ToggleSortDir”变量。
所以我的“ index.cshtml”:
<th>
<a asp-page="./Index"
asp-route-sortOrder="ManufacturerPN"
asp-route-sortDir = "@Model.ToggleSortDir">
@Html.DisplayNameFor(model => model.Inventory[0].ManufacturerPN)
</a>
</th>
还有我的index.cshtml.cs:
public string CurrentSortDir { get; set; }
public string ToggleSortDir {get; set; }
public async Task OnGetAsync(string sortOrder, string sortDir, string currentFilter, string searchString, int? pageIndex)
{
CurrentSort = sortOrder;
CurrentSortDir = sortDir;
if (CurrentSortDir == "DESC")
{
ToggleSortDir = "ASC";
switch (sortOrder)
{
case "ManufacturerPN":
Items = Items.OrderByDescending(s => s.ManufacturerPN);
break;
....
}
}
else
{
ToggleSortDir = "DESC";
switch (sortOrder)
{
case "ManufacturerPN":
Items = Items.OrderBy(s => s.ManufacturerPN);
break;
....
}
}
您最终将获得一个全局排序方向...但是我认为这还可以。否则,您将需要为每个列使用单独的var,然后在每种情况下都添加。