Drag&Drop engine is the integral part of the FireWeb core. Each view element can be draggable by adding @OnDrag annotation listener on one it's public method. By default all elements are not draggable.
/** * Drag moving element between panels. * */ public class MovingElement extends Div { public MovingElement(ColorName color) { setStyleClass("move-element"); setStyle(new Background(color.color())); } @OnDrag @EventDragMove("function(o){var x=o.cloneNode(true);" + "x.style.color='Blue';x.style.fontSize='3em';" + "return x}") public void drag(Event event) { Main main = event.getApplication(); main.getMessage().setText(main.getResource("message.moving") + event.getElement().getText()); } @OnDragCancel public void cancel(Event event) { Main main = event.getApplication(); main.getMessage().setText(main.getResource("message.canceled") + event.getElement().getText()); } }
At this demo you can drag boxes with labels started with # over the left and right containers. Above them is message box with messages coming from engine events.
There are 3 events to listen:
@OnDrop @EventCallBeforeAfter(true) public void drop (Event event) { Main main = event.getApplication(); // Find moving element drop on container Div dropped = (Div) main.findElement(event.getValue().getString(0)); // Detect on which container dropped: left or right boolean isLeft = (event.getElement() == main.getLeft()); dropped .removeDropTarget(isLeft ? main.getLeft() : main.getRight()) .addDropTarget(isLeft ? main.getRight() : main.getLeft()) .setParent(isLeft ? main.getLeft(): main.getRight()); dropped.setStyle(new Background(isLeft ? ColorName.DarkSeaGreen.color() : ColorName.LightCoral.color())); main.getMessage().setText(main.getResource("message.dropped") + dropped.getText()); }
The events OnDrag and OnDragCancel are fired on draggable elements (movement element). The event OnDrop is fired on droppable element (target element).
To complete drag&drop setup you have to point out droppable elements. They can be 1 or more for each draggable element. You can do this by addDropTarget(element). To remove target use removeDropTarget(element) or to list them use getDropTargets().
dropped.removeDropTarget(isLeft ? left : right) .addDropTarget(isLeft ? right : left) .setParent(isLeft ? left : right);
By default dragged element is showing under mouse pointer while moving it. It is the copy of draggable element.
You can change this by adding @EventDragMove event property annotation on draggable element. As a parameter value pass inline JavaScrip code or JavScript function name which will replace the default behaviour. The JavaScript engine passes to the function draggable element as an argument.
@EventDragMove("function(o){var x=o.cloneNode(true);" + "x.style.color='Blue';x.style.fontSize='3em';" + "return x}")
Below drop container is box displaying message about server time pushed to browser by background server task.
The background push thread is simple TimerTask which is not serializable so we have to stop it when application is serialized and start it when application is deserialized. In addition we also do not want to push data do browser when application is not on view. For that we can use events: @OnViewOpen and @OnViewClose.
/** * Start timer and clock thread */ @OnViewOpen public void open() { timer = new Timer(); clock = new Clock(this); timer.schedule(clock, 100, 1000); } /** * Stop timer and clock thread */ @OnViewClose public void close() { timer.cancel(); timer = null; clock = null; }
Demo code you can get from here dragdrop.war