Sort table rows sử dụng Drag & Drop trong ASP.NET Core MVC
Chúng ta thường tổ chức database có trường DisplayOrder hoặc SortOrder, và ta dùng nó một cách thủ công là tự gán giá trị 123456789 rồi sắp xếp tăng dần, giảm dần.
Ok, ở đây chúng ta không làm vậy, và hôm nay sẽ là một hướng dẫn cách sắp xếp giá trị bằng cách kéo thả đến vị trí mong muốn, sử dụng jQuery UI kết hợp Ajax trong ASP.NET Core MVC.
Tiến hành sử dụng Code First Migration
Thứ tự sắp xếp chúng ta sẽ lưu vào database nên việc trước tiên ta phải tạo thực thể và kết nối database.
Bước 1: Tạo project ASP.NET Core Web Application sử dụng MVC mới.
Bước 2: Cài đặt các NuGet Package sau:
- Microsoft.EntityFrameworkCore
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.EntityFrameworkCore.Tools
Bước 3: Cấu hình chuỗi kết nối tới SQL Server trong appsetting.json:
"ConnectionStrings": {
"ConnectionString": "Server=CNPM-PC\\SQLEXPRESS;Database=DbMenu;Trusted_Connection=True;MultipleActiveResultSets=true"
},
Bạn cần chú ý đến Server name và tên database để thay đổi cho phù hợp.
Bước 4: Tạo các lớp sau trong thư mục Models:
Menu.cs:
public class Menu
{
public int Id { get; set; }
public string Name { get; set; }
public int SortOrder { get; set; }
}
DataDbContext.cs:
public class DataDbContext : DbContext
{
public DataDbContext(DbContextOptions<DataDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// Đặt khóa chính
modelBuilder.Entity<Menu>().HasKey(s => s.Id);
}
public DbSet<Menu> Menus { get; set; }
}
Bước 5: Ta vào Startup.cs và tìm đến phương thức ConfigureServices() và thêm đoạn code sau bên trong:
services.AddDbContext<DataDbContext>(options =>
options.UseSqlServer(
Configuration.GetConnectionString("ConnectionString")));
Bước 6: Vào Tools > NuGet Package Manager > NuGet Package Console và thực thi lần lượt 2 command sau:
Bước 1: Tạo mới controller (empty) với tên là MenusController.cs với code sau:
[Route("home/menu")]
public class MenusController : Controller
{
private readonly DataDbContext _context;
public MenusController(DataDbContext context)
{
_context = context;
}
// GET: Menus
[HttpGet]
[Route("index")]
public async Task<IActionResult> Index()
{
return View(await _context.Menus.OrderBy(m => m.SortOrder).ToListAsync());
}
// POST: Menus
[HttpPost]
[Route("index")]
public ActionResult Index(int[] sortId)
{
int order = 1;
foreach (int id in sortId)
{
Menu menu = _context.Menus.Find(id);
menu.SortOrder = order;
_context.SaveChanges();
order += 1;
}
return View(_context.Menus.OrderBy(p => p.SortOrder).ToList());
}
[Route("order")]
public ActionResult UpdateItem(string itemIds)
{
int count = 1;
List<int> itemIdList = new List<int>();
itemIdList = itemIds.Split(",".ToArray(), StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();
foreach (var itemId in itemIdList)
{
try
{
var item = _context.Menus.Where(x => x.Id == itemId).FirstOrDefault();
item.SortOrder = count;
_context.Menus.Update(item);
_context.SaveChanges();
}
catch (Exception)
{
continue;
}
count++;
}
_context.SaveChanges();
return Json(itemIdList);
}
}
Ở đây, chúng ta sử dụng phương thức “UpdateItem” nhận tham số và tìm và sắp xếp theo danh sách và hiển thị ra view và cập nhật cơ sở dữ liệu.
Bước 2: Add view cho method Index trong Views/Menus/Index.cshtml với code sau:
Rebuild solution và xem kết quả.
@model IEnumerable<DragDropSort.Models.Menu>
@{
ViewData["Title"] = "Index";
}
@section Scripts {
<style>
tr:hover {
background: #fafafa;
}
</style>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script>
$(document).ready(function () {
$("#sortable").sortable({
update: function (event, ui) {
var itemIds = "";
$("#sortable").find(".orderLine").each(function () {
var itemId = $(this).attr("data-sortid");
itemIds = itemIds + itemId + ",";
});
$.ajax({
url: '/home/menu/order',
data: { itemIds: itemIds },
type: 'POST',
success: function (data) {
alert("sort: " + data);
},
error: function (xhr, status, error) {
}
});
}
})
})
</script>
}
<h1>Index</h1>
<p>
<a asp-action="Create">Create New</a>
</p>
<table class="table">
<thead>
<tr>
<th>
@Html.DisplayNameFor(model => model.Name)
</th>
<th>
@Html.DisplayNameFor(model => model.SortOrder)
</th>
<th></th>
</tr>
</thead>
<tbody id="sortable">
@foreach (var item in Model)
{
<tr>
<td class="orderLine" id="sort@(item.Id)" data-sortid="@(item.Id)">
@Html.DisplayFor(modelItem => item.Name)
</td>
<td>
@Html.DisplayFor(modelItem => item.SortOrder)
</td>
<td>
<a asp-action="Edit" asp-route-id="@item.Id">Edit</a> |
<a asp-action="Details" asp-route-id="@item.Id">Details</a> |
<a asp-action="Delete" asp-route-id="@item.Id">Delete</a>
</td>
</tr>
}
</tbody>
</table>
Rebuild solution và xem kết quả.
Cảm ơn admin nhiềuu
ReplyDelete