According to this answer, I should be able to get the element that an element "drop" occurred over. However, it's reporting really odd and random results which always seems to be parent elements instead of the actual child element the dragged element is dropped on.
Here's the FULL CODE EXAMPLE on CodeSandbox with the pertinent snippets shown below...
<div>
<div id="sidebar">
<drag :transfer-data="{ type: 'textbox', width: 330, height: 50 }" class="draggable-item"
>Textbox
<div slot="image" class="drag-image"><div class="field-container" style="width: 330px;height: 50px;">Texbox</div></div></drag
>
</div>
<div id="pages-container" @click.self="deselectAll();">
<b-alert show variant="info" class="text-center">Drag controls from the left sidebar to the pages below.</b-alert>
<drop
class="page-container"
v-for="(p, index) in pages"
@drop="onDrop"
@click.self="deselectAll();"
:data-page-number="p.pageNumber"
:key="p.pageNumber + '_page_' + index"
:style="{ width: p.width + 'px', height: p.height + 'px' }"
>
<img src="https://www.kirupa.com/flash/images/single_column_text.png" width="100%" height="100%" :data-page-number="p.pageNumber" @click.self="deselectAll();" />
<div style="position: absolute;top:0;bottom:0;left:0;right:0;background-color:white;opacity:0" :data-page-number="p.pageNumber" @click.self="deselectAll();"></div>
<vue-draggable-resizable
:id="f.id"
:style="{ 'z-index': '1044 !important' }"
:class="{ 'field-container grabbable': true, selected: f.isSelected }"
v-for="(f, f_index) in getPageFields(fields, p.pageNumber)"
:key="f.id"
:min-width="20"
:min-height="20"
:x="f.left"
:y="f.top"
:w="f.width"
:h="f.height"
:parent="false"
:z-index="f.isSelected ? '1045 !important' : '1044 !important'"
:prevent-deactivation="true"
:active.sync="f.isSelected"
@resizestop="onResizeStop"
@dragstop="onDragStop"
@activated="onActivated(f.id);"
@clicked="onActivated(f.id);"
>id: {{ f.id }} <br />
page: {{ p.pageNumber }} fieldIndex: {{ f_index }} selected: {{ f.isSelected }}</vue-draggable-resizable
>
</drop>
</div>
</div>
The pertinent JavaScript is shown here (the page number alert test is always undefined
)...
onDragStop(x, y) {
//...
const el = document.elementFromPoint(x, y);
alert("Dropped onto page number: " + el.dataset.pageNumber);
}
As @Joao pointed out,
document.elementFromPoint()
requires viewport coordinates, butVueDraggableResizable
provides offset coordinates (based on its configured lock aspect ratio and bounds) relative to the initial drop-element. You could still get the viewport coordinates by grabbing them from the draggable item itself.Steps:
Add a
ref
to<vue-draggable-resizable>
(which will create an array of references to the draggable), and update thedragstop
-handler to also take an index that we'll use with the applicableref
in the next step: