Saturday, April 7, 2012

Native GWT Drag and Drop

I just add some new examples, which I am going to describe in the next days, one of them is the native GWT drag and drop. Now this is the very basic one example which was introduced last year on the Google I/O conference. I will use this example to extend it later and show how to do drag and drop also on custom GWT widgets without to use third party libraries. You can find the source code as usual into my example project gwt2go here. The direct links are here and here.

Just short overview of the example. Basically you will have element which you want to be able to drag and drop onto another element which will be the target. To allow element to be dragged you have to use addDragStartHandler. To do so follow this code:

final Label label = new Label("Drag me");
label.getElement().setDraggable(Element.DRAGGABLE_TRUE);
 
label.addDragStartHandler(new DragStartHandler() {
 
    @Override
    public void onDragStart(DragStartEvent event) {
        // required
        event.setData("text", "Hello World");
 
        // optinal: show copy of the image
        event.getDataTransfer()
                .setDragImage(label.getElement(), 10, 10);
    }
});

Now as mention into the conference, some widgets do not implement this interfaces so you have to go for little bit different approach using addDomHandler like this:



label.addDomHandler(new DragStartHandler() {
    @Override
    public void onDragStart(DragStartEvent event) {
        // required
        event.setData("text", "Hello World again;)");
        
        // optional
        event.getDataTransfer().setDragImage(label.getElement(), 10, 10);
    }
}, DragStartEvent.getType());

Using setData, you use a key value function which allows you to put the data to be transferred to target elements. In my case the key is ‘text’ and the value ‘Hello World’. You can use the key ‘text’ from the target element to read the value into it.


Also using setDragImage allows you to put a image or element which will be shown when you drag your element.


Now for the target element you have to go for the following code:



final Label target = new Label("Drag onto me");
// required: you must add dragoverhandler to create a target
target.addDragOverHandler(new DragOverHandler() {
    @Override
    public void onDragOver(DragOverEvent event) {
        target.getElement().getStyle().setBackgroundColor("#ffa");
    }
});
 
// add drop hanlder
target.addDropHandler(new DropHandler() {
    @Override
    public void onDrop(DropEvent event) {
        // prevent the native text drop
        event.preventDefault();
 
        // get the data out of the event
        String data = event.getData("text");
        target.setText(data);
    }
});

Two important thinks to learn here, the onDragOver allows you to set up what should happen to the element when the dragged element is over the target. Drag over is really MUST. The implementation could be empty put you have to initiate the function, otherwise your target may not work into all browsers.


The second thing is to implement addDropHandler, where you can get the transported value and use it into the target widget.


Here the links again: the MVP View here and the Panel with the Dnd example here.


chears

3 comments:

  1. I don't want to pass Text in event.setData, I want to pass an object. Can this be done?

    ReplyDelete
  2. I assume this only works with GWT widgets right? What if I want to support native HTML5 desktop to browser DnD? How would that be done?

    ReplyDelete