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

Dnd does not work when adding new elements in list #107

Open
KuchinaPS opened this issue Oct 14, 2024 · 15 comments
Open

Dnd does not work when adding new elements in list #107

KuchinaPS opened this issue Oct 14, 2024 · 15 comments

Comments

@KuchinaPS
Copy link

KuchinaPS commented Oct 14, 2024

When adding a new element to the draggable list, the new element does not appear in the list, and when refreshing the page, it is not draggable.
How to correctly update the list of draggable elements when adding or removing from it?

I tried updateConfig({}), but nothing worked.

@sashamilenkovic
Copy link
Contributor

@KuchinaPS Hey there! Are the reactive values you are updating the same values that are bound to the list of items you are iterating over? It's hard to guess without seeing your code; I'd be happy to take a look at a reproduction

@KuchinaPS
Copy link
Author

KuchinaPS commented Oct 14, 2024

This is a similar implementation. Here, after moving elements in the list, adding new ones stops working. https://codesandbox.io/p/sandbox/eloquent-bird-9x2xgl

@sashamilenkovic
Copy link
Contributor

sashamilenkovic commented Oct 14, 2024

@KuchinaPS In your example, if I use something other than the index to set the key property, it works fine.

Here's how I updated your addNew function to use unique ids (not saying you explicitly need to use this crypto method, just an example).

const addNew = () => {
  const idx = dataList.value.length;
  const uuid = () => crypto.randomUUID();
  dataList.value.push({
    value: `${idx + 1}`,
    key: uuid(),
  });

  console.log(dataList.value);
};

@KuchinaPS
Copy link
Author

KuchinaPS commented Oct 14, 2024

In the example, everything really works fine. Maybe then the problem is in my receiving data from the backend or using the pinia storage.
Because my props.data value changes, but insideValue, which I use in the list, does not.

@sashamilenkovic
Copy link
Contributor

@KuchinaPS Yeah, shouldn't need to emit an update on the values that are "drag and dropped". My guess would be that the values you're getting from your pinia store are maybe not reactive/refs? \

@BradDuns
Copy link

I am seeing a similar problem. I am using realtime data from firestore that populates a pinia store.
I am using dragAndDrop so I can use the pinia ref for the data. This works for regular drag and drop and I can see the updates happening in the UI and in the database.

const { userData } = storeToRefs(contactsStore)
const groupsParent = ref(null)
dragAndDrop({
  parent: groupsParent,
  values: userData.value.contactOrder,
  dragHandle: '.groupHandle',
  onDragend: (event) => {
    groupOrderChanged(event.values)
  },
  onSort: (event) => {
    userData.value.contactOrder = event.values
  },
})
function groupOrderChanged(values) {
  userData.value.contactOrder = values
  contactsStore.updateContactOrder()
}

However if the data gets changed somewhere else the UI updates but it seems like the event.values don't.
For example if a value gets deleted on the server I see it removed from the list correctly but the console warns "The number of draggable items defined in the parent element..." and If I try to drag an element, the deleted item comes back when I finish dragging.

@KuchinaPS
Copy link
Author

I have the same error "The number of enabled nodes does not match the number of values." when adding and removing an element.

@BradDuns
Copy link

I adjusted KuchinaPS's example with a pinia store and the error I am seeing: https://codesandbox.io/p/sandbox/infallible-fog-fsv9zp?workspaceId=c8c26021-4482-4a8e-87a1-ee4197aaa807

As soon as you hit add it breaks.

@sashamilenkovic
Copy link
Contributor

sashamilenkovic commented Oct 14, 2024

@BradDuns Hey there! I took a look at your reproduction (appreciate it!). So, a couple things:

1). In your example, you are using storeToRefs to get a ref of your userData. That userData has a property, contactOrder, that is not a ref, meaning that when drag and drop updates the contact order array you provide to your dragAndDrop hook, your userData ref from your pinia store isn't going to update as well. So, you could either get contactOrders as a ref from your store, or, use a computed with a getter and setter based on the userData ref. I updated your dragAndDrop example here: https://codesandbox.io/p/sandbox/musing-wildflower-p6jw9x?workspaceId=6de9260e-0f69-4537-a09c-c9ecaac259e7.

2). useDragAndDrop hook is a composable that returns it's own reactive values, so it makes sense that your pinia store isn't getting updated.

3). And then just to put a fine point on this, in your code snippet where in your onSort callback you were assigning the values you were passing to the dragAndDrop hook to the event.values. That is unnecessary. The values you provide, when a sort occurs are being updated already by the library, there's no further work to do on that end.

@BradDuns
Copy link

BradDuns commented Oct 15, 2024

It's interesting, for me this causes the data to get wonky and duplicate keys in my project. There must be some other interaction that causes it to lose reactivity when it round trips through Firestore.
I updated the sandbox: https://codesandbox.io/p/sandbox/infallible-fog-fsv9zp?workspaceId=c8c26021-4482-4a8e-87a1-ee4197aaa807

This uses VueUse but I am using vueFire in my project with the same outcome.
• I drag an item in the list and see it update in the UI and on firestore. Everything looks right.
• I try to drag something else and it causes a duplicate. At that point there are objects with the same key so everything is messed up until I reset the database and reload the page.
• However, if I open it in 2 browsers I can update window 1, see the change in window 2, change in window 2, see the update in 1, etc. But as soon as I try to make changes back to back in one window it breaks

@sashamilenkovic
Copy link
Contributor

@BradDuns I'm seeing the same as you are in your reproduction there. I will take a look at it more closely when I have the chance.

@BradDuns
Copy link

Thanks! I’m not sure, but I wonder if it could be related to using a computed property for a nested object. I thought refs were deeply reactive, and I typically haven’t needed computed properties for this. With vue-draggable I'm passing the top level ref without issue. That said, I really like how much cleaner FormKit makes the template so trying to switch my app over.

@KuchinaPS
Copy link
Author

KuchinaPS commented Oct 17, 2024

Thanks for your help! My problem was solved by using dragAndDrop and computed for the value from the pinia store. But the values ​​started to duplicate. To avoid this, I used:

watch(list, () => {
remapNodes(question.value);
});

@BradDuns
Copy link

BradDuns commented Dec 3, 2024

remap for me didn't fix the issue. @sashamilenkovic have you had time to look at this issue at all?

@sashamilenkovic
Copy link
Contributor

@BradDuns Hey there! Apologies for not taking a look sooner, and I appreciate you reminding me. I have taken a look, and have resolved the issue (not deeply checking for equality in my filter function in performSort). A fix for this will be part of the next release.

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

No branches or pull requests

3 participants