Last active
March 14, 2024 16:21
-
-
Save IlCallo/6abf4826a21662c7e8384a64c43aae53 to your computer and use it in GitHub Desktop.
Apply Drag and Drop to QTable rows using SortableJs
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Taken from https://github.com/angular/components/blob/master/src/cdk/drag-drop/drag-utils.ts | |
/** | |
* @license | |
* Copyright Google LLC All Rights Reserved. | |
* | |
* Use of this source code is governed by an MIT-style license that can be | |
* found in the LICENSE file at https://angular.io/license | |
*/ | |
/** Clamps a number between zero and a maximum. */ | |
function clamp(value: number, max: number): number { | |
return Math.max(0, Math.min(max, value)); | |
} | |
/** | |
* Moves an item one index in an array to another. | |
* @param array Array in which to move the item. | |
* @param fromIndex Starting index of the item. | |
* @param toIndex Index to which the item should be moved. | |
*/ | |
export function moveItemInArray<T = unknown>( | |
array: T[], | |
fromIndex: number, | |
toIndex: number | |
): void { | |
const from = clamp(fromIndex, array.length - 1); | |
const to = clamp(toIndex, array.length - 1); | |
if (from === to) { | |
return; | |
} | |
const target = array[from]; | |
const delta = to < from ? -1 : 1; | |
for (let i = from; i !== to; i += delta) { | |
array[i] = array[i + delta]; | |
} | |
array[to] = target; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<template> | |
<q-table :rows="rows" :columns="columns" row-key="name"> | |
<template #body-cell-drag-handle="props"> | |
<q-td :props="props"> | |
<q-icon name="drag_handle" class="drag-handle" /> | |
</q-td> | |
</template> | |
</q-table> | |
</template> | |
<script lang="ts"> | |
import Sortable from 'sortablejs'; | |
import { | |
defineComponent, | |
ref, | |
getCurrentInstance, | |
onMounted, | |
onUnmounted, | |
} from 'vue'; | |
import { moveItemInArray } from './move'; | |
const columns = [ | |
{ | |
name: 'drag-handle', | |
align: 'left', | |
}, | |
{ | |
name: 'name', | |
align: 'left', | |
label: 'Name', | |
field: 'name', | |
}, | |
]; | |
export default defineComponent({ | |
name: 'QTableDndShowcase', | |
setup() { | |
const rows = ref([ | |
{ name: 'Frozen Yogurt' }, | |
{ name: 'Ice cream sandwich' }, | |
{ name: 'Eclair' }, | |
]); | |
let sortable: Sortable; | |
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | |
const instance = getCurrentInstance()!.proxy!; | |
onMounted(() => { | |
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | |
const tableBody = ( | |
instance.$el as HTMLElement | |
).querySelector<HTMLElement>('.q-table > tbody')!; | |
// Check out other options at https://github.com/SortableJS/Sortable#options | |
sortable = Sortable.create(tableBody, { | |
handle: '.drag-handle', | |
animation: 150, | |
onUpdate({ oldIndex, newIndex }) { | |
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion | |
moveItemInArray(rows.value, oldIndex!, newIndex!); | |
}, | |
}); | |
}); | |
onUnmounted(() => { | |
sortable.destroy(); | |
}); | |
return { | |
columns, | |
rows, | |
}; | |
}, | |
}); | |
</script> | |
<style lang="scss" scoped> | |
.drag-handle { | |
cursor: move; | |
// stylelint-disable-next-line value-no-vendor-prefix | |
cursor: -webkit-grabbing; | |
} | |
</style> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment