Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dual list does not work with getter and setters #77

Closed
MartinMalinda opened this issue Dec 23, 2023 · 4 comments
Closed

Dual list does not work with getter and setters #77

MartinMalinda opened this issue Dec 23, 2023 · 4 comments

Comments

@MartinMalinda
Copy link

MartinMalinda commented Dec 23, 2023

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.

@MartinMalinda
Copy link
Author

MartinMalinda commented Dec 24, 2023

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?

@VincentVanclef
Copy link

VincentVanclef commented Jan 13, 2024

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..

@ronannnn
Copy link

+1

@MartinMalinda
Copy link
Author

MartinMalinda commented May 16, 2024

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/)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants