Search code examples
javascriptjquerydatatablesasp.net-core-mvc

Row transferring is not working between jQuery datatables that uses ajax call


I am working on an ASP.NET Core MVC project in C#, and I have 2 jQuery datatables (Exclude table and Include table) horizontally aligned. In between these 2 datatables, there is 2 buttons (right arrow button and left arrow button) as shown here:

enter image description here

I need to select 1 or more rows from the Exclude table by clicking the rows on it and clicking on the right arrow button, the selected row(s) should be move from Exclude table to Include table and do the same operation by clicking on the left arrow button. That is, moving the selected row or rows from Include table to Exclude table. I am using AJAX Call to load the data in these 2 tables.

Both datatables have the same data model.

In Index.cshtml:

@model RowTransfer.Models.DoorDetails
@using System.Data

@{
    ViewData["Title"] = "Index";
}
<script src="~/js/jquery-2.2.4.min.js"></script>
<script src="~/js/jquery.datatables.min.js"></script>

<script type="text/javascript">
$(document).ready(function () {
    LoadGridExclude();
    LoadGridInclude();
});

function LoadGridExclude() {
         new $("#excludeTable").DataTable({
             stripeClasses: [],
             select: {
                 style: 'multi'
             },
        ordering: true,
        paging: false,
        searching: false,
        serverSide: true,
        filter: true,
        searchDelay: 1000,
        scrollCollapse: true,
        ajax: {
            url: '@Url.Action("LoadExclude", "Home")',
            type: 'GET',
            datatype: 'json',
            headers: { 'RequestVerificationToken': 'your json token' },
            data: (d) => {
                return { draw: d.draw, start: d.start, length: d.length, search: d.search.value, FilterByColumn: d.columns[d.order[0].column].data, ASC_DSEC: d.order[0].dir }
            },
            dataSrc: (json) => {
                json = json.data;
                return json;
            }
        },
        columnDefs: [{ className: "dt-center", targets: [1, 2, 3], width: '2%' }],
        columns: [
            { data: 'SiteCode', title: 'SiteCode', autoWidth: true, searchable: true },
            { data: 'LegacyDoor', title: 'Legacy Door', autoWidth: true },
            { data: 'BuyingGroup', title: 'Buying Group', autoWidth: false, orderable: 
             false },
            { data: 'SettingName', title: 'Setting Name', autoWidth: true }
           ]
        });
      }

       function LoadGridInclude() {
                new $("#includeTable").DataTable({
                stripeClasses: [],
                 select: {
                         style: 'multi'
                         },
                 ordering: true,
                 paging: false,
                 searching: false,
                 serverSide: true,
                 filter: true,
                 searchDelay: 1000,
                scrollCollapse: true,
           ajax: {
            url: '@Url.Action("LoadInclude", "Home")',
            type: 'GET',
            datatype: 'json',
            headers: { 'RequestVerificationToken': 'your json token' },
            data: (d) => {
                return { draw: d.draw, start: d.start, length: d.length, search: d.search.value, FilterByColumn: d.columns[d.order[0].column].data, ASC_DSEC: d.order[0].dir }
            },
            dataSrc: (json) => {
                json = json.data;
                return json;
            }
        },
        columnDefs: [{ className: "dt-center", targets: [1, 2, 3], width: '2%' }],
        columns: [
            { data: 'SiteCode', title: 'SiteCode', autoWidth: true, searchable: true },
            { data: 'LegacyDoor', title: 'Legacy Door', autoWidth: true },
            { data: 'BuyingGroup', title: 'Buying Group', autoWidth: false, orderable: 
              false },
            { data: 'SettingName', title: 'Setting Name', autoWidth: true }
           ]
         });
      }

    </script>

       <div style="vertical-align:top;">
           <table id="excludeInclude" width=100% style="vertical-align:top;">
             <tr style="vertical-align:top;">
              <td valign="top">
                <table id="excludeTable" style="width:100%; height:30%;float:left; 
                 clear:both; vertical-align:top; border:1px solid;"></table>
              </td>
        <td valign="top" style="width:5%;float:left; clear:both;margin-left:5px;margin- 
              right:5px; margin-top:95px; ">
            <div id="btnPanel">
                <button id="btnRight" class="btn-logic"><b> >> </b></button>
                <button id="btnLeft" class="btn-logic"><b> << </b></button>
            </div>
        </td>
        <td valign="top">
            <table id="includeTable" style="width:100%; height:30%;float:left; 
                   clear:both;vertical-align:top;border:1px solid;"></table>
         </td>
       </tr>
     </table>
    </div>

The methods in the HomeController are shown here:

