-
Daniel Göbel authoredDaniel Göbel authored
DraggableLists.vue 2.60 KiB
<script setup lang="ts">
import { onMounted, ref } from "vue";
import Sortable from "sortablejs";
const leftList = defineModel<string[]>("leftList", { required: true });
const rightList = defineModel<string[]>("rightList", { required: true });
const leftListElement = ref<HTMLUListElement | undefined>(undefined);
const rightListElement = ref<HTMLUListElement | undefined>(undefined);
onMounted(() => {
if (leftListElement.value && rightListElement.value) {
new Sortable(leftListElement.value, {
group: "shared",
animation: 150,
sort: false, // To disable sorting: set sort to false
onRemove: (evt) => {
leftList.value.splice(evt.oldIndex ?? 0, 1);
},
onAdd: (evt) => {
leftList.value.splice(
evt.newIndex ?? 0,
0,
(evt.item as HTMLLIElement).innerText,
);
},
});
new Sortable(rightListElement.value, {
group: "shared",
animation: 150,
sort: false, // To disable sorting: set sort to false
onRemove: (evt) => {
rightList.value.splice(evt.oldIndex ?? 0, 1);
},
onAdd: (evt) => {
rightList.value.splice(
evt.newIndex ?? 0,
0,
(evt.item as HTMLLIElement).innerText,
);
},
});
}
});
</script>
<template>
<div class="row">
<div class="col-6 d-flex flex-column justify-content-start">
<h5><slot name="leftHeader" /></h5>
<ul
id="items"
class="list-group flex-fill border border-dashed p-1 overflow-y-scroll"
ref="leftListElement"
style="max-height: 40vh"
>
<li
v-for="(left, index) in leftList"
class="list-group-item"
:key="left"
@click="
rightList.push(left);
leftList.splice(index, 1);
"
>
{{ left }}
</li>
</ul>
</div>
<div class="col-6 d-flex flex-column justify-content-start">
<h5><slot name="rightHeader" /></h5>
<ul
id="items"
class="list-group flex-fill border border-dashed p-1 overflow-y-scroll"
ref="rightListElement"
style="max-height: 40vh"
>
<li
v-for="(right, index) in rightList"
class="list-group-item"
:key="right"
@click="
leftList.push(right);
rightList.splice(index, 1);
"
>
{{ right }}
</li>
</ul>
</div>
</div>
</template>
<style scoped>
li:hover {
cursor: grab;
background: var(--bs-secondary-bg-subtle);
}
.border-dashed {
border-style: dashed !important;
}
</style>