Last active
August 29, 2015 14:16
-
-
Save royshil/3c225473e46efdb8f04b to your computer and use it in GitHub Desktop.
Apache Tapestry 5 progress bar: http://www.morethantechnical.com/2015/03/09/apache-tapestry-5-progress-bar-with-jquerybootstrap-wcode/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
This is an example template that implements the progress bar calls and view | |
--> | |
<html t:type="layout" title="Progress bar example" | |
xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd" | |
xmlns:p="tapestry:parameter"> | |
<p> | |
<t:alerts /> | |
</p> | |
<div class="eg"> | |
<t:actionlink t:id="StartOperation">Start</t:actionlink> | | |
<t:actionlink t:id="CancelOperation">Cancel</t:actionlink> <br/> | |
<t:progressbar id="myprogressbar" clientfunc="updateProgressbar"/> | |
<div class="progress"> | |
<div class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="45" aria-valuemin="0" aria-valuemax="100" style="width: 45%"> | |
0% | |
</div> | |
</div> | |
<script type="text/javascript" language="JavaScript"> | |
<!-- // | |
var updateProgressbar = function(v) { | |
if(v > 100 || v < 0) { | |
$('.progress').hide(); | |
} else { | |
$(".progress").show(); | |
$('.progress-bar').css('width', v+'%').attr('aria-valuenow', v).html(v+'%'); | |
} | |
} | |
// --> | |
</script> | |
</div> | |
</html> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This is the Tapestry component to communicate with the javascript | |
*/ | |
package com.yourpackage.components; | |
import org.apache.tapestry5.BindingConstants; | |
import org.apache.tapestry5.ComponentResources; | |
import org.apache.tapestry5.Link; | |
import org.apache.tapestry5.MarkupWriter; | |
import org.apache.tapestry5.annotations.AfterRender; | |
import org.apache.tapestry5.annotations.Environmental; | |
import org.apache.tapestry5.annotations.Import; | |
import org.apache.tapestry5.annotations.Parameter; | |
import org.apache.tapestry5.internal.util.CaptureResultCallback; | |
import org.apache.tapestry5.ioc.annotations.Inject; | |
import org.apache.tapestry5.json.JSONObject; | |
import org.apache.tapestry5.services.Request; | |
import org.apache.tapestry5.services.javascript.JavaScriptSupport; | |
@Import(library = "progressbar.js") | |
public class ProgressBar { | |
@Parameter(value = "100", defaultPrefix = BindingConstants.LITERAL) | |
private int period; | |
@Parameter(defaultPrefix = BindingConstants.LITERAL) | |
private String clientFunc; | |
@Inject | |
private ComponentResources resources; | |
@Environmental | |
private JavaScriptSupport javaScriptSupport; | |
@Inject | |
private Request request; | |
/* | |
Setup the client code to know what server-side function to call (the onTimer() function), how often to call it (period), | |
and what is the function on the client-side that should be called to update the view. | |
*/ | |
@AfterRender | |
void afterRender(MarkupWriter writer) { | |
Link link = resources.createEventLink("timer"); | |
JSONObject spec = new JSONObject(); | |
spec.put("url", link.toAbsoluteURI()); | |
spec.put("period", period); | |
spec.put("clientFunc", clientFunc); | |
javaScriptSupport.addScript("$.fn.myprogressbar(%s);", spec); | |
} | |
/* | |
When the client polls the server, in turn we poll the page for the onUpdateFromProgressBar() function, and | |
return the result to the client via JSON. | |
*/ | |
Object onTimer() { | |
JSONObject spec = new JSONObject(); | |
double value = 0.0; | |
CaptureResultCallback<Double> callback = new CaptureResultCallback<Double>(); | |
resources.triggerEvent("update", new Object[] { value }, callback); | |
if (callback.getResult() == null) { | |
return spec; | |
} | |
value = callback.getResult(); | |
spec.put("value", value); | |
return spec; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This is a jQuery implementation of the Prototype class from Taha Hafez: http://permalink.gmane.org/gmane.comp.java.tapestry.user/85776 | |
I also removed some unessecary stuff... | |
*/ | |
(function($){ | |
$.fn.myprogressbar = function(options) | |
{ | |
var obj = this; | |
var settings = $.extend({ | |
value: 0 | |
}, options || {}); | |
var bRunning = false; | |
var stopExecuter = function() { | |
bRunning = false; | |
} | |
var onSuccess = function(transport) { | |
if (typeof (transport.value) == "undefined") { | |
console.log("bad server response: " + json); | |
bRunning = false; | |
return; | |
} | |
this.value = transport.value; | |
if (settings.clientFunc) { | |
var func = settings.clientFunc + "(" + transport.value + ")"; | |
eval(func); | |
} | |
if (transport.value >= 100) { | |
stopExecuter(); | |
} | |
} | |
var execute = function(transport) { | |
if(!bRunning) bRunning = true; | |
console.log("starting worker loop: " + settings.url); | |
(function worker() { | |
$.ajax({ | |
url: settings.url, | |
success: function(data) { | |
onSuccess(data); | |
}, | |
complete: function() { | |
if(bRunning == true) { | |
setTimeout(worker, settings.period); | |
} else { | |
console.log("done progress bar"); | |
} | |
} | |
}); | |
})() | |
} | |
execute(); | |
}; | |
})(jQuery); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
This simple page shows what needs to be implemented on the server side | |
*/ | |
package com.yourpackage.pages; | |
public class ProgressBarPage { | |
@Inject | |
ParallelExecutor executor; | |
@Property | |
@Persist | |
ProgressInvokable operationInvokable; | |
@Property | |
@Persist | |
private Future<String> futureOperation; | |
/* | |
The progress bar component will call this function whenever the client polls. | |
*/ | |
double onUpdateFromProgressbar() { | |
return (operationInvokable!=null) ? operationInvokable.getProgress() : 101.0; | |
} | |
public Object onActionFromCancelOperation() { | |
if(futureOperation != null) | |
futureOperation.cancel(true); | |
operationInvokable = null; | |
futureOperation = null; | |
return this; | |
} | |
@Log | |
public Object onActionFromStartOperation() { | |
operationInvokable = new ProgressInvokable() { | |
double progress; | |
@Override | |
public double getProgress() { | |
return progress; | |
} | |
@Override | |
public String invoke() { | |
for(int i = 0; i < 100; i++) { | |
progress = (double)i; | |
Thread.sleep(100); | |
} | |
return null; | |
} | |
}; | |
futureOperation = executor.invoke(operationInvokable); | |
return this; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
We need a simple extension of the Invokable to allow for keeping progress and retrieving it | |
*/ | |
package com.yourpackage.util; | |
import org.apache.tapestry5.ioc.Invokable; | |
public interface ProgressInvokable extends Invokable<String> { | |
double getProgress(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment