5
votes

I'm trying to drag Ember objects from one list to another. If I drag an item to a new list, the item should be removed from its current list and moved to the new one.

Thanks to Drag&Drop with Ember.js and Ember.js - drag and drop list, I figured out how to copy an item to a different list. However, I am unable to determine from which list a dragged object originated. I have dozens of lists on the page, so I'd rather not do a O(n*k) search for the original object.

Currently, I'm using Ember views and the HTML 5 API. It seems like the Handelbars action helper should achieve my goal more easily. Ember's action supports the drop event, but I can't get it to fire: {{ action foo on="drop" }}. It probably has something to do with the nuanced event propagation defaults of the HTML 5 drag-and-drop implementation.

If you know how to solve this problem using actions instead of views, I'd much prefer that solution.

Here's how I'm currently transferring objects:

// this is heavily inspired by http://jsfiddle.net/ud3323/5uX9H/
// Draggable items
App.ItemView = Ember.View.extend({
    templateName: 'item',
    attributeBindings: 'draggable',
    draggable: 'true',
    dragStart: function(event) {
        var dataTransfer = event.originalEvent.dataTransfer;
        // The view's context is the item to transfer
        var item = this.get('context');
        // Use HTML 5 API to transfer object as JSON.
        // There must be a more elegant way to do this.
        dataTransfer.setData('application/json', JSON.stringify(item));
    }
});

// Item list drop zone
App.ItemListView = Ember.View.extend({
    templateName: 'itemList',
    dragEnter: function(event) {
        event.preventDefault();
        return false;
    },
    dragOver: function(event) {
        event.preventDefault();
        return false;
    },
    drop: function(event) {
        event.preventDefault();

        // Extract the transferred data
        var rawData = event.dataTransfer.getData('application/json');

        // Create a new Ember object from the data
        var item = App.Todo.create(JSON.parse(rawData));
        this.get('controller').send('add', item);
        return false;
    }
});

Check out JS Bin for the complete code.

Thanks in advance for your help. Very much appreciated.

1

1 Answers

0
votes

This is maybe not the full solution to your problem, but it satisfies the need to use the action helper instead of the itemView. Here is your modified jsbin http://jsbin.com/ibufeh/15/edit?html,javascript,live, the drop event fires and is catched at the ApplicationRoute level, from where you can then redirect your function call to the appropriate controller, have a look! it's not working correctly but it solves part of your problem - using an action helper. You need still to figure out from which list the item originated, but this will be easy I guess.

hope it helps