Add/Remove Table Rows On Drag and Drop Between Two DataTables?

Add/Remove Table Rows On Drag and Drop Between Two DataTables?

PrateekParekhPrateekParekh Posts: 13Questions: 3Answers: 0
edited September 2015 in Free community support

I want to drag and drop multiple table rows from one datatable to another. The 'tr' elements need to be removed from the source table and added to the destination table - not just ui. I am able to clone the rows and make them work on click but the same is not happening with drag and drop.
Here is my code:
HTML:

<table class="tables_ui" id="source">
    <thead>
  <tr>
    <th >Page Title</th>
    <th >Person ID</th>  
    <th >Language</th>  
    </tr> 
</thead>
<tbody></tbody>
</table>
<table class="tables_ui" id="destination">
    <thead>
  <tr>
    <th >Page Title</th>
    <th Person ID</th>  
    <th>Language</th>  
    </tr> 
</thead>
<tbody></tbody>
</table>

JS:

var stockTable = $('#source').dataTable({
            
            "aaData": src,
            "sPaginationType": "full_numbers",
            "bFilter": false,
            "bProcessing": false,
            "bDestroy": false,
            "colReorder": true,
            "aoColumns": [
                {"mData":"Page Title"},
                {"mData":"Person ID"},
                {"mData":"Language"}
                
            ]
    });
    
    
    var catalogTable = $('#destination').dataTable({
            "aaData": dest,
            "sPaginationType": "full_numbers",
            "bFilter": false,
            "bProcessing": false,
            "bDestroy": false,
            "aoColumns": [
                {"mData":"Page Title"},
                {"mData":"Person ID"},
                {"mData":"Language"}
            ]
    });
   
         
  stockTable.on('click', 'tbody tr' ,function() {
        var $row = $(this);
        var addRow = stockTable.fnGetData(this);
        catalogTable.fnAddData(addRow);
        stockTable.fnDeleteRow($row);
        
   });
    
    catalogTable.on('click', 'tbody tr' ,function() {
        var $row = $(this);
        var addRow = catalogTable.fnGetData(this);
        stockTable.fnAddData(addRow);
        catalogTable.fnDeleteRow($row);
        
    });
    
 
    $("#source tbody").on('click', 'tr', function (e) {
    if (e.ctrlKey || e.metaKey) {
        $(this).toggleClass("selected");
        
    } else {
        $(this).addClass("selected").siblings().removeClass('selected');
    }}).sortable({
    connectWith: "#destination tbody",
    delay: 150,     
    helper: function (e, item) {
             if (!item.hasClass('selected')) {
            item.addClass('selected').siblings().removeClass('selected');
           
        }
  
        var elements = item.parent().children('.selected').clone();
        item.data('multidrag', elements).siblings('.selected').remove();
       var helper = $('<tr/>');
        return helper.append(elements);
    },
    stop: function (e, ui) {
        
//THIS IS WHERE I'M STUCK.... USING UI, I CAN SHOW IN DIFEERENT TABLES
//BUT HOW DO I ACTUALLY ADD TR ELEMENTS TO DESTINATION AND REMOVE //FROM SOURCE AND VICE-VERSA
      var elements = ui.item.data('multidrag');
           
        catalogTable.fnAddData(elements);
        stockTable.fnDeleteRow(elements);
        ui.item.after(elements).remove();
    }

});

Kindly provide a solution where I can drag and drop multiple rows with addition/removal of table rows.

Answers

  • PrateekParekhPrateekParekh Posts: 13Questions: 3Answers: 0
    edited September 2015

    Can anyone atleast suggest a way to achieve this?

  • allanallan Posts: 63,075Questions: 1Answers: 10,384 Site admin

    Hi,

    This is not a feature of DataTables, however, as you have surmised in the above code it should be quite possible using the API. Specifically I would suggest using row().remove() and row.add() to remove and add rows as required. The drag and drop code however would be external to DataTables.

    Allan

  • PrateekParekhPrateekParekh Posts: 13Questions: 3Answers: 0

    Thank you.The issue which happens is even by using draw() I seem unable to get "No Data Available" to go. Basically, I want to duplicate the action of onClick.Any way I can fnAddData on drop?

  • allanallan Posts: 63,075Questions: 1Answers: 10,384 Site admin

    I don't see why you wouldn't be able to use fnAddDa or any other API method in a drop function. Perhaps you can link to a working demo so we can see what is going wrong.

    Allan

  • PrateekParekhPrateekParekh Posts: 13Questions: 3Answers: 0
    edited September 2015

    Here is the updated code:

        var stockTable = $('#source').dataTable({
            "aaData": src,
            "sPaginationType": "full_numbers",
            "bFilter": true,
            "bProcessing": true,
            "bRedraw":true,
            "bInfo":false,
            "bLengthChange":false,
            "aoColumns": [
                {"mData": "Module Title"},
                {"mData": "Module ID"},
                {"mData": "Module Language"}
    
            ]
        });
    
    
        var catalogTable = $('#destination').dataTable({
            "aaData": dest,
            "sPaginationType": "full_numbers",
            "bFilter": true,
            "bProcessing": true,
            "bRedraw":true,
            "bInfo":false,
            "bLengthChange":false,
            "aoColumns": [
                {"mData": "Module Title"},
                {"mData": "Module ID"},
                {"mData": "Module Language"}
            ]
        });
        
        $("#source tbody").on('click', 'tr', function (e) {
            if (e.ctrlKey || e.metaKey) {
                $(this).toggleClass("selected");
    
            } else {
                $(this).addClass("selected").siblings().removeClass('selected');
            }
    
    
        }).sortable({
            connectWith: "tbody",
            delay: 150, //Needed to prevent accidental drag when trying to select
            revert: 'invalid',
            helper: function (e, item) {
                //Basically, if you grab an unhighlighted item to drag, it will deselect (unhighlight) everything else
                if (!item.hasClass('selected')) {
                    item.addClass('selected').siblings().removeClass('selected');
                }
                    
                     
                //HERE'S HOW TO PASS THE SELECTED ITEMS TO THE `stop()` FUNCTION:
    
                //Clone the selected items into an array
                var elements = item.parent().children('.selected').clone();
                
                //Add a property to `item` called 'multidrag` that contains the 
                //  selected items, then remove the selected items from the source list
                item.data('multidrag', elements).siblings('.selected').remove();
                //Now the selected items exist in memory, attached to the `item`,
                //  so we can access them later when we get to the `stop()` callback
                //Create the helper
                var helper = $('<tr/>');
                return helper.append(elements);
    
            },
            stop: function (e, ui) {
                //Now we access those items that we stored in `item`s data!
                var elements = ui.item.data('multidrag');
    
               
                //`elements` now contains the originally selected items from the source list (the dragged items)!!
                //Finally I insert the selected items after the `item`, then remove the `item`, since 
                //  item is a duplicate of one of the selected items.
                ui.item.after(elements).remove();
                catalogTable.rows.add(elements);
               
            }
    
        });
        
        $("#destination tbody").on('click', 'tr', function (e) {
            
            if (e.ctrlKey || e.metaKey) {
                $(this).toggleClass("selected");
    
            } else {
                $(this).addClass("selected").siblings().removeClass('selected');
            }
    
    
        }).sortable({
            connectWith: "tbody",
            delay: 150, //Needed to prevent accidental drag when trying to select
            revert: 'invalid',
            helper: function (e, item) {
                //Basically, if you grab an unhighlighted item to drag, it will deselect (unhighlight) everything else
                if (!item.hasClass('selected')) {
                    item.addClass('selected').siblings().removeClass('selected');
                }
    
                //HERE'S HOW TO PASS THE SELECTED ITEMS TO THE `stop()` FUNCTION:
    
                //Clone the selected items into an array
                var elements = item.parent().children('.selected').clone();
                
                //Add a property to `item` called 'multidrag` that contains the 
                //  selected items, then remove the selected items from the source list
                item.data('multidrag', elements).siblings('.selected').remove();
                //Now the selected items exist in memory, attached to the `item`,
                //  so we can access them later when we get to the `stop()` callback
                //Create the helper
                var helper = $('<tr/>');
                return helper.append(elements);
    
            },
            stop: function (e, ui) {
                //Now we access those items that we stored in `item`s data!
                var elements = ui.item.data('multidrag');
    
                 //`elements` now contains the originally selected items from the source list (the dragged items)!!
                //Finally I insert the selected items after the `item`, then remove the `item`, since 
                //  item is a duplicate of one of the selected items.
                ui.item.after(elements).remove();
                
               
               
            }
    
        });
    

    Also I tried using

    catalogTable.fnAddData(elements);
            stockTable.fnDeleteRow(elements);
    

    but it doesn't update the current table.

    I also tried:

     stop: function (e, ui) {
                //Now we access those items that we stored in `item`s data!
                var elements = ui.item.data('multidrag');
                catalogTable.fnRedraw();
                stockTable.fnRedraw();
                //`elements` now contains the originally selected items from the source list (the dragged items)!!
                //Finally I insert the selected items after the `item`, then remove the `item`, since 
                //  item is a duplicate of one of the selected items.
                ui.item.after(elements).remove();
                
               
            }
    

    What should I add in stop function to make it work smoothly?The drag and drop should add a new row to destination and remove it from source in either direction.

  • allanallan Posts: 63,075Questions: 1Answers: 10,384 Site admin

    Please can you link to a working demo page, as I requested above.

    Allan

  • PrateekParekhPrateekParekh Posts: 13Questions: 3Answers: 0
    edited September 2015

    Doing it on localhost to make the functionality..hence can't post.
    Please do you have a solution?

  • allanallan Posts: 63,075Questions: 1Answers: 10,384 Site admin

    No sorry. We would need a link to a test case to be able to offer any help. Priority support is available if you need urgent help.

    Allan

  • PrateekParekhPrateekParekh Posts: 13Questions: 3Answers: 0

    Solved it as follows:

     stockTable.on('click || dblclick', 'tbody tr', function (e) {
                if (e.ctrlKey || e.shiftKey || e.metaKey){
                    
                    // $('#source tbody tr').addClass('selected');
                    $(this).toggleClass('selected');
                    
                }
                else {
    
                    var $selectedRowsList = document.querySelectorAll(".selected");
                    var len = $selectedRowsList.length;
                    if (len != 0){
    
                            for (var i = 0; i < len; i++) {
                                
                                var addRow = stockTable.fnGetData($selectedRowsList[i]);
                                catalogTable.fnAddData(addRow);
                                $('#dynamic').trigger('change');
                                
                            }
                            stockTable.fnDeleteRow($selectedRowsList);
                            $("selected", stockTable).remove();
                    }
    
                    else {
                       
                        var $row = $(this);
                        var addRow = stockTable.fnGetData(this);
                        catalogTable.fnAddData(addRow);
                        $("#destination .info").hide();
                        stockTable.fnDeleteRow($row);
                        $('#dynamic').trigger('change');
                        
                    }
    
                }
    
            });
    
This discussion has been closed.