Merging Rails and Ember-CLI - Part II

Why?

In part 1 of Merging Rails with ember-cli, I talked about techniques that I use to achieve a smooth development experience when combining a Rails API with an Ember CLI-powered front end. I wanted to build a simple app where people could vote for beer by ranking their favorites on a weighted 1 to N scale. However, I was unsure how Ember would handle a major component of the app: drag-n-drop.In this post, I will go into more detail about how I implemented HTML5 drag-n-drop functionality for updating beer rankings. I will demonstrate how simple it was to build this functionality into my existing, non-dynamic list of beers.

##VS

##BootstrappingI love to use twitter bootstrap when I am prototyping a new idea. Just run...$ bower install --save-dev ember-cli-bootstrap-sass
...then add the following to the top of your root scss stylesheet:EmberApp/app/styles/app.scss@import "bootstrap";
@import "bootstrap/theme";
##Drag-N-DropWe've all heard this request before: "I just want to be able to drag this item here and this item there and POOF, the change is made!" Clients LOVE drag-n-drop. It is a feature I have implemented a million times before, but I almost always use some JQuery library that interfaces with a custom-built API for the sole purpose of building that ONE drag-n-drop component. I was seriously scared that drag-n-drop would be really hard to build in pure Ember, but I am pleased to say that I had it up and running in no time!The first thing I did was hit the docs. I was pleased to see that EmberView supports drag and drop out of the box. This worked out perfectly, since I knew I would need two views in this component: a line item and a slot to drop each line item into. So, I created myself a line-item and an item-slot view with the necessary event dataTransfer data.I had to comb through the w3c spec a bit, but I was able to come up with some solid documentation on HTML5 drag-n-drop and the data transfer interface.EmberApp/app/views/line-item.jsimport Ember from 'ember';

export default Ember.View.extend({
attributeBindings: ['draggable'],
draggable: 'true',
templateName: 'line-item',
classNames: 'line_item',

dragStart: function(ev){
var dragData = { id: this.content.get('id') };
ev.dataTransfer.setData('application/json', JSON.stringify(dragData));
}
});

EmberApp/app/templates/line-item.hbs<span class="weight">{{weight}}</span>
<span class="name">{{beer_name}}</span>
EmberApp/app/views/item-slot.jsimport Ember from 'ember';

export default Ember.View.extend({
templateName: 'item-slot',

dragOver: function(ev){
ev.preventDefault();
},

drop: function(ev){
var data = JSON.parse(ev.dataTransfer.getData('application/json'));
this.get('controller').send('swap', data.id, this.content.get('id'));
}
});
EmberApp/app/templates/item-slot.hbs{{view 'line-item' contentBinding='this'}}
Lastly, I updated my ballot template to use these new views.EmberApp/app/templates/ballot.hbs{{#each this.model.sorted_line_items}}
<div class="row"></div>
<div class="col-xs-12">{{view 'item-slot' contentBinding='this'}}</div>

{{/each}}
<div class="row"></div>
<div class="col-xs-12 new_beer">{{#view 'new-beer' contentBinding='this'}}</div>
<input type="text" placeholder="+ ADD BEER">
{{/view}}

Then I update my controller to handle swapping of weights between two line items. It's a little dirty, but it gets the job done:EmberApp/app/controller/ballot.jsimport Ember from 'ember';

export default Ember.Controller.extend({
sortProperties: ['weight'],

actions: {
swap: function(line_item_id_1, line_item_id_2) {
var li1, li1_weight, li2, li2_weight;
li1 = this.model.get('line_items').findBy('id', line_item_id_1);
li2 = this.model.get('line_items').findBy('id', line_item_id_2);
li1_weight = li1.get('weight');
li2_weight = li2.get('weight');
li1.set('weight', li2_weight);
li2.set('weight', li1_weight);
}
}
});
That’s it, drag-n-drop now works! Yet again Ember proves itself to be an amazing framework for building incredibly dynamic single-page apps with great speed.In Part 3, I will show you how to persist these changes that you make to your backend Rails application!##Resources* Ember-CLI Rails Github Repo* HTML5 Drag and Drop* Part 1* Part 3Cover photo by OUCHcharley

Subscribe to the Smashing Boxes Blog today!

Smashing Boxes is a creative technology lab that partners with clients, taking an integrated approach to solving complex business problems. We fuse strategy, design, and engineering with a steady dose of entrepreneurial acumen and just the right amount of disruptive zeal. Simply put, no matter what we do, we strive to do it boldly. Let's talk today!

Related Posts

WebSockets in Rails 5

Rails 5 is on the horizon. There are many great new features in this new version, but the one I'm most excited about is built-in WebSockets support.

view post

Merging Rails and Ember-CLI - Part I

To say that Ember has grown over the past year would be an understatement.

view post