Row Drag & Drop
Drag and drop functionality is supported for rows in the Grid.
This includes options like rearranging rows within the same Grid,
transferring rows to another Grid, and placing nodes into subtrees
of other nodes in a Tree Grid. Let's see an example for each option!
Rearranging rows
Try rearranging rows in this Grid:
<Grid records-bind="data" style={{ width: "100%" }} columns={[ { header: "Name", field: "fullName", items: ( <cx> <TreeNode expanded-bind="$record.$expanded" leaf-bind="$record.$leaf" level-bind="$record.$level" loading-bind="$record.$loading" text-bind="$record.fullName" /> </cx> ) }, { header: "City", field: "city" } ]} row={{ style: { cursor: "move" } }} dragSource={{ data: { type: "record", source: "data" } }} onDropTest={(e) => e.source.data.type == "record"} onDrop={(e, instance) => instance.controller.move(e)} />
In this scenario, the process unfolds as follows: initially, records
are created and saved in the store. The Grid then presents these records.
To facilitate the reordering of rows, certain parameters need to be defined.
These include dragSource, which specifies the type and source of the data
being dragged, onDropTest, indicating the acceptable type of data that
can be dropped (will be explained in the next example), and onDrop, a function
responsible for managing the rearrangement process. The onDrop function is
designed to identify the dragged item, determine the drop location (index),
and access the records in the store to execute the necessary rearrangement.
Transferring rows between two Grids
This example is similar to the previous one. Take a look at it here.
Drag and drop in tree hierarchy
When working with Tree Grid, a frequent scenario involves dealing with directory structures.
Try dragging files or folders into folders:
| Name |
|---|
| Name |
|---|
<div controller={PageController}>
<Grid
records-bind="data"
style={{
width: "100%"
}}
scrollable={true}
dataAdapter={{
type: TreeAdapter
}}
keyField="name"
columns={[
{
header: "Name",
field: "name",
items: (
<cx>
<TreeNode
expanded-bind="$record.$expanded"
leaf-bind="$record.$leaf"
level-bind="$record.$level"
loading-bind="$record.$loading"
text-bind="$record.name"
icon-bind="$record.icon"
/>
</cx>
)
}
]}
dragSource={{
mode: "copy",
data: { type: "record" }
}}
onRowDropTest={(_e, instance) => instance.controller.onDropTest()}
onRowDragOver={(e, instance) => instance.controller.onDragOver(e)}
onDragEnd={(_e, instance) => instance.controller.onDragEnd()}
onRowDrop={(e, instance) => instance.controller.onRowDrop(e)}
/>
<i
text-tpl="{infoMsg}"
class={{
"hidden": { expr: "!{infoMsgVisible}" },
"visible": { expr: "{infoMsgVisible}" }
}}
></i>
</div>In this case, we're not only dealing with drag and drop functionality, but
with the whole tree structure. After generating the data and saving it in
the store, the Grid will display all items. To enable drag and drop in
such hierarchy, we need to define dragSource (same as before), onRowDropTest
(specifies which record types can be dragged and dropped), onRowDragOver
(this callback checks whether dropping the dragged item is allowed, and controls
the displayed message below the Tree Grid), onDragEnd (removes the message),
and onRowDrop (this callback has access to the store, source and target
nodes, so that's where the tree update happens).