+ Start a Discussion
Natacha JosephNatacha Joseph 

Drag & Drop of rows in a table in Lightning Component

Hi !  I need to be able to drag and drop rows in a table in my Lightning component.   For now I have a table with 3 rows and some values that are hard coded...  Since i've never done that before, I start by searching some example in Google but I found only example of drag & drop between 2 sections like <div> ou <ul>
I found a great library to do drag & drop in tables but I could not manage to make it work in Lightning...  https://github.com/sindu12jun/table-dragger
Is it possible to do some drag & drop in a table in a Lightning Component ? Do I need to change that for div or something else ?
Can you give me an example that I can try and make it work ?   

Thank you !
Rajiv Penagonda 12Rajiv Penagonda 12
Lightning is no diffrent than any other HTML/Javascript code. I do not see a reason why this (https://www.w3schools.com/html/html5_draganddrop.asp) should not work. If this did not help, revert and I can find some more examples.

-Rajiv
Natacha JosephNatacha Joseph
Hi Rajiv, 
thank you for your reply.  As I mentioned in my question, I need to do drag & drop in a table, and I never did this before.  So maybe it seems simple to you but for me it is not.  I look at your example but it is still the same thing as I saw before, drag & drop between two "zones". 
I found a lot of examples for HTML drag & drop on tables using librairies but I am not able to use them in my Lightning Component.
I need to be able to reorder my tables rows and to save my data after.
I tried to use the librairies from the example in https://stackoverflow.com/questions/35282490/js-table-row-drag-and-drop-without-jquery-ui-in-2016 but it dis not worked.  Can you help me with this library ?  I tried to reproduce the same example as the post but in my Lightning Component, I cannot mange to make it work...  
Thank you
Rajiv Penagonda 12Rajiv Penagonda 12
Natacha, lightning component framework is something parallel to jQuery. Though Salesforce officially provides tools for using jQuery within lightning framework, not all the functionalities will be available. Having said that, this third-party tool may not be readily compatible (is see several lines of code that run $(document).ready, which do not work as-is).

Below is a high-level checklist of what your solution should have.
1. Reordering of table rows to be supported with a combination of lightning UI and lightning controller logic (jQuery may of may not work here, there is solution for this using pure lightning - details below).
2. Lightning controller to define a data model (using javascript objects) to manage the run-time data manipulations.
3. The UI logic rendered for #1 above to make extensive use of the data model from #2 above.
4. The ligtning controller logic to manipulate the custom data model to capture the re-ordering changes made by the user in the UI.
5. Lightning controller logic to read information from this custom data model for saving the re-ordered row information back to a Salesforce object (through APEX controller).

Below is a sample code for doing row drag-drop using lightning code only:
Component (SampleDragDrop.cmp)
<aura:component >
    <aura:attribute name="draggedDivID" type="String" access="private" />
    <aura:attribute name="table1Data" type="Object[]" access="private" />
    <aura:attribute name="table2Data" type="Object[]" access="private" />
    <aura:handler name="init" value="this" action="{!c.doInit}" />
    
	<div>
        <div class="dnd-table-parent">
            <div class="dnd-table">
                <aura:iteration items="{!v.table1Data}" var="tableRow">
                    <div id="{!tableRow.rowid}" class="dnd-table-row" draggable="true" ondragstart="{!c.handleDrag}">
                        <aura:iteration items="{!tableRow.rowdata}" var="tableCell">
                            <div class="dnd-table-cell">
                                {!tableCell}
                            </div>
                        </aura:iteration>
                    </div>
                </aura:iteration>
            </div>
        </div><br/><br/>
        <div class="dnd-table-parent">
            <div class="dnd-table" ondrop="{!c.handleDrop}" ondragover="{!c.allowDrop}" id="table2">
                Drop your Content here.<br/>
                <aura:iteration items="{!v.table2Data}" var="tableRow">
                    <div id="{!tableRow.rowid}" class="dnd-table-row" draggable="true" ondragstart="{!c.handleDrag}">
                        <aura:iteration items="{!tableRow.rowdata}" var="tableCell">
                            <div class="dnd-table-cell">
                                {!tableCell}
                            </div>
                        </aura:iteration>
                    </div>
                </aura:iteration>
            </div>
        </div>
    </div>
</aura:component>

Controller (SampleDragDropController.js)
({
    doInit : function(cmp, event, helper) {
        cmp.set('v.table1Data', [
                    	{"rowid":"dnd-r-0", "rowdata":["table1-row1-cell1","table1-row1-cell2"]},
						{"rowid":"dnd-r-1", "rowdata":["table1-row2-cell1","table1-row2-cell2"]}
                	]);
        
        cmp.set('v.table2Data', []);
    },
    allowDrop : function(cmp, event, helper) {
        event.preventDefault();
    },
    handleDrag : function(cmp, event, helper) {
        cmp.set("v.draggedDivID", event.target.id);
    },
    handleDrop : function(cmp, event, helper) {
        var srcId = cmp.get("v.draggedDivID");
        var rowIndex = parseInt(srcId.replace("dnd-r-", ""));
        
        var table1Data = cmp.get("v.table1Data");
        var table2Data = cmp.get("v.table2Data");
        
        var rowThatWasDragged = table1Data[rowIndex];
        table2Data.push(rowThatWasDragged);
        
        table1Data.splice(rowIndex, 1);
        cmp.set("v.table1Data", table1Data);
        cmp.set("v.table2Data", table2Data);
	}
})

CSS (SampleDragDrop.css)
.THIS .dnd-table-parent {
    display: flex;
}

.THIS .dnd-table {
    display: table;
    border: 1px solid red;
}

.THIS .dnd-table-row {
    display: table-row;
}

.THIS .dnd-table-cell {
    border: 1px solid #c0d6e4;
    padding: 10px;
    display: table-cell;
}

.THIS .dnd-recipient-table {
    padding: 20px;
}

Key Points from the above code:
1. The table logic is created here using "div" elements with css.
2. The attributes "table1Data" and "table2Data" are the custom data-models that are initialized and maintained through the lightning controller.
3. Currently, the drop operation appends the dragged row to the end of the new table. There are ways to control this to achieve what you are looking for (dropping at specific location order), however, it is not part of this sample code (got limited time today, will update and share new code when I can).

You may try the above through custom lightning app code below (use preview option in the developer console)
<aura:application >
    <c:SampleDragDrop />
</aura:application>
Hope this helps.

-Rajiv
 
smriti sharan19smriti sharan19
I have seen multiple links to drag and drop rows in lightning but can we do drag and drop columns in lightning
Example1 of drag and drop rows : https://developer.salesforce.com/forums/?id=9060G0000005OcPQAU

Example2 of drag and drop of rows: https://gist.github.com/brianmfear/fb13ac4781c79fad6495ef7dc1676f4f

Example of drag and drop column and rows but this is not using lightning: https://sindu12jun.github.io/table-dragger/

Has anyone worked on drag and drop of columns in lightning. If yes please share the code
jhasanjhasan
@smriti sharan19, I think first two links you provided are working for chrome not working in firefox.