Drag and drop is a part of the HTML5 standard. It allows the user to grab objects in the DOM and drop them at different locations. Any element can be draggable if the browser supports it. Most modern browsers do.
In this recipe, we'll see an example of dragging an IMG file to a drop zone on the screen.
$ ember g component drag-drop-zone $ ember g component drag-drop
The drag-drop-zone
component will represent the area where each item will be dropped. The drag-drop
component will be the item to be dropped.
drag-drop-zone.js
file:// app/components/drag-drop-zone.js import Ember from 'ember'; export default Ember.Component.extend({ classNames: ['draggable-dropzone'], classNameBindings: ['dragClass'], dragClass: 'deactivated', dragLeave(event) { event.preventDefault(); return this.set('dragClass', 'deactivated'); }, dragOver(event) { event.preventDefault(); return this.set('dragClass', 'activated'); }, drop(event) { var data; this.set('dragClass', 'deactivated'); data = event.dataTransfer.getData('text/data'); event.target.appendChild(document.getElementById(data)); } });
This component has a few special events attached to it. Ember has built-in events for dragLeave
, dragOver
, and drop
. These will fire whenever items are dragged on top of the component. Remember that all components render as div
tags. We can use the classNames
property to add more classes.
The classNameBindings
property allows classes to be added to the component as if they were properties. In other words, dragClass
can be set dynamically in the component. We'll use this to change the color of the drop
zone when items are dragged over it. When items are dropped, the drop
event is triggered.
// app/components/drag-drop.js import Ember from 'ember'; export default Ember.Component.extend({ tagName: 'img', classNames: ['draggable-item'], attributeBindings: ['draggable','src'], draggable: 'true', src: 'http://www.programwitherik.com/content/images/2015/02/eriksmall3-1.png ', dragStart(event){ event.dataTransfer.setData('text/data', event.target.id); } });
As mentioned earlier, normally, components render as a div
tag. However, we can change this using the tagName
property. In the drag-drop
component, we are creating an image
tag. The dragStart
event available in Ember. In this example, we are setting the data to the target ID.
To drag items in HTML5, you must have a draggable
attribute on the tag. It also must be set to true
. We'll use attributeBindings
to make this possible.
app.css
file:// app/styles/app.css .draggable-dropzone { border: 1px solid black; width: 200px; height:200px; } .activated { border: 4px solid red; }
This is some basic css
that creates a border around the drop
zone and changes the color to red
when an item is about to be dropped.
// app/templates/application.hbs <h2 id="title">Welcome to Ember</h2> <br> {{drag-drop-zone}} <br> <br> <br> {{drag-drop}} {{outlet}}
This will render the two components to the application template.
You can drag the picture into the box:
The box will turn red before the item is dropped and back to black after it's dropped.