1# Drag-and-Drop Sorting 2 3By using **ForEach**, **LazyForEach**, or **Repeat** within a **List** component and setting up the **onMove** event, you can implement drag-and-drop sorting. When the drag-and-drop gesture is released, if any item's position changes, the **onMove** event is triggered, which reports the original index and target index of the relocated item. In the **onMove** event, the data source must be updated based on the reported start index and target index. Ensure that only the order of the data changes so that the drop animation can be executed properly. 4 5> **NOTE** 6> 7> The initial APIs of this module are supported since API version 12. Updates will be marked with a superscript to indicate their earliest API version. 8 9## onMove 10 11onMove(handler: Optional\<OnMoveHandler\>) 12 13Invoked when data is moved during drag-and-drop sorting. This callback is effective only when the parent container component is [List](./ts-container-list.md) and each iteration of **ForEach**, **LazyForEach**, or **Repeat** generates a **ListItem** component. It allows you to define custom drag actions and handle various drag events. 14 15**Atomic service API**: This API can be used in atomic services since API version 12. 16 17**System capability**: SystemCapability.ArkUI.ArkUI.Full 18 19**Parameters** 20 21| Name| Type | Mandatory| Description | 22| ------ | --------- | ---- | ---------- | 23| handler | Optional\<[OnMoveHandler](#onmovehandler)\> | Yes | Drag operation.| 24 25## onMove<sup>20+</sup> 26 27onMove(handler: Optional\<OnMoveHandler\>, eventHandler: ItemDragEventHandler) 28 29Invoked when data is moved during drag-and-drop sorting. This callback is effective only when the parent container component is [List](./ts-container-list.md) and each iteration of **ForEach**, **LazyForEach**, or **Repeat** generates a **ListItem** component. It allows you to define custom drag actions and handle various drag events. 30 31**Atomic service API**: This API can be used in atomic services since API version 20. 32 33**System capability**: SystemCapability.ArkUI.ArkUI.Full 34 35**Parameters** 36 37| Name| Type | Mandatory| Description | 38| ------ | --------- | ---- | ---------- | 39| handler | Optional\<[OnMoveHandler](#onmovehandler)\> | Yes | Drag operation.| 40| eventHandler | [ItemDragEventHandler](#itemdrageventhandler20) | Yes | Callback invoked when the drag occurs.| 41 42## OnMoveHandler 43 44type OnMoveHandler = (from: number, to: number) => void 45 46Defines the callback triggered when data is moved during drag-and-drop sorting. 47 48**Atomic service API**: This API can be used in atomic services since API version 12. 49 50**System capability**: SystemCapability.ArkUI.ArkUI.Full 51 52**Parameters** 53 54| Name| Type | Mandatory| Description | 55| ------ | --------- | ---- | ---------- | 56| from | number | Yes | Start index of the drag operation. The value range is [0, data source length - 1].| 57| to | number | Yes | End index of the drag operation. The value range is [0, data source length - 1].| 58 59## ItemDragEventHandler<sup>20+</sup> 60 61Defines callbacks for drag events on a data source, allowing you to respond to different drag operations. 62 63**Atomic service API**: This API can be used in atomic services since API version 20. 64 65**System capability**: SystemCapability.ArkUI.ArkUI.Full 66 67**Parameters** 68 69| Name| Type | Mandatory| Description | 70| ------ | ------ | ---- | -------------------- | 71| onLongPress | [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<number\> | No | Callback triggered when an item is long-pressed.<br>- **index**: index of the target when the long press occurs.| 72| onDragStart | [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<number\> | No | Callback triggered when dragging starts.<br>- **index**: index of the target when dragging starts.| 73| onMoveThrough | [OnMoveHandler](#onmovehandler) | No | Callback triggered when the dragged item moves over other items.| 74| onDrop | [Callback](../../apis-basic-services-kit/js-apis-base.md#callback)\<number\> | No | Callback triggered when dragging ends.<br>- **index**: index of the target when dragging ends.| 75 76## Example 77 78### Example 1: Using onMove for Drag and Drop Operations 79 80This example demonstrates how to use **onMove** for drag and drop with **ForEach** in a **List** component. 81 82```ts 83@Entry 84@Component 85struct ForEachSort { 86 @State arr: Array<string> = []; 87 88 build() { 89 Row() { 90 List() { 91 ForEach(this.arr, (item: string) => { 92 ListItem() { 93 Text(item.toString()) 94 .fontSize(16) 95 .textAlign(TextAlign.Center) 96 .size({height: 100, width: '100%'}) 97 }.margin(10) 98 .borderRadius(10) 99 .backgroundColor('#FFFFFFFF') 100 }, (item: string) => item) 101 .onMove((from:number, to:number) => { 102 let tmp = this.arr.splice(from, 1); 103 this.arr.splice(to, 0, tmp[0]); 104 }) 105 } 106 .width('100%') 107 .height('100%') 108 .backgroundColor('#FFDCDCDC') 109 } 110 } 111 aboutToAppear(): void { 112 for (let i = 0; i < 100; i++) { 113 this.arr.push(i.toString()); 114 } 115 } 116} 117``` 118 119### Example 2: Using onMove with Drag Event Callbacks 120 121This example demonstrates how to use **onMove** with additional drag event callbacks when **ForEach** is used in a **List** component. 122 123```ts 124// xxx.ets 125@Entry 126@Component 127struct ListOnMoveExample { 128 private arr: number[] = [0, 1, 2, 3, 4, 5, 6]; 129 130 build() { 131 Column() { 132 List({ space: 20, initialIndex: 0 }) { 133 ForEach(this.arr, (item: number) => { 134 ListItem() { 135 Text('First list' + item) 136 .width('100%') 137 .height(80) 138 .fontSize(16) 139 .textAlign(TextAlign.Center) 140 .borderRadius(10) 141 .backgroundColor(0xFFFFFF) 142 } 143 }, (item: string) => item) 144 .onMove((from: number, to: number) => { 145 let tmp = this.arr.splice(from, 1); 146 this.arr.splice(to, 0, tmp[0]); 147 console.log('List onMove From: ' + from); 148 console.log('List onMove To: ' + to); 149 }, 150 { 151 onLongPress: (index: number) => { 152 console.log('List onLongPress: ' + index); 153 }, 154 onDrop: (index: number) => { 155 console.log('List onDrop: ' + index); 156 }, 157 onDragStart: (index: number) => { 158 console.log('List onDragStart: ' + index); 159 }, 160 onMoveThrough: (from: number, to: number) => { 161 console.log('List onMoveThrough From: ' + from); 162 console.log('List onMoveThrough To: ' + to); 163 } 164 } 165 ) 166 }.width('90%') 167 .scrollBar(BarState.Off) 168 }.width('100%').height('100%').backgroundColor(0xDCDCDC).padding({ top: 5 }) 169 } 170} 171``` 172