GWT FileUpload with Progress Listener - java

I want to observe the upload percentage of a file upload from GWT.
In JavaScript you can use a XMLHttpRequest and add an event listener like this:
var oReq = new XMLHttpRequest();
oReq.upload.addEventListener("progress", updateProgress, false);
// progress on transfers from the server to the client (downloads)
function updateProgress (oEvent) {
if (oEvent.lengthComputable) {
var percentComplete = oEvent.loaded / oEvent.total;
// ...
} else {
// Unable to compute progress information since the total size is unknown
}
}
(The above code is from here.)
This is also done very easily in jQuery as:
var $request = $.ajax({
xhr: function() {
xhrNativeObject = new window.XMLHttpRequest();
//Upload progress
xhrNativeObject.upload.addEventListener("progress", function(event) { ... }
}
});
I want to do the same with GWT. I could use a RequestBuilder to send a request, but this is only a high level wrapper around the XMLHttpRequest JavaScriot object. Another possibility would be to use the GWT XMLHttpRequest class which is a JSNI wrapper of the JavaScript XMLHttpRequest.
My problem:
How can I add a progress listener to the XMLHttpRequest or the RequestBuilder?

I used before gwt-upload library.
You dont need to rediscover America.
Thanks for moxie group
gwt-upload-project page

//upload spring service conroller
#RequestBody public void uploadImage(#RequestParam("file") MultipartFile file ){
//what ever you want
}
XML Configuration
<bean id=multipartResolver" class ="org.springframework.web.multipart.commons.CommonsMultipartResolver" />

GWT Elemental contains all you need already AFAICT.

Related

Writing Javascript code to HTTP response from Controller

In a Struts application some controllers write Javascript code to the HTTP response (this JS code will be executed when the submit ends). Do you think it's a bad approach or is acceptable ? Would it be better to set an attribute and move the JS code to the view ?
#UserInterfaceEvent
public void aceptar_onClick(FormActionContext ctx) {
IGenerateDocListOutputBF bproxy = ProxyFactory.newBusinessProxy(getBusinessComponent(), IGenerateDocListOutputBF.class);
GenerateDocListOutputForm form = (GenerateDocListOutputForm) ctx.form();
String mode = form.getDetailMode();
removeErrors(ctx);
GemaBrowseControl browse = (GemaBrowseControl) ctx.session().getAttribute("outputs");
SelectedData data = browse.getAllSelectedData(ctx, true);
try {
bproxy.generateOutputs(data.getSelectedDboids(), form.getDboid(), false);
if (GemaAppErrorMgr.currentScopeHasErrors()) {
ctx.request().setAttribute(DetailRequest.MODE, mode);
showErrorPopUp(ctx);
} else {
String javascript = "<script>window.opener.refreshDivDocsRelated(); window.close();</script>";
ctx.response().getOutputStream().print(javascript);
ctx.forwardToResponse();
}
} catch (Exception e) {
handleException(e, ctx.request());
}
}
On my opinion it is extremely bad practice. Mixing the business logic and representation layers will not only make it harder to understand (what if the back-end dev does not understand JS at all?), but event more importantly it will make it harder to debug, especially in big projects where the people are constantly changing and this knowledge is lost in process.
I would implement an AJAX call and execute that JS upon request completion (on the view side ofc).

passing parameters from javascript to gwt?

