Row Ordering (Drag & Drop)
This example features row drag and drop functionality using the @angular/cdk drag and drop directives.
| Username | Role | Account Status | Account Created On | Last Visited At | Visit Count | |
|---|---|---|---|---|---|---|
| Chelsie_Kohler | admin | suspended | 29 Apr 2025 06:08:26 PDT | 15 Jul 2025 11:10:46 PDT | 10 | |
| Lewis_Cummings | moderator | active | 18 Oct 2024 09:48:52 PDT | 21 Jul 2025 09:13:33 PDT | 75 | |
| Cyril.Gutkowski | moderator | active | 19 Oct 2024 17:33:13 PDT | 23 Nov 2024 00:52:27 PDT | 2 | |
| Virginia.Bayer2 | moderator | suspended | 05 Jan 2025 00:33:43 PDT | 12 Aug 2025 10:14:00 PDT | 357 | |
| Kim.Mante34 | user | pending | 07 Feb 2025 06:56:38 PDT | 16 Jul 2025 00:33:16 PDT | 71 | |
| Rhiannon_Auer | user | pending | 10 May 2025 08:59:18 PDT | 05 Aug 2025 01:29:01 PDT | 311 | |
| Anna_Schiller22 | moderator | pending | 04 Nov 2024 21:38:31 PDT | 29 Mar 2025 07:28:50 PDT | 7 | |
| Judd_Carroll3 | user | pending | 16 Sep 2025 06:36:31 PDT | 21 Sep 2025 03:51:58 PDT | 2 | |
| Jane.Haag49 | admin | suspended | 16 Apr 2024 16:53:43 PDT | 27 Apr 2025 03:21:25 PDT | 243 | |
| Fidel_Ledner | moderator | active | 21 Sep 2024 19:11:35 PDT | 29 Jul 2025 06:45:46 PDT | 276 |
import {
CdkDrag,
type CdkDragDrop,
CdkDragHandle,
CdkDropList,
moveItemInArray,
} from "@angular/cdk/drag-drop"
import {Component, effect, signal} from "@angular/core"
import {ButtonModule} from "@qualcomm-ui/angular/button"
import {ProgressRingModule} from "@qualcomm-ui/angular/progress-ring"
import {
type AngularTable,
createAngularTable,
TableModule,
} from "@qualcomm-ui/angular/table"
import {getCoreRowModel} from "@qualcomm-ui/core/table"
import {createUserQuery, type User, userColumns} from "./data"
@Component({
imports: [
TableModule,
ButtonModule,
ProgressRingModule,
CdkDropList,
CdkDrag,
CdkDragHandle,
],
selector: "row-dnd-demo",
template: `
<div q-table-root>
<div q-table-action-bar>
<button
q-button
size="sm"
variant="outline"
[disabled]="query.isFetching()"
(click)="query.refetch()"
>
Regenerate
</button>
@if (query.isFetching()) {
<div q-progress-ring size="xs"></div>
}
</div>
<div q-table-scroll-container>
<table q-table-table>
<thead q-table-header>
@for (
headerGroup of table.getHeaderGroups();
track headerGroup.id
) {
<tr q-table-row>
<th q-table-header-cell></th>
@for (header of headerGroup.headers; track header.id) {
<th
q-table-header-cell
[attr.colspan]="header.colSpan"
[style.width.px]="header.getSize()"
>
<ng-container *renderHeader="header; let value">
{{ value }}
</ng-container>
</th>
}
</tr>
}
</thead>
<tbody
cdkDropList
q-table-body
(cdkDropListDropped)="onRowDropped($event)"
>
@for (row of table.getRowModel().rows; track row.id) {
<tr cdkDrag q-table-row>
<td class="p-2" q-table-cell>
<button cdkDragHandle q-table-row-drag-handle></button>
</td>
@for (cell of row.getVisibleCells(); track cell.id) {
<td q-table-cell>
<ng-container *renderCell="cell; let value">
{{ value }}
</ng-container>
</td>
}
</tr>
}
</tbody>
</table>
</div>
</div>
`,
})
export class RowDndDemo {
protected readonly query = createUserQuery(10)
protected readonly mutableData = signal<User[]>([])
constructor() {
effect(() => {
const data = this.query.data()
if (data) {
this.mutableData.set([...data])
}
})
}
protected table: AngularTable<User> = createAngularTable(() => ({
columns: userColumns,
data: this.mutableData(),
getCoreRowModel: getCoreRowModel(),
getRowId: (row) => row.userId,
}))
onRowDropped(event: CdkDragDrop<User[]>) {
this.mutableData.update((data) => {
const newData = [...data]
moveItemInArray(newData, event.previousIndex, event.currentIndex)
return newData
})
}
}Last updated on by Ryan Bower