SortableJS / Vue.Draggable

Vue drag-and-drop component based on Sortable.js
https://sortablejs.github.io/Vue.Draggable/
MIT License
19.99k stars 2.89k forks source link

problems with nesting #191

Closed ctf0 closed 7 years ago

ctf0 commented 7 years ago

update

David-Desmaisons commented 7 years ago

using v-model="childs" which is the same array that is used in the v-for gives error that its an object not array, shouldn't the same item that works for v-for also works for the v-model

@ctf0 v-model should be an array, if it is an object it will (could) not work

ctf0 commented 7 years ago

okay np, already passed that issue with v-model="childs.children", can u help me with the others as well ? 👍

David-Desmaisons commented 7 years ago

What is the next issue?

ctf0 commented 7 years ago
David-Desmaisons commented 7 years ago

@ctf0 , I guess issue like this would be better adressed on stackoverflow once it is not linked to feature or bug on vuedraggable but on its usage. Could you provide a jsfiddle and step by step scenario?

ctf0 commented 7 years ago

the reason i made the ticket is because i found lots of closed issues on the same subject, however all of the demos in those tickets have the one or same problems and couldn't find a valid solution for any, specially that the original lib that this package is built upon doesnt have the nesting feature.

and here is a fiddle u made on another ticket, with minor cleanup https://jsfiddle.net/v8gme77z/60/

it have the issues of

David-Desmaisons commented 7 years ago

Regarding the second problem, you are using incompatinle version of sortable and vuedraggablr. see this fidle: https://jsfiddle.net/dede89/bfksoj5b/

ctf0 commented 7 years ago

okay, will retry again on my local copy even through its showing a different error.

ctf0 commented 7 years ago

update

lots of issues are solved, thanx for the fiddle 💪 , now only the adding more nested items issue remains, which i think the problem is

so maybe a fix for that, we would add a new attribute to the option ex. nested: children and now when u try to move an item, draggable will check if the item u are trying to move under have an array = to the one in the option children

BubbleBear commented 7 years ago

@ctf0 i suppose your problems are related to this one: https://github.com/SortableJS/Vue.Draggable/issues/193 and https://github.com/SortableJS/Vue.Draggable#gotchas

ctf0 commented 7 years ago

for the first link, i already made the recursive comp, check the gif in the main ticket, but the problem is you cant create any more nesting levels other than the one already added, to understand what i mean test with @David-Desmaisons fiddle https://jsfiddle.net/dede89/bfksoj5b/

for the gotchas, i have

.dragArea {
    min-height: 35px;
    display: block;
}
<draggable class="dragArea">...</draggable>

but nothing new, maybe u mean something else ?

BubbleBear commented 7 years ago

@ctf0 1 i have no problem with it though.

David-Desmaisons commented 7 years ago

@ctf0 Do you have a children list in the leaf object? Without any further information I will close the issue and ask you to post this in stackoverflow.

ctf0 commented 7 years ago

@VernalVessel could u show me the code for this, or even a fiddle ?

@David-Desmaisons am sorry i dont know what u mean, but this is what i have atm untitled

David-Desmaisons commented 7 years ago

Share the corresponding tree data please.

ChrisShen93 commented 7 years ago

@VernalVessel Can you share your code ?

@ctf0 Have you solve your problem? If so, can you share your code ?

BubbleBear commented 7 years ago

@ChrisShen93 @ctf0 they're separated into many vue files, and i'm afraid it's a bit tough to convert them into fiddles. :(

ChrisShen93 commented 7 years ago

@VernalVessel Can we exchange QQ or wechat or other stuff to communicate ? I sincerely need help ... My QQ is 2587510238 , please add me if possible

ctf0 commented 7 years ago

@David-Desmaisons am sorry for the late delay, my connection was down for the last week, so here are the 2 comps i use