public IActionResult LoadExclude(int draw = 1, int start = 0, int length = 10, string search = "", string FilterByColumn = "", string ASC_DSEC = "")
{
    List<DoorDetails> excludeDoorList = new List<DoorDetails>();

    DoorDetails eidm1 = new DoorDetails();
    eidm1.LegacyDoor = 43443;
    eidm1.BuyingGroup = "BuyingGroup1";
    eidm1.SiteCode = 11;
    eidm1.SettingName = "Setting1";

    excludeDoorList.Add(eidm1);

    DoorDetails eidm2 = new DoorDetails();
    eidm2.LegacyDoor = 23123;
    eidm2.BuyingGroup = "BuyingGroup2";
    eidm2.SiteCode = 22;
    eidm2.SettingName = "Setting2";

    excludeDoorList.Add(eidm2);

    int recordsTotal = excludeDoorList.Count();

    var jsonData = new { 
                           draw = draw, 
                           recordsFiltered = recordsTotal, 
                           recordsTotal = recordsTotal, 
                           data = excludeDoorList 
                       };

    return OK(jsonData);
}

public IActionResult LoadInclude(int draw = 1, int start = 0, int length = 10, string search = "", string FilterByColumn = "", string ASC_DSEC = "")
{
    List<DoorDetails> includeDoorList = new List<DoorDetails>();

    DoorDetails eidm3 = new DoorDetails();
    eidm3.LegacyDoor = 54483;
    eidm3.BuyingGroup = "BuyingGroup3";
    eidm3.SiteCode = 33;
    eidm3.SettingName = "Setting3";

    includeDoorList.Add(eidm3);

    DoorDetails eidm4 = new DoorDetails();
    eidm4.LegacyDoor = 66543;
    eidm4.BuyingGroup = "BuyingGroup4";
    eidm4.SiteCode = 44;
    eidm4.SettingName = "Setting4";

    includeDoorList.Add(eidm4);

    int recordsTotal = includeDoorList.Count();

    var jsonData = new 
                   { 
                       draw = draw, 
                       recordsFiltered = recordsTotal, 
                       recordsTotal = recordsTotal, 
                       data = includeDoorList 
                   };
    return OK(jsonData);
}

This is the model class:

public class DoorDetails
{       
    public int SiteCode { get; set; }
    public int LegacyDoor { get; set; }       
    public string BuyingGroup { get; set; }
    public string SettingName { get; set; }      
}

Right now, I am not able to do the selection (single and multiple) of rows by clicking on the rows of both datatables and row transferring between the tables.

How to do these things? Please help.


