Edit: Alternative solution
I just thought that, instead of looking for a pos_id
data attribute when traversing the path array, I can look for 'TD' elements (using the tagName
property). Similarly, I can get the parent 'TR'. The cells have a cellIndex
property, and the rows have a rowIndex
, so I can use these values to look for the cell data in the source object from which the table is built.
Original solution
I don't know if this is the best solution, but it worked for me:
First, in the HTML template, I've added to the droppable cells a pos_id
data attribute with the ID of that cell. So they look like:
<tr>
<td data-pos_id="101"> ... </td>
<td data-pos_id="102"> ... </td>
...
<tr>
<tr>
<td data-pos_id="201"> ... </td>
<td data-pos_id="202"> ... </td>
...
<tr>
Second, in the makeDroppable
directive, inside the drop event listener, I use the path
/composedPath
property/method to get an array of the DOM elements over which the cursor is. Then, I traverse this array looking for an element that has a pos_id
dataset attribute, which will be the element that I'm looking for:
el.addEventListener('drop', (e) => {
...
// Event DOM path
var path = e.path || (e.composedPath && e.composedPath());
for(let elem of path) {
// If the element has a data attribute called 'pos_id', it's a droppable <TD>
if (elem.dataset && elem.dataset.pos_id) {
elem.classList.add('over');
console.log('Dropped object on position '+elem.dataset.pos_id);
break;
}
}
...
}
However, this method has a BIG problem: it relies on a dataset attribute to identify uniquely the position where the user dropped the object, so if the user changes this attribute using the developer console or any other method, the application won't work as expected. I'll post a new question about this subject and I'll keep on doing tests to try to solve this issue.