vue-smooth-dnd icon indicating copy to clipboard operation
vue-smooth-dnd copied to clipboard

Directive version errors

Open stuta opened this issue 5 years ago • 1 comments

Motivation

This library uses components, but with components you have to create divs around container and code creates divs around draggable items. It is slow and doubles the dom element amount.

Another big problem is that those divs break flexbox.

So I made a small directive using plain smooth-dnd.

Problems

  1. For some reason if I don't import vue-smooth-dnd the I get his error on drag start: Uncaught TypeError: Failed to execute 'appendChild' on 'Node': parameter 1 is not of type 'Node'.
  2. The other problem is that css display: block (below) breaks flexbox. When I change it to display: flex then I get and error: Uncaught TypeError: Cannot read property 'setDraggables' of undefined.

Prolem css

.smooth-dnd-container.vertical > .smooth-dnd-draggable-wrapper {
	display: flex !important; /* was: display: block; */
}

Usage example

<div v-nc-dnd-container="{groupName: '1', behaviour: 'copy', getChildPayload: getElementPayload, onDrag: onDrag,	onDrop: onDrop}">
    <div v-nc-dnd-draggable="v-nc-dnd-draggable" v-for="(item, index) in arr.element" :key="index">{{item.value}}</div>
</div>

Directive code

This version of code is modified and untested.

// vue-smooth-dnd-directive.js

import { smoothDnD } from 'smooth-dnd'
import 'vue-smooth-dnd/dist/vue-smooth-dnd.esm.js' // error if this is not imported

export const vueSmoothDndDraggable = {
	bind: function (el, binding, vnode) {
		el.classList.add('smooth-dnd-draggable-wrapper')
	}
}

export const vueSmoothDndContainer = {
	bind: function (el, binding) {
		if (el.vueSmoothDndInstance) {
			console.error('v-vue-smooth-dnd-container el.vueSmoothDndInstance exists, it should not exist', el)
			el.vueSmoothDndInstance.dispose()
		}
		let options = binding.value || {}
		if (typeof options !== 'object') {
			console.error('v-vue-smooth-dnd-container options is not an object', el, binding.value)
			options = {}
		}
		el.vueSmoothDndInstance = smoothDnD(el, options)
	},
	unbind: function (el) {
		if (el.vueSmoothDndInstance) {
			el.vueSmoothDndInstance.dispose()
		} else {
			console.error('v-vue-smooth-dnd-container destroy, instance does not exist, el:', el)
		}
	}
}

stuta avatar Apr 20 '19 16:04 stuta

The other problem is that css display: block (below) breaks flexbox. When I change it to display: flex then I get and error: Uncaught TypeError: Cannot read property 'setDraggables' of undefined.

  • I was able to fix css problems with overriding my own correct styles with display: flex !important;.
  • This Uncaught TypeError: Cannot read property 'setDraggables' of undefined error was solved by arranging container and draggable directives in right order.

I would like to know how vue-smooth-dnd changes basic smooth-dnd so that it starts to work.

stuta avatar Apr 20 '19 22:04 stuta