I am new to Gwt,i m implementing a webclipper project so my task to send some parameters from javascript file to Gwt so that i will be able to make the connection with my couchdb database but i am getting a problem in passing parameters like title, url ,and summary from webpage to Gwt n then couchdb.The following code is my javascript code:-
function onPageInfo(o) {
document.getElementById('title').value = o.title;
document.getElementById('url').value = o.url;
document.getElementById('summary').innerText = o.summary;
}
// Global reference to the status display SPAN
var statusDisplay = null;
// POST the data to the server using XMLHttpRequest
function addBookmark() {
// Cancel the form submit
event.preventDefault();
// The URL to POST our data to
var postUrl = "http://127.0.0.1:8888/practice.html? gwt.codesvr=127.0.0.1:9997&gwt.codesvr=127.0.0.1:9997/?title=1&url=2&summary=3";
// Set up an asynchronous AJAX POST request
var xhr = new XMLHttpRequest();
xhr.open('POST', postUrl, true);
// Prepare the data to be POSTed
var title = encodeURIComponent(document.getElementById('title').value);
var url = encodeURIComponent(document.getElementById('url').value);
var summary = encodeURIComponent(document.getElementById('summary').value);
var tags = encodeURIComponent(document.getElementById('tags').value);
var params = 'title=' + title +
'&url=' + url +
'&summary=' + summary +
'&tags=' + tags;
// Replace any instances of the URLEncoded space char with +
params = params.replace(/%20/g, '+');
// Set correct header for form data
xhr.setRequestHeader('Content-type', 'application/json');
// Handle request state change events
xhr.onreadystatechange = function() {
// If the request completed
if (xhr.readyState == 4) {
statusDisplay.innerHTML = '';
if (xhr.status == 200) {
// If it was a success, close the popup after a short delay
statusDisplay.innerHTML = 'Saved!';
window.setTimeout(window.close, 1000);
} else {// Show what went wrong
statusDisplay.innerHTML = 'Error saving: ' + xhr.statusText;
}
}
};
// Send the request and set status
xhr.send(params);
statusDisplay.innerHTML = 'Saving...';
}
// When the popup HTML has loaded
window.addEventListener('load', function(evt) {
// Handle the bookmark form submit event with our addBookmark function
document.getElementById('addbookmark').addEventListener('submit', addBookmark);
// Cache a reference to the status display SPAN
statusDisplay = document.getElementById('status-display');
// Call the getPageInfo function in the background page, injecting content_script.js
// into the current HTML page and passing in our onPageInfo function as the callback
chrome.extension.getBackgroundPage().getPageInfo(onPageInfo);
});
Thanks.....
You can call a function defined in a java file (of GWT client module) by exporting that function. Let's assume there is a class A.java which is also your entry point class. This class contains someMethod() which you need to call from javascript passing some parameters. The content of your class A would be something like
public class A implements EntryPoint {
public static functionExported = false;
public void onModuleLoad() {
ExportToBeCalledFromJs();
// other code goes here
}
public static native void ExportToBeCalledFromJs() /*-{
$wnd.toBeCalledFromJs = $entry(function(s1, s2) {
return #com.practice.gwt.client.A::someFunction();
});
#com.practice.gwt.client.A:functionExported = true;
}-*/;
}
Above code exports the function and makes it available to javascript. You can simply call toBeCalledFromJs(param1, param2) fromyour js where param1 would substitute s1 and param2 would substitute s2. If you wish to add more parameters you can modify $entry(function(s1, s2) in the code above.

jsf. How to post backbean object from jsf form to javascript

I am using Primefaces/JSF in combination with pure javascript tools in order to implement an image viewer & annotator. Image viewer is built upon the OpenLayers framework.
When the user annotates (draws shapes) on the canvas, a JSON object is created and upon Save action passed to the back bean. Back bean retrieves the object (deserialized) and stores it in to a file.
Here is the relevant code:
OpenLayers javascript (image-viewer.js):
function initialiseMap(){'
...
map = new OpenLayers.Map(imageEditorID, options);
imageLayer = new OpenLayers.Layer.TMS(imgURL, "", {
...
});
map.addLayer(imageLayer);
var vlayer = new OpenLayers.Layer.Vector("Editable");
map.addLayer(vlayer);
//draw controls and shape tools
...
//then define save action
var save = new OpenLayers.Control.Button({
...
var GEOJSON_PARSER = new OpenLayers.Format.GeoJSON();
var vectorLayerAsJson = GEOJSON_PARSER.write(vlayer.features);
//and finally post to server layer with drawn shapes
sendJSONToServer([{name:'param', value:vectorLayerAsJson}]);
...
The above Image Viewer/Map tool, is loaded via an p:outputPanel component of primefaces and uses sendJSONToServer remoteCommand to get JSON layer:
<h:head>
<script src="#{facesContext.externalContext.requestContextPath}/js/image-viewer.js" />
...
<h:body>
<h:form id="imageEditor">
<p:fieldset legend="Viewer">
...
// inoutHidden does not have on* events? how am i going to post to image-viewer.js?
<h:inputHidden value="#{imageAnnotations.fetchJsonString()}" />
...
<p:outputPanel layout="block" styleClass="imageEditorImagePanel" />
<p:remoteCommand immediate="true" name="sendJSONToServer" action="#{imageAnnotations.actionOnString}" />
</p:fieldset>
....
Finally in the backbean the JSON object is fetched and stored in a file (implementation is raw):
#ManagedBean(name="imageAnnotations")
public class ImageAnnotations {
//actionOnString fetches and saves the JSON string - this is a raw impementation
public String actionOnString() {
//Do the job and get and save JSON string
}
public String fetchJsonString(){
//Do the job and get JSON string
return jsonString;
}
}
The question is How am i going to use a JSF or primefaces element to make available the imageAnnotations.fetchJsonString() value for fetching from within js?
Even I can't give all answers, for me the filling of your hiddenInput should be managed as following:
#ManagedBean(name="imageAnnotations")
public class ImageAnnotations {
private String jsonString;
public void anyMethodFillingOrInitializingTheJSONString() {
this.jsonString = resultOfYourWork();
}
public String getJsonString(){
return this.jsonString();
}
public void setJsonString(String item) {
this.jsonString = item;
}
}
When you reload this hidden input field, just be sure to trigger a javascript parsing the String and updating your client-side Model. This can be done via the on* - events you can connect with Primefaces buttons.
Guys, can anybody help with the other parts?

stringByEvaluatingJavascriptFromString (iOS method, what is Android equivalent?)

In an iOS app, I used
stringFromJavaScript = [webView stringByEvaluatingJavascriptFromString:#"document.getElementById(\"image\").getAttribute(\"src")"];
To get the src directory of the image that was being displayed on the webView. I want to do the same for Android. What are my options?
Basically the intent is to capture the path so that I can email this same picture...
ie.
"picture.php?image=%#",stringFromJavascript
This way, that same image would be loaded when the user clicks the link, or posts it to facebook etc.
Yeah, I miss this method greatly in Android ;)
To execute JavaScript and get response you can do as follows:
Define JavaScript callback interface in your code:
class MyJavaScriptInterface {
#JavascriptInterface
public void someCallback(String jsResult) {
// your code...
}
}
Attach this callback to your WebView
MyJavaScriptInterface javaInterface = new MyJavaScriptInterface();
yourWebView.addJavascriptInterface(javaInterface, "HTMLOUT");
Run your JavaScript calling window.HTMLOUT.someCallback from the script:
yourWebView.loadUrl("javascript:( function () { var resultSrc = document.getElementById(\"image\").getAttribute(\"src\"); window.HTMLOUT.someCallback(resultSrc); } ) ()");
Hope this helps!

GWT - how do I send the form asynchronously?

I am adding a file upload functionality to an application.
I'm following some tutorials, so far I get something like this:
final FormPanel form = new FormPanel();
form.setAction(GWT.getModuleBaseURL() + "fileupload");
form.setEncoding(FormPanel.ENCODING_MULTIPART);
form.setMethod(FormPanel.METHOD_POST);
final FileUpload fileUpload = new FileUpload();
submit.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
String filename = fileUpload.getFilename();
if (filename.length() == 0) {
} else {
form.submit();
}
}
});
I've made the fileupload servlet, and I guess it's okay. The problem is, after the form.submit() the page gets reloaded, but I would like to send it asynchronously instead.
Something like that is dead simple in php and jquery.
Could anybody help?
Best regards.
For submitting arbitrary data (objects) use GWT-RPC. For file upload take a look at gwtupload.

Categories

Resources