Solution

  • You haven't got a complete data posting route and there are some errors , here is a sample you could follow.

    DoorService.cs to send the data

    public interface IDoorService
    {
        List<DoorDetails> ExcludeDoors { get; }
        List<DoorDetails> IncludeDoors { get; }
        void MoveToInclude(List<int> ids);
        void MoveToExclude(List<int> ids);
    }
    
    public class DoorService : IDoorService
    {
        public List<DoorDetails> ExcludeDoors { get; private set; }
        public List<DoorDetails> IncludeDoors { get; private set; }
    
        public DoorService()
        {
            // Initialize data as you want
            ExcludeDoors = new List<DoorDetails>
            {
                new DoorDetails { SiteCode = 11, LegacyDoor = 43443, BuyingGroup = "BuyingGroup1", SettingName = "Setting1" },
                new DoorDetails { SiteCode = 22, LegacyDoor = 23123, BuyingGroup = "BuyingGroup2", SettingName = "Setting2" }
            };
    
            IncludeDoors = new List<DoorDetails>
            {
                new DoorDetails { SiteCode = 33, LegacyDoor = 54483, BuyingGroup = "BuyingGroup3", SettingName = "Setting3" },
                new DoorDetails { SiteCode = 44, LegacyDoor = 66543, BuyingGroup = "BuyingGroup4", SettingName = "Setting4" }
            };
        }
    
        public void MoveToInclude(List<int> ids)
        {
            var doorsToMove = ExcludeDoors.Where(d => ids.Contains(d.SiteCode)).ToList();
            foreach (var door in doorsToMove)
            {
                ExcludeDoors.Remove(door);
                IncludeDoors.Add(door);
            }
        }
    
        public void MoveToExclude(List<int> ids)
        {
            var doorsToMove = IncludeDoors.Where(d => ids.Contains(d.SiteCode)).ToList();
            foreach (var door in doorsToMove)
            {
                IncludeDoors.Remove(door);
                ExcludeDoors.Add(door);
            }
        }
    }
    

    Register the service

    builder.Services.AddSingleton<IDoorService, DoorService>();
    

    Controller.cs

    public class HomeController : Controller
    {
        
        private readonly IDoorService _doorService;
    
        public HomeController(IDoorService doorService)
        {
            _doorService = doorService;
        }
    
        public IActionResult LoadExclude(int draw = 1, int start = 0, int length = 10)
        {
            var data = _doorService.ExcludeDoors.Skip(start).Take(length).ToList(); // Pagination logic
            var recordsTotal = _doorService.ExcludeDoors.Count;
    
            var jsonData = new
            {
                draw = draw,
                recordsFiltered = recordsTotal,
                recordsTotal = recordsTotal,
                data = data
            };
    
            return Json(jsonData);
        }
    
        public IActionResult LoadInclude(int draw = 1, int start = 0, int length = 10)
        {
            var data = _doorService.IncludeDoors.Skip(start).Take(length).ToList(); // Pagination logic
            var recordsTotal = _doorService.IncludeDoors.Count;
    
            var jsonData = new
            {
                draw = draw,
                recordsFiltered = recordsTotal,
                recordsTotal = recordsTotal,
                data = data
            };
    
            return Json(jsonData);
        }
    
        [HttpPost]
        public IActionResult MoveToInclude([FromBody] List<int> ids)
        {
            _doorService.MoveToInclude(ids);
            return Ok();
        }
    
        [HttpPost]
        public IActionResult MoveToExclude([FromBody] List<int> ids)
        {
            _doorService.MoveToExclude(ids);
            return Ok();
        }
    
        public IActionResult Index()
        {
            return View();
        }
    
    }
    

    Index.cshtml

    Based on my test, the properties in columns and rows need to be in lower case, or there will be errors.

    @section Scripts {
        <script>
                $(document).ready(function () {
                    var excludeTable = LoadGridExclude();
                    var includeTable = LoadGridInclude();
    
                    $('#btnRight').click(function () {
                        var selectedRows = excludeTable.rows({ selected: true }).data().toArray();
                        var ids = selectedRows.map(row => row.siteCode);
    
                        if (ids.length === 0) {
                            alert("Please select rows to move.");
                            return;
                        }
    
                        $.ajax({
                            url: '/Home/MoveToInclude',
                            type: 'POST',
                            contentType: 'application/json',
                            data: JSON.stringify(ids),
                            success: function () {
                                excludeTable.ajax.reload();
                                includeTable.ajax.reload();
                            }
                        });
                    });
    
                    $('#btnLeft').click(function () {
                        var selectedRows = includeTable.rows({ selected: true }).data().toArray();
                        var ids = selectedRows.map(row => row.siteCode);
    
                        if (ids.length === 0) {
                            alert("Please select rows to move.");
                            return;
                        }
    
                        $.ajax({
                            url: '/Home/MoveToExclude',
                            type: 'POST',
                            contentType: 'application/json',
                            data: JSON.stringify(ids),
                            success: function () {
                                excludeTable.ajax.reload();
                                includeTable.ajax.reload();
                            }
                        });
                    });
                });
    
                function LoadGridExclude() {
                    return $('#excludeTable').DataTable({
                        ajax: {
                            url: '/Home/LoadExclude',
                            type: 'GET',
                            datatype: 'json'
                        },
                        columns: [
                            { data: 'siteCode', title: 'SiteCode', autoWidth: true },
                            { data: 'legacyDoor', title: 'Legacy Door', autoWidth: true },
                            { data: 'buyingGroup', title: 'Buying Group', autoWidth: true },
                            { data: 'settingName', title: 'Setting Name', autoWidth: true }
                        ],
                        select: {
                            style: 'multi'
                        },
                        paging: false
                    });
                }
    
                function LoadGridInclude() {
                    return $('#includeTable').DataTable({
                        ajax: {
                            url: '/Home/LoadInclude',
                            type: 'GET',
                            datatype: 'json'
                        },
                        columns: [
                            { data: 'siteCode', title: 'SiteCode', autoWidth: true },
                            { data: 'legacyDoor', title: 'Legacy Door', autoWidth: true },
                            { data: 'buyingGroup', title: 'Buying Group', autoWidth: true },
                            { data: 'settingName', title: 'Setting Name', autoWidth: true }
                        ],
                        select: {
                            style: 'multi'
                        },
                        paging: false
                    });
                }
        </script>
    }
    
    <div style="vertical-align:top;">
        <table id="excludeInclude" width="100%" style="vertical-align:top;">
            <tr style="vertical-align:top;">
                <td valign="top">
                    
                    <table id="excludeTable" class="display" style="width:100%; height:30%; float:left; clear:both; vertical-align:top; border:1px solid;">
                        <thead>
                            <tr>
                                <th>SiteCode</th>
                                <th>Legacy Door</th>
                                <th>Buying Group</th>
                                <th>Setting Name</th>
                            </tr>
                        </thead>
                        <tbody>
                            
                        </tbody>
                    </table>
                </td>
                <td valign="top" style="width:5%; float:left; clear:both; margin-left:5px; margin-right:5px; margin-top:95px;">
                    <div id="btnPanel">
                        <button id="btnRight" class="btn-logic"><b> >> </b></button>
                        <button id="btnLeft" class="btn-logic"><b> << </b></button>
                    </div>
                </td>
                <td valign="top">
                    
                    <table id="includeTable" class="display" style="width:100%; height:30%; float:left; clear:both; vertical-align:top; border:1px solid;">
                        <thead>
                            <tr>
                                <th>SiteCode</th>
                                <th>Legacy Door</th>
                                <th>Buying Group</th>
                                <th>Setting Name</th>
                            </tr>
                        </thead>
                        <tbody>
                            
                        </tbody>
                    </table>
                </td>
            </tr>
        </table>
    </div>
    

    enter image description here