Matrim
Matrim

Reputation: 643

ag-grid: Using Drag drop to reorder rows within the grid

I need to re-order rows within ag-grid by using drag-drop. The drag drop methods are simple enough but when the drop occurs there seems no easy way to switch the rows locations.

I attempted a

gridOptions.api.removeItems(selectedNode); 

to clear the current and then

gridOptions.api.insertItemsAtIndex(2, savedNode);

but the drop event appeared to re-fire preventing that approach. Plus the insertItems (when ran first) falls over in internal ag-grid looping.

I would rather not re-sort the gridRows manually and then reset the gridRow data which would be somewhat clunky. This seems a common request on most grids so i assume it can be done but have just missed the relevant documentation. Thanks for any help..

Upvotes: 1

Views: 10804

Answers (2)

Matrim
Matrim

Reputation: 643

K have finally got an Angular 2 method working, though currently I have to switch off sorting and filtering on the grid.

This particular example is relying on row selection being enabled (due to how it is finding some records). Grid dragdrop should be disabled (as that drags the grid visually which sucks) Instead use a processRowPostCreate to set up draggable params at the row level. This sets the dragged option to the row which looks much nicer.

in gridOptions

 processRowPostCreate: (params) => {
            this.generateRowEvents(params);
        },

which calls

private generateRowEvents(params) {
    params.eRow.draggable = true; 
    params.eRow.ondragstart = this.onDrag(event);
    params.eRow.ondragover = this.onDragOver(event);
    params.eRow.ondrop = this.onDrop(event);
}

I track the source recrord in the onDrag method

                 var targetRowId: any = $event.target.attributes.row.value;
                 this.savedDragSourceData = targetRowId;

onDragOver as usual

On drop we have to protect against an infinite loop (ag-grid appears to recall live methods when items are added to the grid hence the ondrop occurs multiple times) and then insert, delete and splice over both the grid and its data source ( I will carry on looking at using the grid to populate the data as opposed to the source data as that would allow source/filter, currently doign that inserts blank rows). An event (in this case) is then emitted to ask the owning component to 'save' the adjusted data.

private onDrop($event) {
     if ($event && !this.infiniteLoopCheck) {
         if ($event.dataTransfer) {
             if (this.enableInternalDragDrop) {
                 this.infiniteLoopCheck= true;

                  var draggedRows: any = this.gridRows[this.savedDragSourceData];

                 // get the destination row
                 var targetRowId: any = $event.target.offsetParent.attributes.row.value;

                 // remove  from the current location
                 this.gridOptions.api.removeItems(this.gridOptions.api.getSelectedNodes());

                 // remove from source Data  
                this.gridRows.splice(this.savedDragSourceData, 1);


                 if (draggedRows) {
                     // insert into specified drop location
                     this.gridOptions.api.insertItemsAtIndex(targetRowId, [draggedRows]);

                     // re-add rows to source data..
                     this.gridRows.splice(targetRowId, 0, checkAdd);

                     this.saveRequestEvent.emit(this.gridRows);// shout out that a save is needed                     }
                 this.v= false;
             }
             else {
                 this.onDropEvent.emit($event);
             }
         }
     }
 }

NOTE we are wrapping the grid in our own class to allow us to write one set of grid methods and not replicate over the application whenever the grid is used.

I will be refining this over the next few days but as a basic this allows the ag-grid in angular 2 to drag drop rows to sort records.

Upvotes: 2

Shivek Parmar
Shivek Parmar

Reputation: 3003

If you don't find a solution within ag-grid then you can do this by adding one more directive("ngDraggable") and integrate it with ag-grid.

Please find the following working plnkr for this.

https://embed.plnkr.co/qLy0EX/

ngDraggable

Hope this helps..

Upvotes: 1

Related Questions