Ember Drag and Drop demo

Customization of original fiddle, reworking drag image to be same element that user clicked, but positioned at proper click location. Fork of: http://jsfiddle.net/ud3323/5uX9H/ Answer to: http://stackoverflow.com/questions/10762484/ember-js-html5-drag-and-drop-shopping-cart-demo

by Jon Beebe

HTML

<script src="http://cloud.github.com/downloads/emberjs/ember.js/ember-0.9.8.js"></script>
<script type="text/x-handlebars" >  
    <b>Available Products</b>
    <br /><br />
    {{#each App.productsController}}
      {{#view App.ProductView contentBinding="this"}}
        {{content.name}}
      {{/view}}<br />
    {{/each}}
    <hr />
    
    {{#view App.ProductDropTarget 
            dragContextBinding="App.productsController.currentDragItem"}}
    Shopping Cart
    <div style="height: 20px">{{helpText}}</div>
    {{/view}}
    <br />
    {{#each App.cartController}}
      {{#view App.ProductView contentBinding="this"}}
        {{content.name}}
      {{/view}}<br />
    {{/each}}    
</script>

CSS

.dropTarget {
    width: 200px;
    padding: 20px;
    background-color: #2355A1;
    color: white;
}

.product {
    position: relative;
    margin-left: 20px;
    padding-left: 15px;
}

.cart-add {
    background-color: #55A122;
}

.cart-remove {
    background-color: #A12255;
}

JavaScript

App = Ember.Application.create({});

DragNDrop = Ember.Namespace.create();

DragNDrop.cancel = function(event) {
    event.preventDefault();
    return false;
};

DragNDrop.Draggable = Ember.Mixin.create({
    attributeBindings: 'draggable',
    draggable: 'true',
    dragStart: function(event) {
        var dataTransfer = event.originalEvent.dataTransfer;
        dataTransfer.setData('Text', this.get('elementId'));
    }
});

DragNDrop.Droppable = Ember.Mixin.create({
    dragEnter: DragNDrop.cancel,
    dragOver: DragNDrop.cancel,
    drop: function(event) {
        event.preventDefault();
        return false;
    }
});

App.Product = Ember.Object.extend({
    name: null,
    isAdded: null
});

App.ProductView = Ember.View.extend(DragNDrop.Draggable, {
    classNames: ['product'],
    tagName: 'span',
    
    // .setDragImage (in #dragStart) requires an HTML element as the first argument
    // so you must tell Ember to create the view and it's element and then get the 
    // HTML representation of that element.
    dragIconElement: Ember.View.create({
        attributeBindings: ['src'],
        tagName: 'img',
        src: 'http://twitter.com/api/users/profile_image/twitter'
    }).createElement().get('element'),
    
    dragStart: function(event) {
        this._super(event);
        // Let the controller know this view is dragging
        this.setPath('content.isDragging', true);
        
        // Set the drag image and location relative to the mouse/touch event
        var dataTransfer = event.originalEvent.dataTransfer;
        //dataTransfer.setDragImage(this.get('dragIconElement'), 24, 24);
        
        var offset = this.$().offset();
        
        var position = {
            x: event.originalEvent.x - offset.left,
            y: event.originalEvent.y - offset.top
        };
        
        dataTransfer.setDragImage(this.$()[0], position.x, position.y);
    },
    
    dragEnd: function(event) {
        // Let the controller know this view...