I want to add the drag and drop feature to the sidebar containing my slide cards. In this way, I aim to be able to change the location of my slides correctly.
Problem: The slide-card elements are put in the wrong order when the drags items. Because sometimes slide-card elements are not indexing as they appear in the dom.
The html file is below.
<div class="c-side-bar__opened__container__navbar" v-model="isSidebarOpen" ref="slideCards">
<template v-for="(slide, index) in slides">
<li
class="c-side-bar__opened__container__navbar__slide"
:class="{
'c-side-bar__opened__container__navbar__slide--hover': index === activeSlideIndex,
}"
:data-index="index"
:key="slide.ID"
>
<div
class="c-side-bar__opened__container__navbar__slide__card"
:class="{
'c-side-bar__opened__container__navbar__slide__card--hover': index === activeSlideIndex,
}"
>
<slide-card
:slideID="slide.ID"
:data-index="index"
:index="index"
:key="slide.ID"
:totalCount="slides.length"
:isSideBarComponent="isSideBarComponent"
>
</slide-card>
</div>
<span
class="c-side-bar__opened__container__navbar__slide__index"
:class="{'c-side-bar__opened__container__navbar__slide__index--hover': index === activeSlideIndex }"
>{{ index + 1 }}</span
>
</li>
</template>
<li class="c-side-bar__opened__container__navbar__slide c-side-bar--add-slide">
<app-button type="icon" theme="secondary" size="large" @click="addSlide">
<app-icon name="plus"></app-icon>
</app-button>
</li>
</div>
The ts file is below.
this.dragula = dragula([this.$refs.slideCards as Element], {
direction: 'horizantal',
isContainer: (el: Element) => {
if (!this.draggedSlide) {
return false;
}
if (el.classList.contains('c-side-bar__opened__container__navbar__slide__card')) {
const targetIndex = parseInt(el.getAttribute('data-index'), 10);
// The error is here. Sometimes, the data-index of the HTML element is not the same in the order it appears in the dom.
this.draggedSlide.targetIndex = targetIndex;
}
return false;
},
})
.on('drag', (draggingSlideCard: HTMLElement) => {
this.isDragging = true;
this.draggedSlide = {
sourceIndex: parseInt(draggingSlideCard.getAttribute('data-index'), 10),
targetIndex: parseInt(draggingSlideCard.getAttribute('data-index'), 10),
};
})
.on('drop', () => {
if (!this.draggedSlide) {
return;
}
// saves new slides whose order has changed.
this.moveSlide(this.draggedSlide.sourceIndex, this.draggedSlide.targetIndex);
this.draggedSlide = null;
this.isDragging = false;
});