Friday, June 7, 2013

GWT & HTML5 DnD

I figured out a way for users to DnD into GWT's RichTextArea from either inside the GWT application and for us even more importantly from another website/page.  We had to use JSNI as the standard GWT drop listeners are never fired, I assume it's because it uses an iFrame.  I thought I'd post it here as perhaps others will find it useful.  Also if you see some potential problems let me know as I'd like to improve it. 

One question I have is should I be adding the listener to the iframe too or just to iframe.contentWindow?

Also things works really well with Firefox I need to determine if any changes are needed for IE8/9/10 and Chrome.

public class GwtRichTextArea extends RichTextArea {

    private Object dragenterFunction = null;
    private Object dragoverFunction = null;
    private Object dropFunction = null;

    public GwtRichTextArea () {
    }

    @Override
    protected void onAttach() {
        super.onAttach();

        IFrameElement iFrame = IFrameElement.as(getElement());
        iFrame.setName(UUID.uuid());
        addDragOverHandler(iFrame);
        addDropHandler(iFrame);
    }

    @Override
    protected void onDetach() {
        IFrameElement iFrame = IFrameElement.as(getElement());
        removeDragOverHandler(iFrame);
        removeDropHandler(iFrame);

        super.onDetach();
    }

    private native void addDragEnterHandler(IFrameElement iframe)
/*-{
    if (iframe == null)
        return;

    var _this = this;

    var dragenterFunction = function (e) {

        // todo: add some css style here
    }

    _this.@com.gwtcommon.gwt.user.client.ui.GwtRichTextArea::dragenterFunction = dragenterFunction;

    iframe.addEventListener('dragenter', dragenterFunction, true);
    iframe.contentWindow.addEventListener('dragenter', dragenterFunction, true);

}-*/;

    private native void addDragOverHandler(IFrameElement iframe)
/*-{
    if (iframe != null) {
        var _this = this;

        var dragoverFunction = function (e) {

            if (e.preventDefault) {
                e.preventDefault(); 
            }

            e.dataTransfer.dropEffect = 'copy'; 

            return false;
        }

        _this.@com.gwtcommon.gwt.user.client.ui.GwtRichTextArea::dragoverFunction = dragoverFunction;

        iframe.addEventListener('dragover', dragoverFunction, true);
        iframe.contentWindow.addEventListener('dragover', dragoverFunction, true);
    }
}-*/;

    private native void addDropHandler(IFrameElement iframe)
/*-{
    if (iframe == null) {
        return;
    }

    var _this = this;

    var dropFunction = function (event) {

       // Handle the drop.  We attach to the body element...
       iframe.contentWindow.document.body.appendChild(newElement);
        

        return false;
    }

    _this.@com.gwtcommon.gwt.user.client.ui.GWTRichTextArea::dropFunction = dropFunction;

    iframe.addEventListener('drop', dropFunction, true);
    iframe.contentWindow.addEventListener('drop', dropFunction, true);

}-*/;

    private native void removeDragOverHandler(IFrameElement iframe)
/*-{
    if (iframe != null) {
        var _this = this;

        var dragoverFunction = _this.@com.gwtcommon.gwt.user.client.ui.GWTRichTextArea::dragoverFunction;

        iframe.removeEventListener('dragover', dragoverFunction, true);
        iframe.contentWindow.removeEventListener('dragover', dragoverFunction, true);
    }
}-*/;

    private native void removeDropHandler(IFrameElement iframe)
/*-{
    if (iframe != null) {
        var _this = this;

        var dropFunction = _this.@com.gwtcommon.gwt.user.client.ui.GWTRichTextArea::dropFunction;

        iframe.removeEventListener('drop', dropFunction, true);
        iframe.contentWindow.removeEventListener('drop', dropFunction, true);
    }
}-*/;

    private native void removeTextPasteHandler(IFrameElement iframe)
/*-{
    if (iframe != null) {
        var _this = this;

        var pasteFunction = _this.@com.gwtcommon.gwt.user.client.ui.WebTASRichTextArea::pasteFunction;

        iframe.removeEventListener('paste', pasteFunction, true);
        iframe.contentWindow.removeEventListener('paste', pasteFunction, true);
    }
}-*/;

}


--
You received this message because you are subscribed to the Google Groups "Google Web Toolkit" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-web-toolkit+unsubscribe@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at http://groups.google.com/group/google-web-toolkit?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

No comments:

Post a Comment