Row dragging is used to rearrange rows by dragging the row with the mouse. To enable row dragging, set the column
property rowDrag=True
on one (typically the first) column.
columnDefs = [
# make all rows draggable
{ 'field': 'athlete', 'rowDrag': True },
]
There are two ways in which row dragging works in the grid, managed and unmanaged:
In managed dragging, the grid is responsible for rearranging the rows as the rows are dragged. To enable the managed
dragging set the Grid Option:
dashGridOptions = {"rowDragManaged": True}
To enable animation of the rows while dragging, set the Grid Option:
dashGridOptions = {'animateRows': True}
By default, the managed row dragging moves the rows while you are dragging them. This effect might not be desirable due
to your application design. To prevent this default behavior, set the Grid Option:
dashGridOptions = {"suppressMoveWhenRowDragging": True}
It is possible to drag multiple rows at the same time, set the Grid Options:
dashGridOptions = {"rowDragMultiRow": True, "rowSelection": "multiple"}
The example below shows simple managed dragging. In this example:
rowDrag=True
which results in a draggable area being included in the cell.rowDragManaged
is enabled, to tell the grid to move the row as the row is dragged.When multi-row dragging is enabled:
The logic for managed dragging has the following constraints:
These constraints can be bypassed by using unmanaged row dragging.
See the AG Grid docs for more details
on unmanaged row dragging.
When using row dragging it is also possible to reorder rows by clicking and dragging anywhere on the row without the
need for a drag handle by enabling the grid option:
dashGridOptions = {"rowDragEntireRow": True}
The drag handle can be removed by not setting rowDrag=True
in Columns Definition.
Range Selection (enterprise feature) is not supported when
rowDragEntireRow
is enabled.
The example below demonstrates entire row dragging with Multi-Row Dragging. In this example:
rowDragEntireRow
enabled.rowDragMultiRow
is also enabled with rowSelection = 'multiple'
.There are some options that can be used to customize the Row Drag experience, so it has a better integration with your
application.
When a row drag starts, a “floating” DOM element is created to indicate which row is being dragged. By default, this DOM
element will contain the same value as the cell that started the row drag. You can override that text by passing a
function to the rowDragText
property of Grid Options.
dashGridOptions = {"rowDragText": {"function": "params.defaultTextValue + ' (age: ' + params.rowNode.data.age + ')'"}}
rowDragText
(Function) A function that should return a string to be displayed by therowDragComp
while dragging a
row. If this is not set, the current cell value will be used. IfrowDragText
is set in the Column Definition, it
will take precedence over this, except whenrowDragEntireRow=True
.
The example below shows dragging with custom text. The following can be noted:
rowDragText
will add the host city depending on the year to the floating drag element, like “(View the JavaScript functions used for this example
These JavaScript functions must be added to the dashAgGridFunctions.js
file in the assets folder.
See JavaScript Functions
for more information.
var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});
const hostCities = {2000: "Sydney", 2004: "Athens", 2008: "Beijing", 2012: "London",}
dagfuncs.rowDragText = function (params) {
const {year} = params.rowNode.data;
if (year in hostCities) {
return `${params.defaultTextValue} (${hostCities[year]} Olympics)`
}
return params.defaultTextValue;
}
If the grid has more than one column set with rowDrag=True
, rowDragText
can be set in the Column Definition.
columnDefs = [
{
'field': 'athlete',
'rowDrag': True,
"rowDragText": {"function": "athleteRowDragText(params)"}
},
{'field': 'country', 'rowDrag': True},
]
The example below shows dragging with custom text and multiple column draggers. The following can be noted:
When you drag a row by the country row dragger, rowDragText
will add the host city depending on the year to the
floating drag element, like “(London Olympics)” if year of the dragged row is 2012
When you drag the row by the athlete row dragger, rowDragText
in the grid options will be overridden by the one
in the Column Definition and will display the number of athletes selected.
View the JavaScript functions used for this example
These JavaScript functions must be added to the dashAgGridFunctions.js
file in the assets folder.
See JavaScript Functions
for more information.
var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});
const hostCities = {2000: "Sydney", 2004: "Athens", 2008: "Beijing", 2012: "London",}
dagfuncs.rowDragText = function (params) {
const {year} = params.rowNode.data;
if (year in hostCities) {
return `${params.defaultTextValue} (${hostCities[year]} Olympics)`
}
return params.defaultTextValue;
}
dagfuncs.athleteRowDragText = function (params) {
return `${params.rowNodes.length} athlete(s) selected`
}
Due to the complexity of some applications, it could be handy to render the Row Drag Component inside
a Custom Cell Renderer. This can be achieved by
using the registerRowDragger
method in the Custom Cell Renderer:
// this will hold the reference to the element you want to act as row dragger.
const myRef = React.useRef(null);
// synchronize the element with the registerRowDragger function
React.useEffect(() => {
props.registerRowDragger(myRef.current, props.startDragPixels);
});
// then use the reference in the actual element
React.createElement('i', {className: 'fas fa-arrows-alt-v', ref: myRef})
When using
registerRowDragger
you should not set the propertyrowDrag=True
in the Column Definition. Doing that
will cause the cell to have two row draggers.
Custom Start Drag Pixels:
By default, the drag event only starts after the Row Drag Element has been dragged by 4px
, but sometimes it might be
useful to start the drag with a different drag threshold, for example, start dragging as soon as the mousedown
event
happens (dragged by 0px
). For that reason, the registerRowDragger
takes a second parameter to specify the number of
pixels that will start the drag event.
The example below shows a Custom Cell Renderer, using registerRowDragger
to render the Row Dragger inside itself.
View the CSS classes used for this example
These CSS classes must be added to any *.css
file in the assets folder.
See Loading CSS files for more information.
.ag-ltr .ag-cell.custom-athlete-cell.ag-cell-focus:not(.ag-cell-range-selected):focus-within {
border: 1px solid #ff7b7b;
}
.ag-cell.custom-athlete-cell {
padding-left: 0 !important;
padding-right: 0 !important;
}
.ag-cell.custom-athlete-cell > div {
height: 100%;
}
.my-custom-cell-renderer {
display: flex;
font-size: 0.7rem;
background-color: #4180d6;
color: white;
padding: 0.25rem;
align-items: center;
justify-content: space-between;
box-sizing: border-box;
height: 100%;
}
.my-custom-cell-renderer > * {
line-height: normal;
}
.my-custom-cell-renderer i {
visibility: hidden;
cursor: move;
color: orange;
}
.my-custom-cell-renderer:hover i {
visibility: visible;
}
.my-custom-cell-renderer .athlete-info {
display: flex;
flex-direction: column;
width: 85px;
max-width: 85px;
}
.my-custom-cell-renderer .athlete-info > span {
overflow: hidden;
text-overflow: ellipsis;
}
View Custom Cell Renderer used for this example
This JavaScript function must be added to the dashAgGridComponentFunctions.js
file in the assets folder.
See Custom Components for more
information.
var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});
dagcomponentfuncs.RowDraggingCustomCellRenderer = function (props) {
const myRef = React.useRef(null);
React.useEffect(() => {
props.registerRowDragger(myRef.current, props.startDragPixels);
});
return React.createElement('div', {className: 'my-custom-cell-renderer'},
[
React.createElement('div', {className: 'athlete-info'}, [
React.createElement('span', null, props.data.athlete),
React.createElement('span', null, props.data.country),
]),
React.createElement('span', null, props.data.year),
React.createElement('i', {className: 'fas fa-arrows-alt-v', ref: myRef})
]
);
};
Note the following:
dragStartPixels
of registerRowDragger
to 0px using the input component, the drag eventmousedown
is fired.It is possible to drag Full Width Rows by registering
a Custom Row Dragger.
Note the following:
registerRowDragger
method takes a third parameter to specify the Row Drag Text (only relevant with Full WidthView the CSS classes used for this example
These CSS classes must be added to any *.css
file in the assets folder.
See Loading CSS files for more information.
.full-width-panel {
white-space: normal;
height: 100%;
width: 100%;
border: 2px solid blue;
box-sizing: border-box;
padding: 5px;
background-color: lightblue;
}
.full-width-flag {
float: left;
padding: 6px;
}
.full-width-summary {
float: left;
margin-right: 10px;
}
.full-width-panel label {
padding-top: 3px;
display: inline-block;
font-size: 12px;
}
.full-width-center {
overflow-y: scroll;
border: 1px solid grey;
padding: 2px;
height: 100%;
box-sizing: border-box;
font-family: cursive;
background-color: #fafafa;
}
.full-width-center p {
color: black;
margin-top: 0px !important;
}
.full-width-title {
font-size: 20px;
}
View Custom Cell Renderer used for this example
This JavaScript function must be added to the dashAgGridComponentFunctions.js
file in the assets folder.
See Custom Components for more
information.
var dagcomponentfuncs = (window.dashAgGridComponentFunctions = window.dashAgGridComponentFunctions || {});
dagcomponentfuncs.fullWidthCellRendererCountry = function (props) {
return React.createElement('span', null, [
React.createElement('img', {
width: "17", height: "12", style: {verticalAlign: "baseline", marginRight: "5px"},
src: "/assets/images/ag-grid/flags/" + props.data.code + ".svg"
}, null),
props.value,
])
}
dagcomponentfuncs.RowDraggingFullWidthRow = function (props) {
const latinText = `<p>Sample Text in a Paragraph<p>
<p>Lorem ipsum dolor sit amet, his mazim necessitatibus te, mea volutpat intellegebat at. Ea nec perpetua liberavisse,
et modo rebum persius pri. Velit recteque reprimique quo at. Vis ex persius oporteat, esse voluptatum moderatius te vis.
Ex agam suscipit aliquando eum. Mediocrem molestiae id pri, ei cibo facilisis mel. Ne sale nonumy sea. Et vel lorem
omittam vulputate. Ne prima impedit percipitur vis, erat summo an pro. Id urbanitas deterruisset cum, at legere
oportere has. No saperet lobortis elaboraret qui, alii zril at vix, nulla soluta ornatus per ad. Feugiat consequuntur
vis ad, te sit quodsi persequeris, labore perpetua mei ad. Ex sea affert ullamcorper disputationi, sit nisl elit
elaboraret te, quodsi doctus verear ut eam. Eu vel malis nominati, per ex melius delenit incorrupte. Partem
complectitur sed in. Vix dicta tincidunt ea. Id nec urbanitas voluptaria, pri no nostro disputationi. Falli
graeco salutatus pri ea.<p>
<p>Quo ad omnesque phaedrum principes, tale urbanitas constituam et ius, pericula consequat ad est. Ius tractatos
referrentur deterruisset an, odio consequuntur sed ad. Ea molestie adipiscing adversarium eos, tale veniam sea no.
Mutat nullam philosophia sed ad. Pri eu dicta consulatu, te mollis quaerendum sea. Ei doming commodo euismod vis.
Cu modus aliquip inermis his, eos et eirmod regione delicata, at odio definiebas vis.<p>`;
const myRef = React.useRef(null);
React.useEffect(() => {
props.registerRowDragger(myRef.current, undefined, props.data.name);
});
return React.createElement('div', {className: 'full-width-panel', ref: myRef}, [
React.createElement('div', {className: 'full-width-flag'},
React.createElement('img', {
width: "68", height: "40",
src: "/assets/images/ag-grid/flags/" + props.data.code + ".svg"
}, null),
),
React.createElement('div', {className: 'full-width-summary'}, [
React.createElement('span', {className: 'full-width-title'}, props.data.name),
React.createElement('br'),
React.createElement('label', {style: {display: "inline"},}, [
React.createElement('b', null, "Population: "),
props.data.population
]),
React.createElement('br'),
React.createElement('label', {style: {display: "inline"},}, [
React.createElement('b', null, "Known For: "),
props.data.summary
]),
React.createElement('br'),
]),
React.createElement('div', {
className: 'full-width-center',
dangerouslySetInnerHTML: {__html: latinText},
})
]);
}