When ı using dragula for the drag and drop in vuejs project, the target index is returning wrongly

137 views Asked by At

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;
      });
0

There are 0 answers