Hi, So I'm using this for the first time.
I'm using vue 3 and vue 3 DnD package
I'm trying to implement this on a form builder (think Microsoft forms).
I'm having a problem where I can drag up, and it'll work, but when I drag down it won't work
Here is a video of the problem
This is my HTML code (Removed some repetitive code as the block was getting longer)
<!-- Sections -->
<div
v-for="(_, sectionIndex) in formStructure"
:key="`section-${sectionIndex}`"
class="mb-8 bg-base-200 border border-primary-focus rounded-md py-4"
>
<h3
class="text-3xl mb-8 px-2 md:px-6 underline decoration-primary-focus underline-offset-8 opacity-70"
>
Section #{{ sectionIndex + 1 }}
</h3>
<Container
group-name="1"
@drop="onDrop(sectionIndex, $event)"
:get-child-payload="getChildPayload(sectionIndex)"
drag-class="bg-accent"
lock-axis="y"
@drag-end="null"
class="h-full bg-black"
>
<!-- Questions -->
<Draggable
v-for="(question, index) in formStructure[sectionIndex]"
class="px-2 md:px-6 pb-8 pt-4 mb-4 text-2xl border-b border-primary border-opacity-40"
:key="`question-${index}`"
drag-handle-selector="drag-handle"
>
<!-- Drag Icon / Anchor -->
<div
class="w-full flex justify-center hover:text-primary text-base-content cursor-grab"
>
<i-ci-drag-horizontal @mousedown.left="null" />
</div>
<!-- Question -->
<QuestionStatement
v-model="question.statement"
:index="index"
:question="question"
@deleteQuestion="deleteQuestion(index, sectionIndex)"
/>
<!-- Question Content -->
<div v-if="!reorder">
<!-- Choice Question -->
<div
v-if="question.type == 'single' || question.type == 'multiple'"
class="w-full"
>
<div class="mt-4">
<ChoiceOptions
:index="index"
:optionIndex="optionIndex"
:type="question.type"
@deleteOption="(question as ChoiceClass).deleteOption(optionIndex)"
v-for="(option, optionIndex) in (question as ChoiceClass).options"
v-model:value="option.value"
v-model:score="option.score"
:key="`question-${index}-option-${optionIndex}`"
/>
<!-- Place Holder Only -->
<CommentAndImage :question="question" />
</div>
<!-- Actions -->
<div
class="grid grid-cols-2 lg:flex lg:items-end lg:justify-end gap-4 mt-8"
>
<CommentAndImageButtons :question="question" />
<button
class="btn btn-sm btn-primary btn-outline"
@click="(question as ChoiceClass).addOption()"
>
Add Option
</button>
<button
class="btn btn-sm btn-primary btn-outline"
@click="(question as ChoiceClass).addOtherOption()"
>
Add 'Other' Option
</button>
</div>
...
</div>
</div>
</Draggable>
</Container>
</div>
This is my JS code
...
import { Container, Draggable } from "vue3-smooth-dnd";
...
...
const showForm = ref(true);
const reorder = ref(false);
const getChildPayload = function (sectionIndex: number) {
return (index: number) => {
return formStructure[sectionIndex][index];
};
};
const onDrop = (sectionIndex: number, { removedIndex, payload, addedIndex }) => {
console.log(removedIndex, addedIndex);
showForm.value = false;
if (removedIndex === null && addedIndex === null) return;
const result = [...formStructure[sectionIndex]];
if (removedIndex !== null) {
result.splice(removedIndex, 1)[0];
}
if (addedIndex !== null) {
result.splice(addedIndex, 0, payload);
}
formStructure[sectionIndex] = result;
showForm.value = true;
};
This is my data object
[
[
{
"position": 2,
"type": "matrix",
"statement": "Question 2",
"comment": false,
"image": false,
"subQuestions": [
{
"statement": "Please Type Your Question",
"comment": false
},
{
"statement": "Please Type Your Question",
"comment": false
}
],
"optionsCount": 5,
"options": [
{
"value": "Option"
},
{
"value": "Option"
},
{
"value": "Option"
},
{
"value": "Option"
},
{
"value": "Option"
}
]
},
{
"position": 1,
"type": "multiple",
"statement": "Question 1",
"comment": false,
"image": false,
"options": [
{
"value": "Option 1",
"score": "1"
},
{
"value": "Option 2",
"score": "2"
}
]
}
]
]
As I was trying this package for the first time... I made a trial, and that worked perfectly (It's got the same JS logic)
<script setup>
import { Container, Draggable } from "vue3-smooth-dnd";
import { reactive } from "vue";
let items = reactive([
[
"item 0-0",
"item 0-1",
"item 0-2",
],
[
"item 1-0",
"item 1-1",
"item 1-2",
],
]);
const getChildPayload = function (listIndex) {
return (index) => {
return items[listIndex][index];
};
};
const onDrop = (listIndex, { removedIndex, payload, addedIndex }) => {
if (removedIndex === null && addedIndex === null) return;
const result = [...items[listIndex]];
if (removedIndex !== null) {
result.splice(removedIndex, 1)[0];
}
if (addedIndex !== null) {
result.splice(addedIndex, 0, payload)
}
items[listIndex]=result;
};
</script>
<!-- Your Markup Here -->
<template>
<div>
<div class="flex justify-center gap-x-12">
<div
v-for="(item, listIndex) in items"
:key="`section-${listIndex}`"
class="border border-primary mx-8"
>
<Container
group-name="1"
@drop="onDrop(listIndex, $event)"
:get-child-payload="getChildPayload(listIndex)"
>
<Draggable
v-for="(subItem, subIndex) in item"
:key="`subItem-${subIndex}`"
class="px-4 border-b border-primary-focus last-of-type:border-0 py-4"
>
<div>{{ subItem }}</div>
</Draggable>
</Container>
</div>
</div>
</div>
</template>
Sorry for the long post, but I'm at the end of my wits trying to figure this out
Thanks in advance