0

I am using the wonderful GWTQuery library to add drag drop support to my GWT cell widgets.

I have a CellTable, and a CellTree both in different modules of my application (I am using GWTP, so everything is decoupled). Neither of these widgets are allowed to know about each other, they simply accept draggables/droppables, check the underlying datatype and then handle them appropriately.

The problem I am having is that I need to support dragging "in between" my cell tree nodes. IE: The typical functionality where if you drag directly over an element in the tree, it drops into that element, BUT if you drag just slightly below or above, you are given a visual indicator (usually a horizontal line) that indicates to the user they can drag the current item in between nodes as well.

And here-in lies the problem, thus far I have no found a way to provide this functionality becuase the setOnDrag() method does not tell me anything about detected droppables, and setOnOver only fires once when it first encounters a droppable.

So far as I can tell this leaves me with only two options:

1.) Add extra "invisible" nodes into my CellTree which are also droppable and sit in between my other nodes. 2.) Implement some custom event handler which I attach to the helper draggable before drag start and use to compare positions of the helper and the droppable once the draggable is actually over the droppable.

Option 1 is really unsavory because it seriously mucks up my CellTree design, and potentially impacts efficiency pretty badly.

Option 2 is really unsavory because it requires a lot of extra code and hacks to get it to work just right.

So I am hoping there is an Option 3 which I might not have though of, any help would be much appreciated.

Cheers,

Casey

Casey Jordan
  • 1,204
  • 1
  • 20
  • 39

1 Answers1

0

I think I have found a solution although it may not be the best, but it is working for me at the moment. In the setOnDrag method, I determine where the item is being dragged at which point I can either add a line before or after the element, or put some css on the element to denote that I am dropping the dragged item on top. I create a GQuery place holder to show the before/after line, and putting a border around element with css for dropping on top.

To know which element I am dropping on top of, I set a global variable in the setOnOver method. Here is a simple mock up:

private GQuery placeHolder = $("<div id='cellPlaceHolder' style=' outline: thin dashed #B5D5FF; height: 2px; background:#B5D5FF;'></div> ");
private Element oldEl = null;

options.setOnOver(new DroppableFunction() {
    @Override
    public void f(DragAndDropContext context) {
       oldEl = context.getDroppable();
    }
});

options.setOnDrag(new DragFunction() {

        @Override
        public void f(DragContext context) {
            if (oldEl != null) {
                int difference = Math.abs(oldEl.getAbsoluteTop() - context.getHelperPosition().top);

                if (difference > 0 && difference < 16) {
                    /* dragging on top edge, so insert place holder */
                    oldEl.getFirstChildElement().getStyle().clearProperty("border");
                    placeHolder.insertBefore(oldEl.getFirstChildElement());
                } else if (difference > 26 && difference < 53) {
                    /* dragging on bottom edge, so insert place holder */
                    oldEl.getFirstChildElement().getStyle().clearProperty("border");
                    placeHolder.insertAfter(oldEl.getFirstChildElement());
                }else if (difference > 15 && difference < 27) {
                    /* dragging in middle so add border */
                    placeHolder.remove();
                    oldEl.getFirstChildElement().getStyle().setProperty("border", "2px solid red");
                }
            }
        }
    });

This way uses several global variables, but it seems to be the best method I have found since the drag options do not include info about the droppable element. And you will have to add the logic to know if it is being dropped before/after/or on and do what you want with it at that point.

Will
  • 292
  • 4
  • 16