Your search did not match any results.

Data Grid - Drag & Drop Between Two Grids

This functionality requires that data objects have a data field that identifies which grid they belong to. In this demo, this data field is Status.

Backend API
<div class="tables"> <div class="column"> @await Html.PartialAsync("DnDBetweenGridsPartial", 1) </div> <div class="column"> @await Html.PartialAsync("DnDBetweenGridsPartial", 2) </div> </div> <script> function onAdd(e) { var store1 = $("#grid1").dxDataGrid("instance").getDataSource().store(), store2 = $("#grid2").dxDataGrid("instance").getDataSource().store(), values = { Status: e.toData }, key = e.itemData.ID; store1.update(key, values).then(() => { var changes = [{ type: "update", key: key, data: values }]; store1.push(changes); store2.push(changes); }); } </script> <script src="~/data/priorities.js"></script>
@model int @(Html.DevExtreme().DataGrid<DevExtreme.NETCore.Demos.Models.RowReorderingTask>() .ID("grid" + @Model) .ElementAttr("class", "grid") .Height(440) .DataSource(d => d.Mvc() .Controller("DnDBetweenGrids") .Key("ID") .LoadAction("Tasks") .UpdateAction("UpdateTask") ) .DataSourceOptions(o => o.ReshapeOnPush(true).Filter(new object[]{"Status", "=", @Model})) .RowDragging(rd => rd .Group("tasksGroup") .Option("data", @Model) .OnAdd("onAdd") ) .Scrolling(scrolling => scrolling.Mode(GridScrollingMode.Virtual)) .ShowBorders(true) .Columns(columns => { columns.AddFor(m => m.Subject); columns.AddFor(m => m.Priority) .Width(80) .Lookup(lookup => lookup .DataSource(new JS("priorities")) .ValueExpr("id") .DisplayExpr("text") ); columns.AddFor(m => m.Status) .Visible(false); }) )
using DevExtreme.NETCore.Demos.Models; using DevExtreme.NETCore.Demos.Models.DataGrid; using DevExtreme.NETCore.Demos.Models.SampleData; using Microsoft.AspNetCore.Mvc; using System.Linq; namespace DevExtreme.NETCore.Demos.Controllers { public class DataGridController : Controller { public ActionResult DnDBetweenGrids() { return View(); } } }
using DevExtreme.AspNet.Data; using DevExtreme.AspNet.Mvc; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Caching.Memory; using Newtonsoft.Json; using System.Linq; using DevExtreme.NETCore.Demos.Models.SampleData; using DevExtreme.NETCore.Demos.Models; using DevExtreme.NETCore.Demos.Models.DataGrid; namespace DevExtreme.NETCore.Demos.Controllers.ApiControllers { [Route("api/[controller]/[action]")] public class DnDBetweenGridsController : Controller { InMemoryRowReorderingTasksDataContext _context; public DnDBetweenGridsController(IHttpContextAccessor httpContextAccessor, IMemoryCache memoryCache) { _context = new InMemoryRowReorderingTasksDataContext(httpContextAccessor, memoryCache); } [HttpGet] public object Tasks(DataSourceLoadOptions loadOptions) { return DataSourceLoader.Load(_context.Tasks.Where(task => task.Status < 3).Take(10).ToList<RowReorderingTask>(), loadOptions); } [HttpPut] public IActionResult UpdateTask(int key, string values) { var order = _context.Tasks.First(o => o.ID == key); JsonConvert.PopulateObject(values, order); if(!TryValidateModel(order)) return BadRequest(ModelState.GetFullErrorMessage()); _context.SaveChanges(); return Ok(order); } } }
using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Caching.Memory; using System; using System.Collections.Generic; using DevExtreme.NETCore.Demos.Models; namespace DevExtreme.NETCore.Demos.Models.DataGrid { public class InMemoryRowReorderingTasksDataContext : InMemoryDataContext<RowReorderingTask> { public InMemoryRowReorderingTasksDataContext(IHttpContextAccessor contextAccessor, IMemoryCache memoryCache) : base(contextAccessor, memoryCache) { } public ICollection<RowReorderingTask> Tasks => ItemsInternal; protected override IEnumerable<RowReorderingTask> Source => SampleData.SampleData.RowReorderingTasks; protected override int GetKey(RowReorderingTask item) => item.ID; protected override void SetKey(RowReorderingTask item, int key) => item.ID = key; } }
var priorities = [{ id: 1, text: "Low" }, { id: 2, text: "Normal" }, { id: 3, text: "High" }, { id: 4, text: "Urgent" }];
using System.ComponentModel.DataAnnotations; namespace DevExtreme.NETCore.Demos.Models { public class RowReorderingTask { public int ID { set; get; } [Required] public string Subject { set; get; } [Required] public int Status { set; get; } [Required] public int Owner { set; get; } [Required] public int AssignedEmployee { get; set; } public int OrderIndex { get; set; } public int Priority { get; set; } } }
using System; using System.Collections.Generic; namespace DevExtreme.NETCore.Demos.Models.SampleData { public partial class SampleData { public static readonly IEnumerable<RowReorderingTask> RowReorderingTasks = new[] { new RowReorderingTask { ID = 1, Subject = "Prepare 2013 Financial", Status = 5, Owner = 1, AssignedEmployee = 7, OrderIndex = 0, Priority = 3 }, new RowReorderingTask { ID = 2, Subject = "Prepare 2013 Marketing Plan", Status = 5, Owner = 1, AssignedEmployee = 4, OrderIndex = 1, Priority = 4 }, new RowReorderingTask { ID = 3, Subject = "Update Personnel Files", Status = 5, Owner = 1, AssignedEmployee = 2, OrderIndex = 2, Priority = 1 }, new RowReorderingTask { ID = 4, Subject = "Review Health Insurance Options Under the Affordable Care Act", Status = 1, Owner = 1, AssignedEmployee = 2, OrderIndex = 3, Priority = 4 }, new RowReorderingTask { ID = 5, Subject = "Choose between PPO and HMO Health Plan", Status = 4, Owner = 2, AssignedEmployee = 1, OrderIndex = 4, Priority = 3 }, new RowReorderingTask { ID = 6, Subject = "Google AdWords Strategy", Status = 1, Owner = 4, AssignedEmployee = 1, OrderIndex = 5, Priority = 2 }, new RowReorderingTask { ID = 7, Subject = "New Brochures", Status = 1, Owner = 4, AssignedEmployee = 1, OrderIndex = 6, Priority = 1 }, new RowReorderingTask { ID = 8, Subject = "2013 Brochure Designs", Status = 1, Owner = 1, AssignedEmployee = 28, OrderIndex = 7, Priority = 1 }, new RowReorderingTask { ID = 9, Subject = "Brochure Design Review", Status = 1, Owner = 28, AssignedEmployee = 29, OrderIndex = 8, Priority = 1 }, new RowReorderingTask { ID = 10, Subject = "Website Re-Design Plan", Status = 5, Owner = 28, AssignedEmployee = 29, OrderIndex = 9, Priority = 2 }, new RowReorderingTask { ID = 11, Subject = "Rollout of New Website and Marketing Brochures", Status = 5, Owner = 1, AssignedEmployee = 4, OrderIndex = 10, Priority = 2 }, new RowReorderingTask { ID = 12, Subject = "Update Sales Strategy Documents", Status = 5, Owner = 4, AssignedEmployee = 8, OrderIndex = 11, Priority = 2 }, new RowReorderingTask { ID = 13, Subject = "Create 2012 Sales Report", Status = 5, Owner = 8, AssignedEmployee = 41, OrderIndex = 12, Priority = 4 }, new RowReorderingTask { ID = 14, Subject = "Direct vs Online Sales Comparison Report", Status = 5, Owner = 41, AssignedEmployee = 42, OrderIndex = 13, Priority = 3 }, new RowReorderingTask { ID = 15, Subject = "Review 2012 Sales Report and Approve 2013 Plans", Status = 5, Owner = 41, AssignedEmployee = 4, OrderIndex = 14, Priority = 3 }, new RowReorderingTask { ID = 16, Subject = "Deliver R&D Plans for 2013", Status = 2, Owner = 1, AssignedEmployee = 3, OrderIndex = 15, Priority = 2 }, new RowReorderingTask { ID = 17, Subject = "Create 2013 R&D Plans", Status = 5, Owner = 3, AssignedEmployee = 32, OrderIndex = 16, Priority = 0 }, new RowReorderingTask { ID = 18, Subject = "2013 QA Strategy Report", Status = 5, Owner = 32, AssignedEmployee = 33, OrderIndex = 17, Priority = 0 }, new RowReorderingTask { ID = 19, Subject = "2013 Training Events", Status = 5, Owner = 33, AssignedEmployee = 31, OrderIndex = 18, Priority = 0 }, new RowReorderingTask { ID = 20, Subject = "Approve Hiring of John Jeffers", Status = 5, Owner = 31, AssignedEmployee = 5, OrderIndex = 19, Priority = 0 }, new RowReorderingTask { ID = 21, Subject = "Non-Compete Agreements", Status = 5, Owner = 5, AssignedEmployee = 2, OrderIndex = 20, Priority = 0 }, new RowReorderingTask { ID = 22, Subject = "Update NDA Agreement", Status = 5, Owner = 2, AssignedEmployee = 1, OrderIndex = 21, Priority = 0 }, new RowReorderingTask { ID = 23, Subject = "Update Employee Files with New NDA", Status = 1, Owner = 2, AssignedEmployee = 5, OrderIndex = 22, Priority = 3 }, new RowReorderingTask { ID = 24, Subject = "Sign Updated NDA", Status = 5, Owner = 5, AssignedEmployee = 6, OrderIndex = 23, Priority = 0 }, new RowReorderingTask { ID = 25, Subject = "Sign Updated NDA", Status = 5, Owner = 5, AssignedEmployee = 7, OrderIndex = 24, Priority = 0 }, new RowReorderingTask { ID = 26, Subject = "Sign Updated NDA", Status = 1, Owner = 5, AssignedEmployee = 8, OrderIndex = 25, Priority = 1 }, new RowReorderingTask { ID = 27, Subject = "Sign Updated NDA", Status = 4, Owner = 5, AssignedEmployee = 9, OrderIndex = 26, Priority = 0 }, new RowReorderingTask { ID = 28, Subject = "Submit Questions Regarding New NDA", Status = 1, Owner = 9, AssignedEmployee = 17, OrderIndex = 27, Priority = 1 }, new RowReorderingTask { ID = 29, Subject = "Submit Questions Regarding New NDA", Status = 1, Owner = 9, AssignedEmployee = 18, OrderIndex = 28, Priority = 1 }, new RowReorderingTask { ID = 30, Subject = "Submit Questions Regarding New NDA", Status = 4, Owner = 9, AssignedEmployee = 19, OrderIndex = 29, Priority = 0 }, new RowReorderingTask { ID = 31, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = 14, OrderIndex = 30, Priority = 0 }, new RowReorderingTask { ID = 32, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = 13, OrderIndex = 31, Priority = 0 }, new RowReorderingTask { ID = 33, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = 15, OrderIndex = 32, Priority = 0 }, new RowReorderingTask { ID = 34, Subject = "Submit Signed NDA", Status = 5, Owner = 10, AssignedEmployee = 16, OrderIndex = 33, Priority = 0 }, new RowReorderingTask { ID = 35, Subject = "Update Revenue Projections", Status = 5, Owner = 1, AssignedEmployee = 7, OrderIndex = 34, Priority = 0 }, new RowReorderingTask { ID = 36, Subject = "Review Revenue Projections", Status = 5, Owner = 7, AssignedEmployee = 8, OrderIndex = 35, Priority = 0 }, new RowReorderingTask { ID = 37, Subject = "Comment on Revenue Projections", Status = 5, Owner = 7, AssignedEmployee = 41, OrderIndex = 36, Priority = 0 }, new RowReorderingTask { ID = 38, Subject = "Comment on Revenue Projections", Status = 5, Owner = 7, AssignedEmployee = 42, OrderIndex = 37, Priority = 0 }, new RowReorderingTask { ID = 39, Subject = "Comment on Revenue Projections", Status = 1, Owner = 7, AssignedEmployee = 45, OrderIndex = 38, Priority = 2 }, new RowReorderingTask { ID = 40, Subject = "Provide New Health Insurance Docs", Status = 5, Owner = 11, AssignedEmployee = 5, OrderIndex = 39, Priority = 0 }, new RowReorderingTask { ID = 41, Subject = "Review Changes to Health Insurance Coverage", Status = 5, Owner = 11, AssignedEmployee = 10, OrderIndex = 40, Priority = 0 }, new RowReorderingTask { ID = 42, Subject = "Scan Health Insurance Forms", Status = 5, Owner = 10, AssignedEmployee = 14, OrderIndex = 41, Priority = 0 }, new RowReorderingTask { ID = 43, Subject = "Sign Health Insurance Forms", Status = 5, Owner = 14, AssignedEmployee = 15, OrderIndex = 42, Priority = 0 }, new RowReorderingTask { ID = 44, Subject = "Sign Health Insurance Forms", Status = 5, Owner = 14, AssignedEmployee = 13, OrderIndex = 43, Priority = 0 }, new RowReorderingTask { ID = 45, Subject = "Sign Health Insurance Forms", Status = 3, Owner = 14, AssignedEmployee = 16, OrderIndex = 44, Priority = 0 }, new RowReorderingTask { ID = 46, Subject = "Follow up with West Coast Stores", Status = 1, Owner = 9, AssignedEmployee = 18, OrderIndex = 45, Priority = 3 }, new RowReorderingTask { ID = 47, Subject = "Follow up with East Coast Stores", Status = 1, Owner = 9, AssignedEmployee = 17, OrderIndex = 46, Priority = 3 }, new RowReorderingTask { ID = 48, Subject = "Send Email to Customers about Recall", Status = 5, Owner = 9, AssignedEmployee = 19, OrderIndex = 47, Priority = 0 }, new RowReorderingTask { ID = 49, Subject = "Submit Refund Report for 2013 Recall", Status = 5, Owner = 7, AssignedEmployee = 9, OrderIndex = 48, Priority = 0 }, new RowReorderingTask { ID = 50, Subject = "Give Final Approval for Refunds", Status = 5, Owner = 7, AssignedEmployee = 2, OrderIndex = 49, Priority = 0 }, new RowReorderingTask { ID = 51, Subject = "Prepare Product Recall Report", Status = 5, Owner = 3, AssignedEmployee = 32, OrderIndex = 50, Priority = 0 }, new RowReorderingTask { ID = 52, Subject = "Review Product Recall Report by Engineering Team", Status = 5, Owner = 3, AssignedEmployee = 1, OrderIndex = 51, Priority = 0 }, new RowReorderingTask { ID = 53, Subject = "Create Training Course for New TVs", Status = 5, Owner = 32, AssignedEmployee = 31, OrderIndex = 52, Priority = 0 }, new RowReorderingTask { ID = 54, Subject = "Review Training Course for any Omissions", Status = 5, Owner = 31, AssignedEmployee = 33, OrderIndex = 53, Priority = 0 }, new RowReorderingTask { ID = 55, Subject = "Review Overtime Report", Status = 5, Owner = 5, AssignedEmployee = 6, OrderIndex = 54, Priority = 0 }, new RowReorderingTask { ID = 56, Subject = "Submit Overtime Request Forms", Status = 5, Owner = 6, AssignedEmployee = 21, OrderIndex = 55, Priority = 0 }, new RowReorderingTask { ID = 57, Subject = "Submit Overtime Request Forms", Status = 5, Owner = 6, AssignedEmployee = 22, OrderIndex = 56, Priority = 0 }, new RowReorderingTask { ID = 58, Subject = "Submit Overtime Request Forms", Status = 5, Owner = 6, AssignedEmployee = 23, OrderIndex = 57, Priority = 0 }, new RowReorderingTask { ID = 59, Subject = "Overtime Approval Guidelines", Status = 5, Owner = 6, AssignedEmployee = 2, OrderIndex = 58, Priority = 0 }, new RowReorderingTask { ID = 60, Subject = "Refund Request Template", Status = 3, Owner = 12, AssignedEmployee = 8, OrderIndex = 59, Priority = 0 }, new RowReorderingTask { ID = 61, Subject = "Recall Rebate Form", Status = 3, Owner = 12, AssignedEmployee = 8, OrderIndex = 60, Priority = 0 }, new RowReorderingTask { ID = 62, Subject = "Create Report on Customer Feedback", Status = 5, Owner = 30, AssignedEmployee = 12, OrderIndex = 61, Priority = 0 }, new RowReorderingTask { ID = 63, Subject = "Review Customer Feedback Report", Status = 5, Owner = 30, AssignedEmployee = 8, OrderIndex = 62, Priority = 0 }, new RowReorderingTask { ID = 64, Subject = "Customer Feedback Report Analysis", Status = 3, Owner = 8, AssignedEmployee = 1, OrderIndex = 63, Priority = 0 }, new RowReorderingTask { ID = 65, Subject = "Prepare Shipping Cost Analysis Report", Status = 5, Owner = 8, AssignedEmployee = 10, OrderIndex = 64, Priority = 0 }, new RowReorderingTask { ID = 66, Subject = "Provide Feedback on Shippers", Status = 5, Owner = 10, AssignedEmployee = 13, OrderIndex = 65, Priority = 0 }, new RowReorderingTask { ID = 67, Subject = "Provide Feedback on Shippers", Status = 5, Owner = 10, AssignedEmployee = 15, OrderIndex = 66, Priority = 0 }, new RowReorderingTask { ID = 68, Subject = "Provide Feedback on Shippers", Status = 5, Owner = 10, AssignedEmployee = 16, OrderIndex = 67, Priority = 0 }, new RowReorderingTask { ID = 69, Subject = "Select Preferred Shipper", Status = 5, Owner = 10, AssignedEmployee = 2, OrderIndex = 68, Priority = 0 }, new RowReorderingTask { ID = 70, Subject = "Complete Shipper Selection Form", Status = 3, Owner = 2, AssignedEmployee = 1, OrderIndex = 69, Priority = 0 }, new RowReorderingTask { ID = 71, Subject = "Upgrade Server Hardware", Status = 5, Owner = 22, AssignedEmployee = 6, OrderIndex = 70, Priority = 0 }, new RowReorderingTask { ID = 72, Subject = "Upgrade Personal Computers", Status = 4, Owner = 21, AssignedEmployee = 6, OrderIndex = 71, Priority = 0 }, new RowReorderingTask { ID = 73, Subject = "Approve Personal Computer Upgrade Plan", Status = 5, Owner = 6, AssignedEmployee = 2, OrderIndex = 72, Priority = 0 }, new RowReorderingTask { ID = 74, Subject = "Decide on Mobile Devices to Use in the Field", Status = 5, Owner = 6, AssignedEmployee = 3, OrderIndex = 73, Priority = 0 }, new RowReorderingTask { ID = 75, Subject = "Upgrade Apps to Windows RT or stay with WinForms", Status = 5, Owner = 24, AssignedEmployee = 6, OrderIndex = 74, Priority = 0 }, new RowReorderingTask { ID = 76, Subject = "Estimate Time Required to Touch-Enable Apps", Status = 5, Owner = 24, AssignedEmployee = 25, OrderIndex = 75, Priority = 0 }, new RowReorderingTask { ID = 77, Subject = "Report on Tranistion to Touch-Based Apps", Status = 5, Owner = 6, AssignedEmployee = 23, OrderIndex = 76, Priority = 0 }, new RowReorderingTask { ID = 78, Subject = "Try New Touch-Enabled WinForms Apps", Status = 5, Owner = 6, AssignedEmployee = 3, OrderIndex = 77, Priority = 0 }, new RowReorderingTask { ID = 79, Subject = "Rollout New Touch-Enabled WinForms Apps", Status = 4, Owner = 6, AssignedEmployee = 24, OrderIndex = 78, Priority = 0 }, new RowReorderingTask { ID = 80, Subject = "Site Up-Time Report", Status = 5, Owner = 3, AssignedEmployee = 6, OrderIndex = 79, Priority = 0 }, new RowReorderingTask { ID = 81, Subject = "Review Site Up-Time Report", Status = 5, Owner = 3, AssignedEmployee = 4, OrderIndex = 80, Priority = 0 }, new RowReorderingTask { ID = 82, Subject = "Review Online Sales Report", Status = 5, Owner = 4, AssignedEmployee = 1, OrderIndex = 81, Priority = 0 }, new RowReorderingTask { ID = 83, Subject = "Determine New Online Marketing Strategy", Status = 5, Owner = 4, AssignedEmployee = 8, OrderIndex = 82, Priority = 0 }, new RowReorderingTask { ID = 84, Subject = "New Online Marketing Strategy", Status = 5, Owner = 8, AssignedEmployee = 42, OrderIndex = 83, Priority = 0 }, new RowReorderingTask { ID = 85, Subject = "Approve New Online Marketing Strategy", Status = 5, Owner = 8, AssignedEmployee = 4, OrderIndex = 84, Priority = 0 }, new RowReorderingTask { ID = 86, Subject = "Submit New Website Design", Status = 5, Owner = 8, AssignedEmployee = 28, OrderIndex = 85, Priority = 0 }, new RowReorderingTask { ID = 87, Subject = "Create Icons for Website", Status = 5, Owner = 28, AssignedEmployee = 29, OrderIndex = 86, Priority = 0 }, new RowReorderingTask { ID = 88, Subject = "Review PSDs for New Website", Status = 5, Owner = 28, AssignedEmployee = 6, OrderIndex = 87, Priority = 0 }, new RowReorderingTask { ID = 89, Subject = "Create New Shopping Cart", Status = 5, Owner = 6, AssignedEmployee = 24, OrderIndex = 88, Priority = 0 }, new RowReorderingTask { ID = 90, Subject = "Create New Product Pages", Status = 5, Owner = 6, AssignedEmployee = 25, OrderIndex = 89, Priority = 0 } }; } }
.tables { display: flex; } .column:first-child { width: 50%; padding-right: 15px; } .column:last-child { width: 50%; padding-left: 15px; }

To allow users to move rows between grids, follow these steps:

  1. Bind the grids to the same store
    The store should be able to update data. In this demo, the store is created using the createStore method (part of the DevExtreme.AspNet.Data extension). The specified updateUrl enables the store to update data.

  2. Specify grid identifiers
    Save them in the rowDragging.data property. The grids below have identifiers 1 and 2.

  3. Filter the grids to display different record sets
    Use the identifiers in the filterValue property to filter the grids. The grids below display only the records whose Status field equals the grid's identifier.

  4. Join the grids into one drag and drop group
    Set the rowDragging.group property to the same value for all grids to allow moving rows between them.

  5. Update the data field that specifies where the row belongs
    Implement the rowDragging.onAdd function. To access the target grid's identifier, use the toData function parameter. Call the store's update method to send this identifier to the server and push the same changes to the store on the client. The grids are refreshed automatically if you enable reshapeOnPush in the dataSource.