- child
```vue
<template>
    <draggable :list="childs"
        class="dragArea"
        :options="{draggable:'.item', group:'pages'}"
        :element="'ul'">
        <li v-for="item in childs" :key="item.id" class="item">
            <div>{{ item.title }}</div>

            <template v-if="item.children && item.children.length > 0">
                <menu-child :childs="item.children"></menu-child>
            </template>
        </li>
    </draggable>
</template>

<script>
import draggable from 'vuedraggable'

export default {
    name: 'menu-child',
    props: ['childs'],
    components: {draggable},
}
</script>

@ChrisShen93 sadly still no luck :cry: .

@VernalVessel i believe the components are mostly main and child for recursiveness, or do you need more to get the nesting to work ?

BubbleBear commented 7 years ago

@ctf0 i suppose your problems are related to this one:

193

and https://github.com/SortableJS/Vue.Draggable#gotchas

like i have said, your problem is the dragarea's size, you seem to define a min-height for it, while dragarea isn't the 'draggable' component but your nested component, move this class to 'menu-child' component.

ctf0 commented 7 years ago

actually whether i added the dragArea class or not, nothing changes, i wish you were right but sadly nothing is working.

ctf0 commented 7 years ago

@David-Desmaisons any news on this ? 🐈

David-Desmaisons commented 7 years ago

Hello @ctf0 I need a jsfiddle to work on this to figure out what is the problem. It really seems that this is linked to the usage of draggable and not the compnent itself.

ctf0 commented 7 years ago

@David-Desmaisons is it possible for u to make a fiddle that works correctly for nesting and i will try to find out the issue with my comps ?

David-Desmaisons commented 7 years ago

Here we go: https://jsfiddle.net/dede89/bfksoj5b/

ctf0 commented 7 years ago

thank you, but this is the same as old one, you can't create new levels of nesting, ex.

David-Desmaisons commented 7 years ago

This is because this example allows only one level of nesting. You should use a recursive component.

ctf0 commented 7 years ago

we are going in circles, thanx anyway & apologize for the long ticket.

David-Desmaisons commented 7 years ago

recursive example: https://jsfiddle.net/dede89/bfksoj5b/9/

ctf0 commented 7 years ago

@David-Desmaisons fockein awesome, many thanx

Update i figured out the issue, in order for draggable to be able to add new levels of nesting, u have to have an empty nest item under ur li items <ul class="dragArea"></ul>, which will work as an empty placeholder for draggable to add new items in that place.

in my comp code above the problem was v-if="item.children && item.children.length > 0" which prevent creating unnecessary empty items.

however what should happen is that draggable creates that item on the fly, otherwise we will have an empty space in our list.

old fiddle updated https://jsfiddle.net/bfksoj5b/11/

new "old" problem https://jsfiddle.net/bfksoj5b/12/ https://jsfiddle.net/bfksoj5b/14/

try to nest task 3 under task 4, the item will disappear

Update 2 fixed, not sure about the fiddle though, but the nested prop have to be an empty array (not null) or draggable wont be able to push into it.

mjamro commented 6 years ago

@ctf0 Would it be possible to use your updated fiddle to create an official example for nested draggable tree? It works perfectly however it's slightly hard to find/easy to miss (you need to dig through the github's issues).

ctf0 commented 6 years ago

@mariuszjamro i feel u, but honestly this was a daunting issue and i would rather not to go through it again.

still. what is the issue u r stuck at atm ?

mjamro commented 6 years ago

@ctf0 i don't have an issue any more - made it work based on info in this issue.

Can in submit a PR with draggable tree to the examples/ folder?

ctf0 commented 6 years ago

will see what i can do

satvikpendem commented 5 years ago

Any update on this? I'm also dealing with the same issue.

David-Desmaisons commented 5 years ago

@mariuszjamro a PR with this kind of example will be welcome

ZJH9Rondo commented 5 years ago

@David-Desmaisons how can i fix my question like this image

I have been try many times and read your documents about it , but no way to fix it.

the same question with this " in order for draggable to be able to add new levels of nesting, u have to have an empty nest item under ur li items

, which will work as an empty placeholder for draggable to add new items in that place. " @ctf0

shubh47-dddd commented 3 years ago

Please can I see the code where it is working. I am trying to create a nested drag and drop menu but not able to add nested children. Any working example would be appreciated.

kerwin-ly commented 1 year ago

I encountered the same issue but a little different. It's not working as I wrapped the <li> tag with <transition-group>. Like below

<draggable
    :list="tree"
    :group="{name: 'p1'}"
    v-bind="dragOptions"
    @start="drag = true"
    @end="drag = false"
    tag="div"
    class="drag-area"
  >
    <transition-group
      type="transition"
      :name="!drag ? 'flip-list' : null"
    >
      <div
        class="element-item"
        v-for="(item, index) in tree"
        :key="item.elementId"
      >
        <!-- ... -->
        <draggable-tree
          :tree="item.children"
          :parentIndex="parentIndex + (index + 1) + '.'"
        ></draggable-tree>
      </div>
    </transition-group>
  </draggable>

Then it's be fixed after I removed <transition-group>. Below is my code, hope this can help someone else.

// draggable-tree.vue
<template>
  <draggable
    :list="tree"
    :group="{name: 'p1'}"
    v-bind="dragOptions"
    tag="ul"
    class="drag-area"
  >
    <li
      class="element-item"
      v-for="(item, index) in tree"
      :key="item.elementId"
    >
      <div>
        <p>
          <span>{{ parentIndex + (index + 1) }}</span>
          <span>{{ item.content }}</span>
        </p>
        <p>
          {{ item.guideline }}
        </p>
      </div>
      <draggable-tree
        :tree="item.children"
        :parentIndex="parentIndex + (index + 1) + '.'"
      ></draggable-tree>
    </li>
  </draggable>
</template>

<style lang="scss" scoped>
.drag-area {
  min-height: 5px;
}
.element-item {
  padding: 10px 20px;
  border-top: 1px solid #ebebeb;
  border-left: 1px solid #ebebeb;
  border-right: 1px solid #ebebeb;
}
.element-item:not(:first-child) {
  padding-top: 10px;
  padding-bottom: 10px;
  padding-left: 20px;
}
.no-move {
  transition: transform 0s;
}
.ghost {
  opacity: 0.5;
  background: #c8ebfb;
}
.element-item {
  cursor: move;
}
.element-item i {
  cursor: pointer;
}
ul,
li {
  list-style: none;
}
</style>

<script>
import draggable from 'vuedraggable';

export default {
  components: {
    draggable,
  },
  name: 'DraggableTree',
  props: {
    tree: {
      required: true,
      type: Array,
    },
    parentIndex: {
      type: String,
      default: '',
    },
  },
  data() {
    return {};
  },
  computed: {
    dragOptions() {
      return {
        animation: 200,
        disabled: false,
        ghostClass: 'ghost',
      };
    },
  },
};
</script>
// App.vue
<template>
<draggable-tree :tree="elementList"></draggable-tree>
</template>

<script>
import DraggableTree from './components/DraggableTree.vue';

export default {
  components: { DraggableTree },
  data() {
    return {
      elementList: [
        {
          elementId: '1',
          content:
            'This is content1',
          guideline: 'This is guideline1',
          children: [
            {
              elementId: '1.1',
              content:
                'This is content1.1',
              guideline: 'This is guideline1.1',
              children: [
                {
                  elementId: '1.1.1',
                  content:
                    'This is content1.1.1',
                  guideline: 'This is guideline1.1.1',
                  children: [], // 'children' property should be an empty array not null if it's a leaf node
                },
              ],
            },
          ],
        }
      ]
    };
  },
  computed: {},
  mounted() {},
  methods: {},
};
</script>
linspw commented 1 year ago

I have the same problem, I can't make an object with empty children receive a new element