Component drag more than one item
Closed this issue · 3 comments
camohub commented
I have almost whole implementation done. I am using slots and inside default slot I use another simple component with simple drop down menu for actions. This nested component causes the problem when I drag item. I takes more than one item while dragging. This is the code.
<template>
<Draggable v-model="treeData"
:childrenKey="childrenKey"
:textKey="titleKey"
:defaultOpen="false"
:keepPlaceholder="true"
:indent="30"
>
<template #default="{ node, stat }">
<div class="category">
<div class="category-title">
<div class="category-title__text">
<div class="drag-drop">
<Iconbase name="DragDrop"></Iconbase>
</div>
{{ node[titleKey] }}
</div>
<div class="category-title__buttons">
<div v-if="stat.children && stat.children.length"
@click="toggleNestedItems(stat.data[idKey])"
:class="{ active: activeId === stat.data[idKey], arrow: true }"
>
<Iconbase name="Arrowdown" height="10" width="10"></Iconbase>
</div>
<div class="edit">
<EditActions :id="stat.data[idKey]" :options="actions" @editactions="action($event)" />
</div>
</div>
</div>
</div>
</template>
<template #placeholder="{tree}">
<div>
<span class="mtl-ml"></span>
</div>
</template>
</Draggable>
</template>
<script lang="ts" setup>
import { BaseTree, Draggable, dragContext } from '@he-tree/vue'
import '@he-tree/vue/style/default.css'
import '@he-tree/vue/style/material-design.css'
import EditActions from '@/components/ui/button/EditActions.vue'
import Iconbase from '@/components/icons/Iconbase.vue'
import { ref, defineProps, computed } from 'vue'
// Component props
const props = defineProps({
items: {
type: Array,
required: true
},
// This is universal component which should handle any items object with its own keys.
// Keys which component will use to access items object properties.
// Component uses this: id, title, description, childrenKey
idKey: {
type: String,
default: 'id',
},
titleKey: { // The item.key which will be used as title
type: String,
default: 'title',
},
childrenKey: { // The item.key where nested items are stored eg. item.children or item.subcategory
type: String,
default: 'children',
},
translateKeys: []
})
// Component emits (events)
const emit = defineEmits(['action'])
// EditActions component options
const actions = [
{ name: 'create_nested_item', ico: 'Pluscircle' },
{ name: 'edit', ico: 'Penciledit' },
{ name: 'delete', ico: 'Delete' }
]
let activeId = ref(-1)
let unsavedChanges = ref(false)
let treeData = computed({
get() {
console.log('treeData::get()')
console.log(props.items)
return props.items
},
set(value) {
console.log('treeData::set()')
console.log(value)
}
})
function logList() {
console.log('change')
console.log(props.items)
}
function action(event) {
console.log('NestedDraggable action')
console.log(event)
emit('action', event)
}
function toggleNestedItems(id) {
console.log('toggleOpen')
console.log(id)
activeId.value = activeId.value === id
? -1 // Zatvorí sa aktívny accordion
: id // Otvorí sa vybraný accordion
}
</script>
And this is the EditActions components which causes the problem
<template>
<div ref="target" @click="openMenu($event)" class="c-edit-button" :class="{ active: editOnOff }">
<div class="c-edit-button-target">
<Iconbase name="Editdots" width="4" height="15" />
</div>
<div class="c-edit-button-list" :style="style" ref="list">
<div v-for="(option, index) in props.options" :key="index" class="c-edit-button-item" @click="setActiveAction(option.name)">
<Iconbase :name="option.ico" width="17" height="17" />
{{ $t(option.name) }}
</div>
</div>
</div>
</template>
<script lang="ts" setup>
import Iconbase from '@/components/icons/Iconbase.vue'
import { PropType, ref, onMounted } from 'vue'
import { ButtonEditProps } from '@/types/button/Buttonedit.types'
import { onClickOutside } from '@vueuse/core'
const editOnOff = ref<boolean>(false)
const target = ref(null)
const actionList = ref()
const style = ref()
const height = ref()
const emit = defineEmits(['editactions'])
const props = defineProps({
id: {
type: Number as PropType<ButtonEditProps['id']>,
required: true
},
options: {
type: Object as () => ButtonEditProps['options'],
required: true
}
})
onClickOutside(target, () => (editOnOff.value = false))
function openMenu(event: any) {
editOnOff.value = !editOnOff.value
if (event.screenY + height.value > window.outerHeight) {
style.value = 'bottom: 30px; top: unset;'
}
}
function setActiveAction(item: string) {
emit('editactions', {
action: item.toLowerCase(),
id: props.id
})
}
onMounted(() => {
height.value = actionList.value?.offsetHeight
})
</script>
phphe commented
can you create a online reproduce on codepen or others?
camohub commented
Is there any codepen with all settings for this which I could clone? I dont know how to prepare it.