wuyuedefeng / vue-sortable-tree

vue tree draggable, drag item sort
90 stars 21 forks source link

Can I extend isAllowToDrop() method? #15

Open stryaponoff opened 6 years ago

stryaponoff commented 6 years ago

Hello. I need a custom function to prevent some drag operations in my tree. Is this component allows such operations?

If such functionality is not implemented yet should I make a pull request if I'll write it for myself?

nautilebleu commented 6 years ago

I'm also interested :)

nautilebleu commented 6 years ago

FTR, I done this by tracking the changes in the changePosition method: I check some properties of options.afterParent and if it doesn't match, revert the node to options.beforeParent using options.beforeIndex.

While not perfect (I'd have a ghost of the node flying back to the previous position), it does the job!

msouidi309 commented 6 years ago

Hi @nautilebleu, could you please show how you performed it ? I'm really interested, i'm working on a project and i don't want a 'leaf' to 'become' a folder

nautilebleu commented 6 years ago

When a node is dropped, it triggers the changePosition method. In my case, I need to prevent dropping on node that have action !== 'button' (except for create a new root)

export default {
  name: 'Tree',
  methods: {
    _canDrop (option) {
      if (option.afterParent.action === 'button' ||
          option.afterParent.depth === 0) {
        return true
      }
      return false
    },
    _moveNode (option) {
      // sends the move to the backend
    },
    _revertNode (option) {
      // reset the node to its position before the drag and drop
      let found = false
      option.beforeParent.children.forEach(function (item, idx) {
        if (found === false && idx === option.beforeIndex) {
          found = true
          option.beforeParent.children.splice(
            option.beforeIndex, 0, option.data)
        }
      })
      found = false
      option.afterParent.children.forEach(function (item, idx) {
        if (found === false && item.id === option.data.id) {
          option.afterParent.children.splice(idx, 1)
        }
      })
    },
    changePosition: function (option) {
      if (this._canDrop(option) === true) {
        this._moveNode(option)
      } else {
        this._revertNode(option)
      }
    }
  }
}
msouidi309 commented 6 years ago

Thanks a lot, i added this on the isAllowToDrop function :

isAllowToDrop () {
    return !(this.isNextToMe || this.isParent || this.isMeOrMyAncestor || !this.hasChildren(this))
}

and it works

nautilebleu commented 6 years ago

But if you do that, you change the code of Vue-Sortable-Tree so you need to fork ?

msouidi309 commented 6 years ago

I don't know what is fork ?

nautilebleu commented 6 years ago

The goal of using an external library such as Vue-Sortable-Tree is to use it "as it is", without changing its code.

If you have installed it with a package manager such as npm, the changes will be erased when you update the lib. And your change are not available to your coworkers.

So when a lib doesn't do what you want, you should fork it (make a copy with git) and do your changes in your copy.

If your changes are of general interest for everyone, once your copy is available on github, you can ask the main dev to merge your changes in its repository via a Pull Request (aka a PR) If your changes are only for you, at least it will help you merge the updates in your repository so you can quickly integrate new functionnalities and bug fixes.