File Upload With A Progress Bar, Or Accessing The Html 5 File Api From Google Web Toolkit?
Solution 1:
There are many issues in GWT which makes difficult deal with this:
- There is no
FormData
object in GWT, so you have to use JSNI to get one. RequestBuilder
does not support sendingFormaData
but only strings.RequestBuilder
does not support upload or download progress notifications.FileUpload
does not support the multiple attribute.- The Elemental package in GWT only works with webkit browsers, and I had some issues last time I tried to use the File Api.
Fortunately, gwtquery 1.0.0 has a bunch of features which facilitates to solve the problem.
Here you have a working example (with very few lines of code), which works in all browsers supporting the HTML5 file api:
importstatic com.google.gwt.query.client.GQuery.*;
[...]
final FileUpload fileUpload = newFileUpload();
RootPanel.get().add(fileUpload);
$(fileUpload)
// FileUpload does not have a way to set the multiple attribute,// we use gQuery instead
.prop("multiple", true)
// We use gQuery events mechanism
.on("change", newFunction() {
publicvoidf() {
// Use gQuery utils to create a FormData object instead of JSNIJavaScriptObject form = JsUtils.runJavascriptFunction(window, "eval", "new FormData()");
// Get an array with the files selectedJsArray<JavaScriptObject> files = $(fileUpload).prop("files");
// Add each file to the FormDatafor (int i = 0, l = files.length(); i < l; i++) {
JsUtils.runJavascriptFunction(form, "append", "file-" + i, files.get(i));
}
// Use gQuery ajax instead of RequestBuilder because it // supports FormData and progressAjax.ajax(Ajax.createSettings()
.setUrl(url)
.setData((Properties)form))
// gQuery ajax returns a promise, making the code more declarative
.progress(newFunction() {
publicvoidf() {
double total = arguments(0);
double done = arguments(1);
double percent = arguments(2);
// Here you can update your progress barconsole.log("Uploaded " + done + "/" + total + " (" + percent + "%)");
}
})
.done(newFunction() {
publicvoidf() {
console.log("Files uploaded, server response is: " + arguments(0));
}
})
.fail(newFunction() {
publicvoidf() {
console.log("Something went wrong: " + arguments(0));
}
});
}
});
Another option is to use gwtupload, which supports any browser, and it comes with some nice widgets and progress bar, even you can plug your own progress and status widgets.
It does not use HTML5 File api yet but an ajax solution based on a server listener. It will though, support html5 in future versions, falling back to ajax mechanism for old browsers. When gwtupload supports this, you wont have to modify anything in your code.
Solution 2:
All the building blocks are in Elemental but might not work everywhere (Elemental is "close to the metal", without any support detection or hiding/working around browser bugs/discrepancies).
Or you can use JSNI.
Post a Comment for "File Upload With A Progress Bar, Or Accessing The Html 5 File Api From Google Web Toolkit?"