I have been working on a https://github.com/wekan/ fork where I try to implement additional drag and drop functionality. Out of the box wekan already came with labels/member drag and drop where the hover overlay is done via droppable hoverClass:
const selector = $cards.find(itemsSelector);
selector.droppable({
hoverClass: 'draggable-hover-card',
accept: '.js-member,.js-label',
'drop'(evt, ui) {
evt.preventDefault();
evt.stopPropagation();
const cardId = Blaze.getData(this)._id;
const card = Cards.findOne(cardId); //get current card I am hovering
//stuff
},
});
I added attachment drag and drop functionality, which won't work exactly like above code and produces the problem that I cannot add the hoverClass cleanly. When I implement it as shown below the logic of doing addClass is sound but I get an error:
Exception from Tracker afterFlush function:
debug.js:41 Error: Expected DOM element or View
at Object.Blaze.getData (view.js:757)
at list.js:116
at Object.Tracker._runFlush (tracker.js:511)
at onGlobalMessage (setimmediate.js:102)
My code where I want to get an overlay/hover functionality for a single card that I hover over with a file:
const cardId = Blaze.getData(this)._id;
const card = Cards.findOne(cardId); //get current card I am hovering
selector.on({'': (evt) => { //.droppable as above does not work
evt.preventDefault(); //prevent default browser behavior
evt.stopPropagation();
},
dragover(e) { // pulled out of selector.on() to add/removeClass
e.preventDefault();
e.stopPropagation();
card.addClass('is-selected'); //add overlay on hover
},
dragenter(e) {
e.preventDefault();
e.stopPropagation();
},
dragleave(e) {
e.preventDefault();
e.stopPropagation();
card.removeClass('is-selected');
},
drop(evt, ui) {
card.removeClass('is-selected');
if(!ui){ // prevent complications with other drop events
evt.preventDefault();
evt.stopImmediatePropagation(); // prevent x -times actions
evt.target.files = evt.dataTransfer.files; // working file upload
_.each(evt.dataTransfer.files, (f) => {
const file = new FS.File(f);
file.boardId = card.boardId;
file.cardId = card._id;
Attachments.insert(file);
});}
},
});
When I move
const cardId = Blaze.getData(this)._id;
const card = Cards.findOne(cardId);
back into the drop event like in the first code block and try/test e.g. selector.addClass('') instead, the overlay works, but not correctly(selector basically returns the whole card list instead of a single card). I am a novice currently in training and I just can't understand what error I am making.
Template.currentData() instead of Blaze.getData() does not work. When I try selector.droppable() my dropped file isn't accepted and all the other events won't fire either. After trying different varieties I am pretty sure that Blaze.getData() is the problem here. I don't know how to replace its function though.
The problem was a syntax and logic error on my side. While I knew that this
in Blaze.getData()
would point to the div I wanted, this.addClass()
would throw an error. So I thought I'd need the whole Blaze-Block which then lead to the problem above.
Right Syntax:
$(this).addClass('');