1

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

2 Answers 2

1

You can use the open source javascript library dropzone.js designed by Matias Meno and wildly available and open source; download and place it directly in your war folder. Create dropzone.html in the war and place this content there

<!doctype html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="dropzone.js"></script>
<title>Web Uploader Project</title>
</head>
<body>
	<form action="/file-upload" class="dropzone" id="my-awesome-dropzone"></form>
		<script>
		window.Dropzone.options.myAwesomeDropzone = {
			
			init : function() {
				this.on("addedfile", function(file) {
					window.parent.notifier();
				});

			}
		};
	</script>
</body>
</html>
Set action to your servlet which will process the upload event on the server side. Setting class to dropzone tells the library where you want to place your dropzone. By the way http://www.dropzonejs.com has alot of detail you may want to check out to appreciate its power. window.parent.notifier is a Dom method you will export from your SmartGWT code using JSNI.

In your above class add this code:

		final Window win = new Window();
/*
*your other cod
*/
   

		VLayout dropguy = new VLayout();
		dropguy.setWidth100();
		dropguy.setWidth100();
		dropguy.setShowEdges(true);

		Frame frame = new Frame();
		frame.setSize("100%", "100%");
		frame.setUrl("dropzone.html");
		dropguy.addMember(frame);
		win.addItem(dropguy);
		
        EntryP.fileAdded(this);
		win.draw();
	}

	public static void notifier() {
		SC.say("NOFITIER SAYS: file added");
	}

	public static native void fileAdded(EntryP examp) /*-{
		$wnd.notifier=$entry(@com.example.client.EntryP::notifier());
		
	}-*/;
Notice how i have reference dropzone.html and exported the static notifier method by a call to EntryP.fileAdded(this); to make it available in the DOM. You can set the dimensions of the Frame to whatever you want and place it inside a layout of your choice.

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you. This also seems like a good answer but unfortunatelly before i had chance to try and implement it i had to move to another library so Dropzone will have to wait for another time.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.