Search code examples
htmlgwtdrag-and-dropsmartgwt

Catching HTML5 drag&drop events inside smartgwt modal Window


I'm trying to make modal window with form to upload new files in smartgwt, currently i'm using FileItem and dropping file on its browse button works in some browsers. Problem is that i can't style FileItem and i would like it to look like a bigger "drop zone". As far as i understand styling of FileItem is limited due security concerns so i tried to use another element (label) to catch drag&drop events and then set value of dropped file to FileItem.

The problem is that smartgwt has listeners implemented on Widgets level and doesn't catch browser events on DOM elements (or at least it looks like that). I also tried using Event and DOM classes to catch events but im getting Umbrella Exceptions.

Current code for modal window:

public class ImportDocumentWindow extends Window{

private GroupFiles groupFiles;

public ImportDocumentWindow(GroupFiles groupFiless) {
    this.groupFiles = groupFiless;

    //window properties
    setShowTitle(false);
    setShowHeader(false);
    setShowStatusBar(false);
    setCanDragReposition(false);
    setHeight(300);
    setWidth(325);
    setIsModal(true);
    setShowModalMask(true);
    setModalMaskOpacity(50);
    centerInPage();
    setShowMinimizeButton(false);
    setShowCloseButton(false);
    setStyleName("modalWindow");
    setBodyStyle("modalWindowBody");

    //main layout
    VLayout vlayout = new VLayout();
    vlayout.setHeight100();
    vlayout.setWidth100();

    //header layout
    HLayout headLayout = new HLayout();
    headLayout.setWidth100();
    headLayout.setHeight(30);
    headLayout.setStyleName("modalWindowHeader");

    Label lblWindowTitle = new Label("Upload files");
    lblWindowTitle.setWidth(300);
    lblWindowTitle.setHeight(20);
    lblWindowTitle.setValign(VerticalAlignment.CENTER);
    lblWindowTitle.setStyleName("modalWindowTitle");

    IButton close = new IButton("");
    close.setShowTitle(false);
    close.setIcon("x icon.png");
    close.setWidth(24);
    close.setHeight(24);
    close.setValign(VerticalAlignment.CENTER);
    close.setAlign(Alignment.RIGHT);
    close.setBaseStyle("closeButtonStyle");
    close.addClickHandler(new ClickHandler() {

        @Override
        public void onClick(ClickEvent event) {
            destroy();
        }
    });

    headLayout.addMembers(lblWindowTitle,close);
    vlayout.addMember(headLayout);

    DynamicForm form = new DynamicForm();
    form.setWidth100();
    form.setHeight("*");
    form.setTitleOrientation(TitleOrientation.TOP);
    form.setNumCols(1);
    form.setStyleName("modalWinodowForm");

    final FileItem file = new FileItem();
    file.setShowTitle(true);
    file.setTitle("Drop or browse file");
    file.setTitleStyle("topInputLabel");
    file.setControlStyle("uploadBox");
    file.setWidth(260);
    form.setFields(file);
    vlayout.addMember(form);

    /*
     * Insert drop zone here?
     * 
     */
     Label dropZone = new Label();
     dropZone.setTitle("Drop files here");
     dropZone.setWidth(200);
     dropZone.setHeight(200);
     dropZone.addDropOverHandler(new DropOverHandler() {

        @Override
        public void onDropOver(DropOverEvent event) {
            // Expects another canvas / widget to be dropped??

        }
    });


    vlayout.addMember(dropZone);
    addItem(vlayout);   
}
}

So, anyone has idea how to catch event when file is dropped from desktop to application?

GWT version is 2.6.0


Solution

  • I ended up using external library called "DHTMLX Vault". Implementation is quite simple.

    1. Import library somewhere into your war folder
    2. Link JS and CSS files inside main HTML file
    3. Create custom servlets to handle upload (include them inside main XML file)
    4. Use oficial implementation guides for styling and modifiing inside your Java class.

    Short example:

    Canvas canvas = new Canvas();
        canvas.setContents("<div id='vaultObj' style='width:524px; height:300px; margin:15px auto;'></div>");
        vlayout.addMember(canvas);
    
    ...
    
    public native void initVault(String url) /*-{
    
        var myVault = new $wnd.dhtmlXVaultObject({
            container:  "vaultObj",
            uploadUrl:  url,
            swfPath:    "dhxvault.swf",
            slXap:      "dhxvault.xap",
            autoStart:  true,
            autoRemove: false,
            buttonClear:false,
        });
    
    
    }-*/;
    

    Notice i created div with class "vaultObj" inside canvas and that class is later used to mark vault container selector. In my case i had to call initVault method inside onDraw method to apply library styles and JS correctly.