Drag-and-drop with Datatable

The library supports drag-and-drop of items from and to a table.

Moving Rows

To enable the drag-and-drop support for rows, set the drag parameter to true.

Enabling the drag-and-drop support for rows

webix.ui({
    view:"datatable",
    drag:true
});

To drag/drop rows between several tables you should enable the drag parameter in each of them.

Related sample:  Drag-and-Drop between Tables in DataTable

The 'move' mode

There is a special drag-and-drop mode - 'move'. In this mode, the dragged nodes are moved out.

To enable the d-n-d support and activate the 'move' mode, set the drag parameter to move.

Activating the 'move' mode for rows

webix.ui({
    view:"datatable",
    drag:"move"
});

Related sample:  The DnD Modes for Rows

The 'order' mode

This mode works similar to "move", but does not allow to drag the nodes outside the datatable.

Also, while the user is dragging an item, the remaining items are automatically rearranged to make space for the item.

To enable the d-n-d support and activate the 'order' mode, set the drag parameter to order.

Activating the 'order' mode for rows

webix.ui({
    view:"datatable",
    drag:"order"
});

Related sample:  The DnD Modes for Rows

Moving Columns

To enable the drag-and-drop support for columns within one datatable, set the dragColumn parameter to true.

Enabling the drag-and-drop support for columns

webix.ui({
    view:"datatable",
    dragColumn:true
});

To drag/drop columns between several tables you should enable the dragColumn parameter in each of them.

Related sample:  Drag-and-Drop Support for Columns

There are three events that will be useful during column drag-n-drop process:

  • onBeforeColumnDrag - fires the moment you start dragging the column from its source position
  • onBeforeColumnDrop - fires the moment you drop the column to its target position
  • onAfterColumnDrop - fires after the column has been dragged and dropped to the target position

The "order" mode

In the "order" mode, columns can't be dragged out of the table boundaries. Also, while the user is dragging a column, the remaining columns are automatically rearranged make space for the column.

To enable the d-n-d support and activate the 'order' mode for columns, set the dragColumn parameter to order.

Activating the "order" mode for columns

webix.ui({
    view:"datatable",
    dragColumn:"order"
});

Related sample:  Datatable: Column Reordering

If column drag-n-drop in the "order" mode is enabled, the onBeforeColumnDrop and onAfterColumnDrop events won't fire. These events will fire instead:

Advanced

Follow these guidelines to customize drag-and-drop modes.

Custom contents of the dragged items

To change the default drag marker (the element that is displayed next you the mouse pointer when you drag items), use the onBeforeDrag event

The contents of the element are set with the help of the context.html property. You can assign any text or HTML to it.

Use cases:

  • Show the number of dragged items:
dtable.attachEvent("onBeforeDrag", function(context, ev){
    context.html = context.source.length+" item(s)";
});
  • Show an image and the id of the dragged item:
dtable.attachEvent("onBeforeDrag", function(context, ev){
    context.html = "<img src='some.gif'></img> " + context.start;
});
  • Show the names of the dragged items:

dtable.attachEvent("onBeforeDrag", function(context, ev){
    context.html = "";
    for (var i=0; i< context.source.length; i++){
        context.html += context.from.getItem(context.source[i]).title + "<br>" ;
    }
});

Related sample:  Using Events for Customizing Drag-and-Drop

Denying dragging of specific items

To deny dragging of specific items, you can use the onBeforeDrag event.

Denying dragging even items

dtable.attachEvent("onBeforeDrag", function(context, ev){
    if(dtable.getIndexById(context.start)%2==0){
        return false;      //denies dragging if the item index is even
    }
    return true;           //allows dragging in any other case
});

You can use the addCss method to mark items and hasCss to check whether an item has a certain marking.

Denying dropping to specific positions

To deny dropping to some positions, you can use the onBeforeDrop event and return false each time you want to block the operation.

Let's assume you want to deny dropping to the position of an item with 'id=2':

Denying dropping to a specific position

var dtable = webix.ui({
    view:"datatable",
    data:[
        { id:1, title:"The Shawshank Redemption", year:1994},
        { id:2, title:"The Godfather",            year:1972},
        { id:3, title:"The Godfather: Part II",   year:1974}
    ]
});
dtable.data.addMark(2,"type", false,"b"); // adds a flag (type='b') to an item with id=2
 
dtable.attachEvent("onBeforeDrop", function(context, ev){
// if an item has flag type='b', denies dropping to the position of this item
    if(dtable.data.getMark(context.target,"type")=='b') return false;
    return true;
});

Switching between 'move' and 'copy' behavior

By default, rows are moved (not copied) while d-n-d.

To set the 'copy' behavior, use the onBeforeDrop event. Specify inside the copy logic and return false to prevent drag-and-drop processing:

Setting the 'copy' behavior for d-n-d

dtable.attachEvent("onBeforeDrop", function(context, ev){
    for (var i=0; i< context.source.length; i++){
        context.from.copy(context.source[i],context.index,this,webix.uid());
    }
    return false;
});

Related sample:  Using Events for Customizing Drag-and-Drop

Limiting the draggable area within the specified element

By default the whole element is draggable (wherever within the element you click, you can drag it). To restrict dragging to a specific part of the item, follow these steps:

1. Add or specify the element that will serve as the handle for dragging.
2. Set this element as the target object for the onBeforeDrag event.

.webix_drag_handle{
    background-image:url(./handle.png);
    background-repeat: no-repeat;
}
var dtable = webix.ui({
    view:"datatable",
    // datatable configuration
    columns:[
        { id:"rank",    header:"", css:"rank" },
        { id:"title",   header:"Film title" },
        { id:"year",    header:"Released"},
        { id:"drag",    header:"", template:"<div class='webix_drag_handle'></div>" }
    ],
    on:{
        onBeforeDrag:function(data, e){
            return (e.target||e.srcElement).className == "webix_drag_handle";
        }
    }
});

If the target of the event does not have the "webix_drag_handle", DnD won't work.

Related sample:  Limiting Draggable Area for Items (Dragging Rows)
Related sample:  Limiting Draggable Area for Items (Dragging Columns)

Scrolling during Drag And Drop

By default datatable will scroll itself when drag is near the top or bottom border. This behavior can be disabled by using dragscroll configuration property

webix.ui({
    view:"datatable",
    dragscroll:false
});

By default drag scroll works only for vertical scroll. You can enable it for both x and y directions:

webix.ui({
    view:"datatable",
    dragscroll:"xy"
});

Related events

The following events are called during the d-n-d process:

  • onBeforeDrag - fires before the mouse button is pressed and moved over a draggable item
  • onBeforeDragIn - fires before a dragged element is moved over the droppable area
  • onDragOut - fires when a dragged element is moved outside of the droppable area
  • onBeforeDrop - fires before a dragged element is released over the droppable area
  • onBeforeDropOut - fires before a dragged element is released over the droppable area (fires in the drag SOURCE component, not in the drag target one)
  • onAfterDrop - fires after drag-n-drop was finished

Use these events to customize DnD.

Webix Tutorials

You can try your hand in Webix Tutorials.

Back to top
If you have not checked yet, be sure to visit site of our main product Webix web ui framework and page of javascript datagrid library product.