Question

I'm desperately trying to enable the multiple-property to users of my webside. User should be able to upload a bunch of PDF-files to my server without choosing each file separately. I'm using gwt-upload for my uploads. Sadly the

MultiUploader

does not actually lets the user select several files at once, but you have to click the "Browse"-Button for every file again and select in in the browser.

I researched and realised that I need to have something like this

<input name='uploads[]' type="file" multiple>

Setting the "multiple"-property at the input created from gwt-upload does the trick so far that the opening file-dialog lets me select several files, but then the upload does not start / work anymore.

I could not find any example using a multi-file-input with gwt. It would be perfect if there is a way to do this with gwt-upload because I do not really want to implement the whole upload logic by myself again!

Thanks a lot!

Was it helpful?

Solution

The solution is pretty simple. gwt-upload has a class Uploader which is able to do multiple uploads. The servlet code suggested in the wiki of gwt-upload is already capable of handling multiple uploads.

I had to change somethings in the Uploader class (source is fully available, so I just copied it and replaced the parts I needed). To access filenames and filesizes of the selected files I created a simple native method:

private static native String getFilesSelected() /*-{
    var count = $wnd.$('input:file')[0].files.length;

    var out = "";

    for (i = 0; i < count; i++) {
        var file = $wnd.$('input:file')[0].files[i];
        out += file.name + ';' + file.size + ";";
    }
    return out;
}-*/;

whichs return value I split by ; to get the needed results.

And you need to replace the uploaders FileInput (setFileInput()) with a custom one, which sets the multiple property to the input. I use a wrapper class like this:

public class MyFileInput implements IFileInput {

    private final FileUpload fu;

    public MyFileInput() {
        fu = new FileUpload();
        DOM.setElementProperty(fu.getElement(), "multiple", "multiple");    
    }
}

you obviously need to implement the other methods of IFileInput, I linked them all through to fu. Two had no equivalent method, but I dont use them, so no problem here ...

OTHER TIPS

Here's what I ended up with that I believe works on all browsers:

form = new FormPanel();
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
form.add(new HTML("<input type='file' id='fileselect' name='fileselect[]' multiple />"));

then on the server side I'm just using "org.apache.commons.fileupload" stuff.

Yeah some people may not like the HTML element in the form, but here is how you CAN get the input element from it if you want:

protected Element getFileSelectElement() {
    HashMap<String, Element> idMap = Maps.newHashMap();
    GuiUtil.parseIdsToMap(inputField.getElement(), idMap);
    Element input = idMap.get("fileselect");
    return input;
}

public static void parseIdsToMap(Element element, HashMap<String, Element> idMap) {
    int nodeCount = element.getChildCount();
    for (int i = 0; i < nodeCount; i++) {
        Element e = (Element) element.getChild(i);
        if (e.getId() != null) {
            idMap.put(e.getId(), e);
        }
    }
}

and finally... if you want to get access to the list of files the user selected, on the browser side, here's what I have:

public static native String getFileNames(Element input) /*-{

    var ret = "";

    //microsoft support
    if (typeof (input.files) == 'undefined'
            || typeof (input.files.length) == 'undefined') {
        return input.value;
    }

    for ( var i = 0; i < input.files.length; i++) {
        if (i > 0) {
            ret += ",";
        }
        ret += input.files[i].name;
    }
    return ret;
}-*/;

I use a more simple solution.

defaultUploader = new MultiUploader();
IFileInput ctrl = defaultUploader.getFileInput();
DOM.setElementProperty((ctrl).getElement(), "multiple", "multiple");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top