Nepal on Rails

millisami's rants!

Drag and Drop With Emberjs

There were good old days on how to implement drag-n-drop UI. But now we’re at better stage. Its a piece of cake to impelement it using Emberjs. So lets build it with the rapid emberjs development workflow.

Lets start.

brunch new gh:mutewinter/tapas-with-ember drag-n-drop
cd drag-n-drop
git init
git add .
git commit -m 'Initial commit'

Start the server with cake server and visit http://localhost:3333

Objective

  1. List of Products
  2. Make it draggable
  3. Cart where user can drop the product into
  4. Update the cart’s total price when dropped into the cart

First, lets add and list the products in the model.

app/routes/index.coffee
1
2
3
4
5
6
7
module.exports = App.IndexRoute = Ember.Route.extend
  model: ->
    [
      {id: 1, title: 'Mac Book', price: 2000},
      {id: 2, title: 'Dell Inspiron', price: 2120},
      {id: 3, title: 'Lenovo', price: 1200}
    ]

To list the products, add the following content.

app/templates/index.hbs
1
2
3
4
5
6
7
<h2>Welcome to Store</h2>

<div class="products">
{{#each product in controller}}
  {{view App.ProductItemView contentBinding="product"}}
{{/each}}
</div>

Now we need the ProductItemView.

app/views/product_item.coffee
1
2
3
4
5
6
7
module.exports = App.ProductItemView = Ember.View.extend
  templateName: 'product_item'
  attributeBindings: ['draggable']
  draggable: "true"

  dragStart: (ev) ->
    ev.dataTransfer.setData('text/data', @get('content.id'))

And this is the template.

app/templates/product_item.hbs
1
2
3
4
<div class="product">
  <span class="title">{{product.title}}</span>
  <span class="price">$ {{product.price}}</span>
</div>

If you see the browser, now you can drag the individual product. This is all possible due to the attributeBindings: ['draggable'] property at app/views/product_item.coffee.

If you inspect one of the product, you can see it like <div id="ember261" class="ember-view" draggable="true">....</div>. Out of several Events, HTML5 drag and drop events are:

  • dragStart
  • drag
  • dragEnter
  • dragLeave
  • drop
  • dragEnd

We can trasfer and receive the data using the setData and getData method of HTML5 Drag and Drop API.

Now, lets introduce the Cart view where the user can drop the products.

app/views/cart.coffee
1
2
3
4
5
6
7
8
9
module.exports = App.CartView = Ember.View.extend
  templateName: 'cart'
  classNames: ['basket']
  dragOver: (ev) ->
    ev.preventDefault()
  drop: (ev) ->
    id = ev.dataTransfer.getData('text/data')
    record = @get('controller').findProperty('id', Number(id))
    console.log record

And this is the template.

app/templates/cart.hbs
1
2
3
<div class="shop_cart">
  <span>Drop the product here</span>
</div>

Now, if the product is dragged and dropped on the basket, the dragged product should be logged into the console. The method getData on ev.dataTransfer object can retrieve the data. In this case, we get the product id of the product. Since we get the id of the product, we can get the product using the findProperty method.

In the next part, we’ll add more functionality to this app such as:

  • Update the Total cart price
  • List the products added in the cart

The code is pushed at https://github.com/millisami/drag-n-drop-emberjs

Update: Feb 22, 2014 Part 2 is released at Drag N Drop With Emberjs, Part 2

To stay updated, just follow @nepalonrails

Comments