Closed MartinMalinda closed 1 month ago
It seems like the behavior is different for changing sort in the list and when moving things across lists.
For changing order I can find list.value =
set.
https://github.com/Alfred-Skyblue/vue-draggable-plus/blob/main/src/useDraggable.ts#L175
But for the onAdd
and onRemove
, there's no setting of list.value
which seems like a bug to me? It seems like there's a purposeful unRef
and then the native array is sliced (or pushed to). Almost as if to intentionally avoid reactivity?
Noticed this too. Was extremely happy seeing someone took up the torch to keep vue3 up to date with sortablejs. However, using computed wrapper does not work with this package :/
This is how i've done it using the outdated vuedraggable package which i hoped would still work for this but it doesnt..
const request = ref<UpdateCustomerProductAccessRequest>({
customerId: props.customer.id,
productIds: cloneDeep(props.customer.productAccesses),
});
const productsWithoutAccess = computed({
get: () => sortedProducts.value.filter(product => !request.value.productIds.includes(product.id)),
set: (v) => {
v.forEach(product => {
const index = request.value.productIds.indexOf(product.id);
if (index >= 0) {
request.value.productIds.splice(index, 1);
}
});
},
});
const productsWithAccess = computed({
get: () => sortedProducts.value.filter(product => request.value.productIds.includes(product.id)),
set: (v) => {
v.forEach(product => {
const index = request.value.productIds.indexOf(product.id);
if (index < 0) {
request.value.productIds.push(product.id);
}
});
},
});
<div class="flex flex-col flex-1 col-span-6 overflow-hidden">
<p class="text-center text-14 mb-3 font-bold">
No Access
</p>
<Draggable v-model="productsWithoutAccess"
:animation="products.length > 50 ? 0 : 200"
:sort="false"
:disabled="false"
class="flex flex-col gap-3 bg-background p-3 flex-1 border border-border overflow-auto"
:group="{ name: 'product-accesses', pull: true, put: true }"
ghost-class="ghost">
<CustomerProductAccessesProduct v-for="product in productsWithoutAccess" :key="product.id" :product="product"/>
</Draggable>
</div>
<div class="flex flex-col flex-1 col-span-6 overflow-hidden">
<p class="text-center text-14 mb-3 font-bold">
Access
</p>
<Draggable v-model="productsWithAccess"
:animation="products.length > 50 ? 0 : 200"
:sort="false"
:disabled="false"
class="flex flex-col gap-3 bg-background p-3 flex-1 border border-border overflow-auto"
:group="{ name: 'product-accesses', pull: true, put: true }"
ghost-class="ghost">
<CustomerProductAccessesProduct v-for="product in productsWithAccess" :key="product.id" :product="product"/>
</Draggable>
</div>
</div>
the setters are not triggered when moving from list A to list B :/ I could add the data into 2 seperate ref<[]> objects but that requires more boilerplate to ensure they get populated when the api promise returns etc..
+1
I fixed this back then for myself by forking, published here:
https://www.npmjs.com/package/vue-draggable-plus-plus
But beware, I may have broken other functionality while fixing it for my usecase.
(commits: https://github.com/MartinMalinda/vue-draggable-plus/commits/main/)
Minimal repro:
https://codesandbox.io/p/sandbox/vue-draggable-plus-dual-list-setters-5wl5qm
If you drag items as part of one list, it works well. Once you try to drag across lists, the setters do not get called.
This worked for me before I switched the original package (vue draggable next) for this one. So something must have broken it after the fork.