I'm trying to make a boostrap 5 carousel draggable using drag and drop API. I have a problem when the carousel is dragged into another position where it can be dropped, it will lose all css settings that are in my vue component css and I will not be able to moove it again. How I can fix this and make the carousel and it's content draggable?
COMPONNENT HTML
<div class="row widget-area position-absolute m-0">
<div class="col-3 pt-2 pb-2 dropzone" @drop.prevent="onDrop($event)" @dragover.prevent @dragenter.prevent="onDragenter($event)" @dragleave="onDragleave($event)">
<div id="newsCarousel" class="carousel slide position-absolute" data-ride="carousel" draggable="true" @dragstart="startDrag($event)">
<!-- carousel inner -->
<div class="carousel-inner" draggable="true">
<div class="carousel-item card draggable-el position-absolute" :class="{ 'active': index === 0 }" :id="index" v-for="( news, index ) in newsfeed.articles" :key="index" draggable="true">
<img class="card-img-top" :src="news.image" :id="index" draggable="true" @dragstart="startDrag($event)">
<div class="card-body p-2">
<a class="text-decoration-none text-body" :href="news.source.url">
<small class="d-block text-muted">{{ news.source.name }}</small>
</a>
<a class="h6 text-decoration-none text-body card-title stretched-link" :href="news.url">{{ news.title }}</a>
</div>
</div>
</div>
<!-- carousel controls -->
<a class="carousel-control-prev" href="#newsCarousel" role="button" data-slide="prev" draggable="true">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</a>
<a class="carousel-control-next" href="#newsCarousel" role="button" data-slide="next" draggable="true">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</a>
</div>
</div>
<div class="col-3 pt-2 pb-2 dropzone"
@drop.prevent="onDrop($event)"
@dragover.prevent
@dragenter.prevent="onDragenter($event)"
@dragleave="onDragleave($event)">
</div>
<div class="col-3 pt-2 pb-2 dropzone"
@drop.prevent="onDrop($event)"
@dragover.prevent
@dragenter.prevent="onDragenter($event)"
@dragleave="onDragleave($event)">
</div>
<div class="col-3 pt-2 pb-2 dropzone"
@drop.prevent="onDrop($event)"
@dragover.prevent
@dragenter.prevent="onDragenter($event)"
@dragleave="onDragleave($event)">
</div>
</div>
JS CODE
//drag n drop
startDrag(e) {
let ids = [];
e.dataTransfer.dropEffect = 'move';
e.dataTransfer.effectAllowed = 'move';
const items = document.getElementsByClassName('draggable-el');
items.forEach( (el) => {
el.classList.add('dragging');
ids.push(el.id);
});
e.dataTransfer.setData('text/plain', JSON.stringify(ids));
},
onDragenter(e) {
e.target.classList.add('drop');
},
onDragleave(e) {
e.target.classList.remove('drop');
},
onDrop(e) {
let ids = JSON.parse(e.dataTransfer.getData('text/plain'));
ids.forEach( (id) => {
const item = document.getElementById(id);
item.classList.remove('dragging');
e.target.classList.remove('drop');
e.target.appendChild(item);
});
// return false;
}
SCOPED CSS
.widget-area {
width: 100%;
height: 350px;
top: 8em;
z-index: 200;
.dropzone {
&.drop{
border: rgba(255,255,255,0.3) dotted 1px;
.draggable-el {
pointer-events: none;
}
}
}
#newsCarousel {
// width: 18.5rem;
// height: 330px;
.carousel-inner {
width: 18.5rem;
height: 330px;
z-index: 300;
.draggable-el {
height: 330px;
width: 18.5rem;
transition: all 0.3s cubic-bezier(0.4, 0.0, 0.2, 1);
&:active {
cursor: grabbing;
}
&.dragging {
opacity: .5;
transform: scale(.8);
}
}
}
.carousel-control-prev, .carousel-control-next {
z-index: 300;
top: -6em;
}
}
}